From avatar@brahms.mmlab.cse.yzu.edu.tw  Mon Aug 31 07:31:48 1998
Received: from brahms.mmlab.cse.yzu.edu.tw (brahms.mmlab.cse.yzu.edu.tw [140.138.145.183])
          by hub.freebsd.org (8.8.8/8.8.8) with SMTP id HAA28489
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 31 Aug 1998 07:31:12 -0700 (PDT)
          (envelope-from avatar@brahms.mmlab.cse.yzu.edu.tw)
Received: (qmail 29045 invoked by uid 1000); 31 Aug 1998 14:29:22 -0000
Message-Id: <19980831142922.29044.qmail@brahms.mmlab.cse.yzu.edu.tw>
Date: 31 Aug 1998 14:29:22 -0000
From: avatar@www.mmlab.cse.yzu.edu.tw
Reply-To: avatar@www.mmlab.cse.yzu.edu.tw
To: FreeBSD-gnats-submit@freebsd.org
Subject: back patch from -current to -stable Linux emulator<Synopsis of the problem (one line)>
X-Send-Pr-Version: 3.2

>Number:         7792
>Category:       i386
>Synopsis:       back patch from -current to -stable Linux emulator
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 31 07:40:00 PDT 1998
>Closed-Date:    Wed Sep 23 07:12:54 PDT 1998
>Last-Modified:  Wed Sep 23 07:13:17 PDT 1998
>Originator:     Avatar Liang
>Release:        FreeBSD 2.2.7-RELEASE i386
>Organization:
Multimedia Laboratory at Yuan Ze University
>Environment:

	This patch has been tested on FreeBSD 2.2.7-RELEASE.
	

>Description:

	This patch included following changes in -stable Linux emulator:

		1. Some system calls back ported from -current
		2. Support SNDCTL_SEQ_XXXXX VoxWare style ioctl calls(actually
		   most of them are the same in FreeBSD & Linux. Already tested
		   on my machine for at least 7 monthes).

	Some system calls which implemented in -current was not ported due
	to lack of kernel support(system call #164~#181.)

	Please check and apply this patch, thanks.
	

>How-To-Repeat:

	N/A

>Fix:
	
	

diff -ru sys/i386/linux/linux.h /sys/i386/linux/linux.h
--- sys/i386/linux/linux.h	Thu Feb 19 08:37:24 1998
+++ /sys/i386/linux/linux.h	Mon Aug  3 12:24:13 1998
@@ -500,6 +500,21 @@
 #define LINUX_IP_DROP_MEMBERSHIP	36
 
 /* Sound system defines */
+#define LINUX_SNDCTL_SEQ_RESET		0x5100
+#define LINUX_SNDCTL_SEQ_SYNC		0x5101
+#define LINUX_SNDCTL_SYNTH_INFO		0x5102
+#define LINUX_SNDCTL_SEQ_CTRLRATE	0x5103
+#define LINUX_SNDCTL_SEQ_GETOUTCOUNT	0x5104
+#define LINUX_SNDCTL_SEQ_GETINCOUNT	0x5105
+#define LINUX_SNDCTL_SEQ_PERCMODE	0x5106
+#define LINUX_SNDCTL_FM_LOAD_INSTR	0x5107
+#define LINUX_SNDCTL_SEQ_TESTMIDI	0x5108
+#define LINUX_SNDCTL_SEQ_RESETSAMPLES	0x5109
+#define LINUX_SNDCTL_SEQ_NRSYNTHS	0x510A
+#define LINUX_SNDCTL_SEQ_NRMIDIS	0x510B
+#define LINUX_SNDCTL_MIDI_INFO		0x510C
+#define LINUX_SNDCTL_SEQ_TRESHOLD	0x510D
+#define LINUX_SNDCTL_SYNTH_MEMAVL	0x510E
 #define LINUX_SNDCTL_DSP_RESET		0x5000
 #define LINUX_SNDCTL_DSP_SYNC		0x5001
 #define LINUX_SNDCTL_DSP_SPEED		0x5002
diff -ru sys/i386/linux/linux_dummy.c /sys/i386/linux/linux_dummy.c
--- sys/i386/linux/linux_dummy.c	Thu Feb 19 08:37:28 1998
+++ /sys/i386/linux/linux_dummy.c	Mon Aug  3 12:20:59 1998
@@ -179,13 +179,6 @@
 }
 
 int
-linux_iopl(struct proc *p, struct linux_iopl_args *args, int *retval)
-{
-    printf("Linux-emul(%d): iopl() not supported\n", p->p_pid);
-    return ENOSYS;
-}
-
-int
 linux_vhangup(struct proc *p, struct linux_vhangup_args *args, int *retval)
 {
     printf("Linux-emul(%d): vhangup() not supported\n", p->p_pid);
diff -ru sys/i386/linux/linux_file.c /sys/i386/linux/linux_file.c
--- sys/i386/linux/linux_file.c	Mon Jan  5 12:03:42 1998
+++ /sys/i386/linux/linux_file.c	Wed Aug  5 22:10:14 1998
@@ -666,6 +666,27 @@
 }
 
 int
+linux_lchown(struct proc *p, struct linux_lchown_args *args, int *retval)
+{
+	struct lchown_args bsd;
+	caddr_t sg;
+
+	sg = stackgap_init();
+	CHECKALTEXIST(p, &sg, args->path);
+
+#ifdef DEBUG
+	printf("Linux-emul(%d): lchown(%s, %d, %d)\n",
+		p->p_pid, args->path, args->uid, args->gid);
+#endif
+	bsd.path = args->path;
+	/* XXX size casts here */
+	bsd.uid = args->uid;
+	bsd.gid = args->gid;
+
+	return lchown(p, &bsd, retval);
+}
+
+int
 linux_mkdir(struct proc *p, struct linux_mkdir_args *args, int *retval)
 {
 	struct mkdir_args bsd;
diff -ru sys/i386/linux/linux_genassym.c /sys/i386/linux/linux_genassym.c
--- sys/i386/linux/linux_genassym.c	Sun Mar  3 05:00:10 1996
+++ /sys/i386/linux/linux_genassym.c	Thu Aug  6 09:31:16 1998
@@ -5,11 +5,15 @@
 #include <sys/proc.h>
 #include <i386/linux/linux.h>
 
-extern int	main __P((void));
+#define	offsetof(type, member)	((size_t)(&((type *)0)->member))
+#define	OS(s, m)		((u_int)offsetof(struct s, m))
+
+int	main __P((void));
 
 int
 main()
 {
+#if	0
 	struct linux_sigframe *linux_sigf = (struct linux_sigframe *)0;
 	struct linux_sigcontext *linux_sc = (struct linux_sigcontext *)0;
 
@@ -18,6 +22,14 @@
 	printf("#define\tLINUX_SC_FS %d\n", &linux_sc->sc_fs);
 	printf("#define\tLINUX_SC_GS %d\n", &linux_sc->sc_gs);
 	printf("#define\tLINUX_SC_EFLAGS %d\n", &linux_sc->sc_eflags);
-
+#else
+	printf("#define\tLINUX_SIGF_HANDLER %u\n",
+		OS(linux_sigframe, sf_handler));
+	printf("#define\tLINUX_SIGF_SC %u\n", OS(linux_sigframe, sf_sc));
+	printf("#define\tLINUX_SC_FS %u\n", OS(linux_sigcontext, sc_fs));
+	printf("#define\tLINUX_SC_GS %u\n", OS(linux_sigcontext, sc_gs));
+	printf("#define\tLINUX_SC_EFLAGS %u\n",
+		OS(linux_sigcontext, sc_eflags));
+#endif
 	return (0);
 }
diff -ru sys/i386/linux/linux_ioctl.c /sys/i386/linux/linux_ioctl.c
--- sys/i386/linux/linux_ioctl.c	Thu Feb 19 08:37:30 1998
+++ /sys/i386/linux/linux_ioctl.c	Wed Aug  5 22:18:21 1998
@@ -250,9 +250,8 @@
 #ifdef DEBUG
     printf("LINUX: LINUX termios structure (output):\n");
     printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
-	   linux_termios->c_iflag, linux_termios->c_oflag,
-	   linux_termios->c_cflag, linux_termios->c_lflag,
-	   linux_termios->c_line);
+	linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
+	linux_termios->c_lflag, linux_termios->c_line);
     printf("c_cc ");
     for (i=0; i<LINUX_NCCS; i++) 
 	printf("%02x ", linux_termios->c_cc[i]);
@@ -269,9 +268,8 @@
 #ifdef DEBUG
     printf("LINUX: LINUX termios structure (input):\n");
     printf("i=%08x o=%08x c=%08x l=%08x line=%d\n",
-	   linux_termios->c_iflag, linux_termios->c_oflag,
-	   linux_termios->c_cflag, linux_termios->c_lflag,
-	   linux_termios->c_line);
+	linux_termios->c_iflag, linux_termios->c_oflag, linux_termios->c_cflag,
+	linux_termios->c_lflag, linux_termios->c_line);
     printf("c_cc ");
     for (i=0; i<LINUX_NCCS; i++) 
 	printf("%02x ", linux_termios->c_cc[i]);
@@ -665,6 +663,51 @@
 	return copyout(&linux_line, (caddr_t)args->arg, 
 		       sizeof(int));
 
+    case LINUX_SNDCTL_SEQ_RESET:
+	args->cmd = SNDCTL_SEQ_RESET;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_SYNC:
+	args->cmd = SNDCTL_SEQ_SYNC;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SYNTH_INFO:
+	args->cmd = SNDCTL_SYNTH_INFO;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_CTRLRATE:
+	args->cmd = SNDCTL_SEQ_CTRLRATE;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_GETOUTCOUNT:
+	args->cmd = SNDCTL_SEQ_GETOUTCOUNT;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_GETINCOUNT:
+	args->cmd = SNDCTL_SEQ_GETINCOUNT;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_PERCMODE:
+	args->cmd = SNDCTL_SEQ_PERCMODE;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_FM_LOAD_INSTR:
+	args->cmd = SNDCTL_FM_LOAD_INSTR;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_TESTMIDI:
+	args->cmd = SNDCTL_SEQ_TESTMIDI;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_RESETSAMPLES:
+	args->cmd = SNDCTL_SEQ_RESETSAMPLES;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_NRSYNTHS:
+	args->cmd = SNDCTL_SEQ_NRSYNTHS;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_NRMIDIS:
+	args->cmd = SNDCTL_SEQ_NRMIDIS;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_MIDI_INFO:
+	args->cmd = SNDCTL_MIDI_INFO;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SEQ_TRESHOLD:
+	args->cmd = SNDCTL_SEQ_TRESHOLD;
+	return ioctl(p, (struct ioctl_args *)args, retval);
+    case LINUX_SNDCTL_SYNTH_MEMAVL:
+	args->cmd = SNDCTL_SYNTH_MEMAVL;
+	return ioctl(p, (struct ioctl_args *)args, retval);
     case LINUX_SNDCTL_DSP_GETOPTR :
 	args->cmd = SNDCTL_DSP_GETOPTR;
 	return ioctl(p, (struct ioctl_args *)args, retval);
@@ -893,7 +936,7 @@
       }
     }
     uprintf("LINUX: 'ioctl' fd=%d, typ=0x%x(%c), num=0x%x not implemented\n",
-	    args->fd, (args->cmd&0xffff00)>>8,
-	    (args->cmd&0xffff00)>>8, args->cmd&0xff);
+	args->fd, (u_int)((args->cmd & 0xffff00) >> 8),
+	(int)((args->cmd & 0xffff00) >> 8), (u_int)(args->cmd & 0xff));
     return EINVAL;
 }
diff -ru sys/i386/linux/linux_ipc.c /sys/i386/linux/linux_ipc.c
--- sys/i386/linux/linux_ipc.c	Thu Sep  4 03:17:09 1997
+++ /sys/i386/linux/linux_ipc.c	Wed Aug  5 22:22:13 1998
@@ -33,6 +33,7 @@
 #include <sys/systm.h>
 #include <sys/sysproto.h>
 #include <sys/proc.h>
+#include <sys/sem.h>
 #include <sys/shm.h>
 
 #include <i386/linux/linux.h>
@@ -85,6 +86,17 @@
     lpp->seq = bpp->seq;
 }
 
+struct linux_semid_ds {
+	struct linux_ipc_perm	sem_perm;
+	linux_time_t		sem_otime;
+	linux_time_t		sem_ctime;
+	void			*sem_base;
+	void			*sem_pending;
+	void			*sem_pending_last;
+	void			*undo;
+	ushort			sem_nsems;
+};
+
 struct linux_shmid_ds {
     struct linux_ipc_perm shm_perm;
     int shm_segsz;
@@ -100,6 +112,26 @@
 };
 
 static void
+linux_to_bsd_semid_ds(struct linux_semid_ds *lsp, struct semid_ds *bsp)
+{
+    linux_to_bsd_ipc_perm(&lsp->sem_perm, &bsp->sem_perm);
+    bsp->sem_otime = lsp->sem_otime;
+    bsp->sem_ctime = lsp->sem_ctime;
+    bsp->sem_nsems = lsp->sem_nsems;
+    bsp->sem_base = lsp->sem_base;
+}
+
+static void
+bsd_to_linux_semid_ds(struct semid_ds *bsp, struct linux_semid_ds *lsp)
+{
+	bsd_to_linux_ipc_perm(&bsp->sem_perm, &lsp->sem_perm);
+	lsp->sem_otime = bsp->sem_otime;
+	lsp->sem_ctime = bsp->sem_ctime;
+	lsp->sem_nsems = bsp->sem_nsems;
+	lsp->sem_base = bsp->sem_base;
+}
+
+static void
 linux_to_bsd_shmid_ds(struct linux_shmid_ds *lsp, struct shmid_ds *bsp)
 {
     linux_to_bsd_ipc_perm(&lsp->shm_perm, &bsp->shm_perm);
@@ -130,19 +162,119 @@
 static int
 linux_semop(struct proc *p, struct linux_ipc_args *args, int *retval)
 {
-    return ENOSYS;
+	struct semop_args /* {
+	int	semid;
+	struct	sembuf *sops;
+	int		nsops;
+	} */ bsd_args;
+
+	bsd_args.semid = args->arg1;
+	bsd_args.sops = (struct sembuf *)args->ptr;
+	bsd_args.nsops = args->arg2;
+	return semop(p, &bsd_args, retval);
 }
 
 static int
 linux_semget(struct proc *p, struct linux_ipc_args *args, int *retval)
 {
-    return ENOSYS;
+	struct semget_args /* {
+	key_t	key;
+	int		nsems;
+	int		semflg;
+	} */ bsd_args;
+
+	bsd_args.key = args->arg1;
+	bsd_args.nsems = args->arg2;
+	bsd_args.semflg = args->arg3;
+	return semget(p, &bsd_args, retval);
 }
 
 static int
 linux_semctl(struct proc *p, struct linux_ipc_args *args, int *retval)
 {
-    return ENOSYS;
+	struct linux_semid_ds   linux_semid;
+	struct semid_ds bsd_semid;
+	struct __semctl_args /* {
+	int		semid;
+	int		semnum;
+	int		cmd;
+	union	semun *arg;
+	} */ bsd_args;
+	int	error;
+	caddr_t sg, unptr, dsp, ldsp;
+
+	sg = stackgap_init();
+	bsd_args.semid = args->arg1;
+	bsd_args.semnum = args->arg2;
+	bsd_args.cmd = args->arg3;
+	bsd_args.arg = (union semun *)args->ptr;
+
+	switch (args->arg3) {
+	case LINUX_IPC_RMID:
+		bsd_args.cmd = IPC_RMID;
+		break;
+	case LINUX_GETNCNT:
+		bsd_args.cmd = GETNCNT;
+		break;
+	case LINUX_GETPID:
+		bsd_args.cmd = GETPID;
+		break;
+	case LINUX_GETVAL:
+		bsd_args.cmd = GETVAL;
+		break;
+	case LINUX_GETZCNT:
+		bsd_args.cmd = GETZCNT;
+		break;
+	case LINUX_SETVAL:
+		bsd_args.cmd = SETVAL;
+		break;
+	case LINUX_IPC_SET:
+		bsd_args.cmd = IPC_SET;
+		error = copyin(args->ptr, &ldsp, sizeof(ldsp));
+		if (error)
+			return error;
+		error = copyin(ldsp, (caddr_t)&linux_semid, sizeof(linux_semid));
+		if (error)
+			return error;
+		linux_to_bsd_semid_ds(&linux_semid, &bsd_semid);
+		unptr = stackgap_alloc(&sg, sizeof(union semun));
+		dsp = stackgap_alloc(&sg, sizeof(struct semid_ds));
+		error = copyout((caddr_t)&bsd_semid, dsp, sizeof(bsd_semid));
+		if (error)
+			return error;
+		error = copyout((caddr_t)&dsp, unptr, sizeof(dsp));
+		if (error)
+			return error;
+		bsd_args.arg = (union semun *)unptr;
+		return __semctl(p, &bsd_args, retval);
+	case LINUX_IPC_STAT:
+		bsd_args.cmd = IPC_STAT;
+		unptr = stackgap_alloc(&sg, sizeof(union semun *));
+		dsp = stackgap_alloc(&sg, sizeof(struct semid_ds));
+		error = copyout((caddr_t)&dsp, unptr, sizeof(dsp));
+		if (error)
+			return error;
+		bsd_args.arg = (union semun *)unptr;
+		error = __semctl(p, &bsd_args, retval);
+		if (error)
+			return error;
+		error = copyin(dsp, (caddr_t)&bsd_semid, sizeof(bsd_semid));
+		if (error)
+			return error;
+		bsd_to_linux_semid_ds(&bsd_semid, &linux_semid);
+		error = copyin(args->ptr, &ldsp, sizeof(ldsp));
+		if (error)
+			return error;
+		return copyout((caddr_t)&linux_semid, ldsp, sizeof(linux_semid));
+	case LINUX_GETALL:
+		/* FALLTHROUGH */
+	case LINUX_SETALL:
+		/* FALLTHROUGH */
+	default:
+		uprintf("LINUX: 'ipc' typ=%d not implemented\n", args->what);
+		return EINVAL;
+	}
+	return __semctl(p, &bsd_args, retval);
 }
 
 static int
@@ -298,14 +430,18 @@
     case LINUX_IPC_RMID:
 	bsd_args.shmid = args->arg1;
 	bsd_args.cmd = IPC_RMID;
-	if ((error = copyin(args->ptr, (caddr_t)&linux_shmid, 
-		    	    sizeof(linux_shmid))))
-	    return error;
-	linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
-	bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
-	if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
-		     	     sizeof(struct shmid_ds))))
-	    return error;
+	if (NULL == args->ptr)
+	    bsd_args.buf = NULL;
+	else {
+	    if ((error = copyin(args->ptr, (caddr_t)&linux_shmid, 
+				sizeof(linux_shmid))))
+		return error;
+	    linux_to_bsd_shmid_ds(&linux_shmid, &bsd_shmid);
+	    bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
+	    if ((error = copyout((caddr_t)&bsd_shmid, (caddr_t)bsd_args.buf,
+				sizeof(struct shmid_ds))))
+		return error;
+	}
 	return shmctl(p, &bsd_args, retval);
 
     case LINUX_IPC_INFO:
diff -ru sys/i386/linux/linux_misc.c /sys/i386/linux/linux_misc.c
--- sys/i386/linux/linux_misc.c	Thu Feb 19 08:37:32 1998
+++ /sys/i386/linux/linux_misc.c	Thu Aug  6 09:41:00 1998
@@ -61,6 +61,10 @@
 #include <vm/vm_map.h>
 #include <vm/vm_extern.h>
 
+#include <machine/frame.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+
 #include <i386/linux/linux.h>
 #include <i386/linux/linux_proto.h>
 #include <i386/linux/linux_util.h>
@@ -79,7 +83,7 @@
     it.it_value.tv_usec = 0;
     it.it_interval.tv_sec = 0;
     it.it_interval.tv_usec = 0;
-    s = splclock();
+    s = splclock(); /* XXX Still needed ? */
     old_it = p->p_realtimer;
     tv = time;
     if (timerisset(&old_it.it_value))
@@ -147,9 +151,9 @@
     new = (vm_offset_t)args->dsend;
     tmp.nsize = (char *) new;
     if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval))
-	retval[0] = (int)new;
+	*retval = (int)new;
     else
-	retval[0] = (int)old;
+	*retval = (int)old;
 
     return 0;
 #endif
@@ -621,6 +625,38 @@
 }
 
 int
+linux_mremap(struct proc *p, struct linux_mremap_args *args, int *retval)
+{
+	struct munmap_args /* {
+		void *addr;
+		size_t len;
+	} */ bsd_args;
+	int error = 0;
+
+#ifdef DEBUG
+	printf("Linux-emul(%ld): mremap(%p, %08x, %08x, %08x)\n",
+	    (long)p->p_pid, (void *)args->addr, args->old_len, args->new_len,
+	    args->flags);
+#endif
+	args->new_len = round_page(args->new_len);
+	args->old_len = round_page(args->old_len);
+
+	if (args->new_len > args->old_len) {
+		*retval = 0;
+		return ENOMEM;
+	}
+
+	if (args->new_len < args->old_len) {
+		bsd_args.addr = args->addr + args->new_len;
+		bsd_args.len = args->old_len - args->new_len;
+		error = munmap(p, &bsd_args, retval);
+	}
+
+	*retval = error ? 0 : (int)args->addr;
+	return error;
+}
+
+int
 linux_msync(struct proc *p, struct linux_msync_args *args, int *retval)
 {
 	struct msync_args bsd_args;
@@ -894,7 +930,7 @@
 		return EINVAL;
 
 	/* Yes Jim, it's still a Linux... */
-	retval[0] = 0;
+	*retval = 0;
 	return 0;
 }
 
@@ -938,6 +974,22 @@
 	bsa.which = args->which;
 	bsa.itv = args->itv;
 	return getitimer(p, &bsa, retval);
+}
+
+int
+linux_iopl(struct proc *p, struct linux_iopl_args *args, int *retval)
+{
+	int error;
+	struct trapframe *regs;
+
+	error = suser(p->p_ucred, &p->p_acflag);
+	if (error != 0)
+		return error;
+	if (securelevel > 0)
+		return EPERM;
+	regs = (struct trapframe *)p->p_md.md_regs;
+	regs->tf_eflags |= PSL_IOPL;
+	return 0;
 }
 
 int
diff -ru sys/i386/linux/linux_proto.h /sys/i386/linux/linux_proto.h
--- sys/i386/linux/linux_proto.h	Thu Feb 19 08:37:34 1998
+++ /sys/i386/linux/linux_proto.h	Thu Aug  6 09:41:27 1998
@@ -12,357 +12,373 @@
 #include <sys/param.h>
 #include <sys/mount.h>
 
+struct proc;
+
+#define	PAD_(t) (sizeof(register_t) <= sizeof(t) ? \
+		0 : sizeof(register_t) - sizeof(t))
+
 struct	linux_setup_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_fork_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_open_args {
-	char * path;
-	int flags;
-	int mode;
+	char *	path;	char path_[PAD_(char *)];
+	int	flags;	char flags_[PAD_(int)];
+	int	mode;	char mode_[PAD_(int)];
 };
 struct	linux_waitpid_args {
-	int pid;
-	int * status;
-	int options;
+	int	pid;	char pid_[PAD_(int)];
+	int *	status;	char status_[PAD_(int *)];
+	int	options;	char options_[PAD_(int)];
 };
 struct	linux_creat_args {
-	char * path;
-	int mode;
+	char *	path;	char path_[PAD_(char *)];
+	int	mode;	char mode_[PAD_(int)];
 };
 struct	linux_unlink_args {
-	char * path;
+	char *	path;	char path_[PAD_(char *)];
 };
 struct	linux_execve_args {
-	char * path;
-	char ** argp;
-	char ** envp;
+	char *	path;	char path_[PAD_(char *)];
+	char **	argp;	char argp_[PAD_(char **)];
+	char **	envp;	char envp_[PAD_(char **)];
 };
 struct	linux_chdir_args {
-	char * path;
+	char *	path;	char path_[PAD_(char *)];
 };
 struct	linux_time_args {
-	linux_time_t * tm;
+	linux_time_t *	tm;	char tm_[PAD_(linux_time_t *)];
 };
 struct	linux_mknod_args {
-	char * path;
-	int mode;
-	int dev;
+	char *	path;	char path_[PAD_(char *)];
+	int	mode;	char mode_[PAD_(int)];
+	int	dev;	char dev_[PAD_(int)];
 };
 struct	linux_chmod_args {
-	char * path;
-	int mode;
+	char *	path;	char path_[PAD_(char *)];
+	int	mode;	char mode_[PAD_(int)];
 };
-struct	linux_chown_args {
-	char * path;
-	int uid;
-	int gid;
+struct	linux_lchown_args {
+	char *	path;	char path_[PAD_(char *)];
+	int	uid;	char uid_[PAD_(int)];
+	int	gid;	char gid_[PAD_(int)];
 };
 struct	linux_break_args {
-	char * nsize;
+	char *	nsize;	char nsize_[PAD_(char *)];
 };
 struct	linux_stat_args {
-	char * path;
-	struct ostat * up;
+	char *	path;	char path_[PAD_(char *)];
+	struct ostat *	up;	char up_[PAD_(struct ostat *)];
 };
 struct	linux_lseek_args {
-	int fdes;
-	long off;
-	int whence;
+	int	fdes;	char fdes_[PAD_(int)];
+	long	off;	char off_[PAD_(long)];
+	int	whence;	char whence_[PAD_(int)];
 };
 struct	linux_mount_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_umount_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_stime_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_ptrace_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_alarm_args {
-	unsigned int secs;
+	unsigned int	secs;	char secs_[PAD_(unsigned int)];
 };
 struct	linux_fstat_args {
-	int fd;
-	struct ostat * up;
+	int	fd;	char fd_[PAD_(int)];
+	struct ostat *	up;	char up_[PAD_(struct ostat *)];
 };
 struct	linux_pause_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_utime_args {
-	char * fname;
-	struct linux_utimbuf * times;
+	char *	fname;	char fname_[PAD_(char *)];
+	struct linux_utimbuf *	times;	char times_[PAD_(struct linux_utimbuf *)];
 };
 struct	linux_stty_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_gtty_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_access_args {
-	char * path;
-	int flags;
+	char *	path;	char path_[PAD_(char *)];
+	int	flags;	char flags_[PAD_(int)];
 };
 struct	linux_nice_args {
-	int inc;
+	int	inc;	char inc_[PAD_(int)];
 };
 struct	linux_ftime_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_kill_args {
-	int pid;
-	int signum;
+	int	pid;	char pid_[PAD_(int)];
+	int	signum;	char signum_[PAD_(int)];
 };
 struct	linux_rename_args {
-	char * from;
-	char * to;
+	char *	from;	char from_[PAD_(char *)];
+	char *	to;	char to_[PAD_(char *)];
 };
 struct	linux_mkdir_args {
-	char * path;
-	int mode;
+	char *	path;	char path_[PAD_(char *)];
+	int	mode;	char mode_[PAD_(int)];
 };
 struct	linux_rmdir_args {
-	char * path;
+	char *	path;	char path_[PAD_(char *)];
 };
 struct	linux_pipe_args {
-	int * pipefds;
+	int *	pipefds;	char pipefds_[PAD_(int *)];
 };
 struct	linux_times_args {
-	struct linux_times_argv * buf;
+	struct linux_times_argv *	buf;	char buf_[PAD_(struct linux_times_argv *)];
 };
 struct	linux_prof_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_brk_args {
-	char * dsend;
+	char *	dsend;	char dsend_[PAD_(char *)];
 };
 struct	linux_signal_args {
-	int sig;
-	linux_handler_t handler;
+	int	sig;	char sig_[PAD_(int)];
+	linux_handler_t	handler;	char handler_[PAD_(linux_handler_t)];
 };
 struct	linux_phys_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_lock_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_ioctl_args {
-	int fd;
-	u_long cmd;
-	int arg;
+	int	fd;	char fd_[PAD_(int)];
+	u_long	cmd;	char cmd_[PAD_(u_long)];
+	int	arg;	char arg_[PAD_(int)];
 };
 struct	linux_fcntl_args {
-	int fd;
-	int cmd;
-	int arg;
+	int	fd;	char fd_[PAD_(int)];
+	int	cmd;	char cmd_[PAD_(int)];
+	int	arg;	char arg_[PAD_(int)];
 };
 struct	linux_mpx_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_ulimit_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_olduname_args {
-	struct linux_oldold_utsname * up;
+	struct linux_oldold_utsname *	up;	char up_[PAD_(struct linux_oldold_utsname *)];
 };
 struct	linux_ustat_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_sigaction_args {
-	int sig;
-	struct linux_sigaction * nsa;
-	struct linux_sigaction * osa;
+	int	sig;	char sig_[PAD_(int)];
+	struct linux_sigaction *	nsa;	char nsa_[PAD_(struct linux_sigaction *)];
+	struct linux_sigaction *	osa;	char osa_[PAD_(struct linux_sigaction *)];
 };
 struct	linux_siggetmask_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_sigsetmask_args {
-	linux_sigset_t mask;
+	linux_sigset_t	mask;	char mask_[PAD_(linux_sigset_t)];
 };
 struct	linux_sigsuspend_args {
-	int restart;
-	linux_sigset_t oldmask;
-	linux_sigset_t mask;
+	int	restart;	char restart_[PAD_(int)];
+	linux_sigset_t	oldmask;	char oldmask_[PAD_(linux_sigset_t)];
+	linux_sigset_t	mask;	char mask_[PAD_(linux_sigset_t)];
 };
 struct	linux_sigpending_args {
-	linux_sigset_t * mask;
+	linux_sigset_t *	mask;	char mask_[PAD_(linux_sigset_t *)];
 };
 struct	linux_select_args {
-	struct linux_select_argv * ptr;
+	struct linux_select_argv *	ptr;	char ptr_[PAD_(struct linux_select_argv *)];
 };
 struct	linux_symlink_args {
-	char * path;
-	char * to;
+	char *	path;	char path_[PAD_(char *)];
+	char *	to;	char to_[PAD_(char *)];
 };
 struct	linux_readlink_args {
-	char * name;
-	char * buf;
-	int count;
+	char *	name;	char name_[PAD_(char *)];
+	char *	buf;	char buf_[PAD_(char *)];
+	int	count;	char count_[PAD_(int)];
 };
 struct	linux_uselib_args {
-	char * library;
+	char *	library;	char library_[PAD_(char *)];
 };
 struct	linux_readdir_args {
-	int fd;
-	struct linux_dirent * dent;
-	unsigned int count;
+	int	fd;	char fd_[PAD_(int)];
+	struct linux_dirent *	dent;	char dent_[PAD_(struct linux_dirent *)];
+	unsigned int	count;	char count_[PAD_(unsigned int)];
 };
 struct	linux_mmap_args {
-	struct linux_mmap_argv * ptr;
+	struct linux_mmap_argv *	ptr;	char ptr_[PAD_(struct linux_mmap_argv *)];
 };
 struct	linux_truncate_args {
-	char * path;
-	long length;
+	char *	path;	char path_[PAD_(char *)];
+	long	length;	char length_[PAD_(long)];
 };
 struct	linux_statfs_args {
-	char * path;
-	struct linux_statfs_buf * buf;
+	char *	path;	char path_[PAD_(char *)];
+	struct linux_statfs_buf *	buf;	char buf_[PAD_(struct linux_statfs_buf *)];
 };
 struct	linux_fstatfs_args {
-	int fd;
-	struct linux_statfs_buf * buf;
+	int	fd;	char fd_[PAD_(int)];
+	struct linux_statfs_buf *	buf;	char buf_[PAD_(struct linux_statfs_buf *)];
 };
 struct	linux_ioperm_args {
-	unsigned int lo;
-	unsigned int hi;
-	int val;
+	unsigned int	lo;	char lo_[PAD_(unsigned int)];
+	unsigned int	hi;	char hi_[PAD_(unsigned int)];
+	int	val;	char val_[PAD_(int)];
 };
 struct	linux_socketcall_args {
-	int what;
-	void * args;
+	int	what;	char what_[PAD_(int)];
+	void *	args;	char args_[PAD_(void *)];
 };
 struct	linux_ksyslog_args {
-	int what;
+	int	what;	char what_[PAD_(int)];
 };
 struct	linux_setitimer_args {
-	u_int which;
-	struct itimerval * itv;
-	struct itimerval * oitv;
+	u_int	which;	char which_[PAD_(u_int)];
+	struct itimerval *	itv;	char itv_[PAD_(struct itimerval *)];
+	struct itimerval *	oitv;	char oitv_[PAD_(struct itimerval *)];
 };
 struct	linux_getitimer_args {
-	u_int which;
-	struct itimerval * itv;
+	u_int	which;	char which_[PAD_(u_int)];
+	struct itimerval *	itv;	char itv_[PAD_(struct itimerval *)];
 };
 struct	linux_newstat_args {
-	char * path;
-	struct linux_newstat * buf;
+	char *	path;	char path_[PAD_(char *)];
+	struct linux_newstat *	buf;	char buf_[PAD_(struct linux_newstat *)];
 };
 struct	linux_newlstat_args {
-	char * path;
-	struct linux_newstat * buf;
+	char *	path;	char path_[PAD_(char *)];
+	struct linux_newstat *	buf;	char buf_[PAD_(struct linux_newstat *)];
 };
 struct	linux_newfstat_args {
-	int fd;
-	struct linux_newstat * buf;
+	int	fd;	char fd_[PAD_(int)];
+	struct linux_newstat *	buf;	char buf_[PAD_(struct linux_newstat *)];
 };
 struct	linux_uname_args {
-	struct linux_old_utsname * up;
+	struct linux_old_utsname *	up;	char up_[PAD_(struct linux_old_utsname *)];
 };
 struct	linux_iopl_args {
-	int level;
+	int	level;	char level_[PAD_(int)];
 };
 struct	linux_vhangup_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_idle_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_vm86_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_wait4_args {
-	int pid;
-	int * status;
-	int options;
-	struct rusage * rusage;
+	int	pid;	char pid_[PAD_(int)];
+	int *	status;	char status_[PAD_(int *)];
+	int	options;	char options_[PAD_(int)];
+	struct rusage *	rusage;	char rusage_[PAD_(struct rusage *)];
 };
 struct	linux_swapoff_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_sysinfo_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_ipc_args {
-	int what;
-	int arg1;
-	int arg2;
-	int arg3;
-	caddr_t ptr;
+	int	what;	char what_[PAD_(int)];
+	int	arg1;	char arg1_[PAD_(int)];
+	int	arg2;	char arg2_[PAD_(int)];
+	int	arg3;	char arg3_[PAD_(int)];
+	caddr_t	ptr;	char ptr_[PAD_(caddr_t)];
 };
 struct	linux_sigreturn_args {
-	struct linux_sigcontext * scp;
+	struct linux_sigcontext *	scp;	char scp_[PAD_(struct linux_sigcontext *)];
 };
 struct	linux_clone_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_newuname_args {
-	struct linux_newuname_t * buf;
+	struct linux_newuname_t *	buf;	char buf_[PAD_(struct linux_newuname_t *)];
 };
 struct	linux_modify_ldt_args {
-	int func;
-	void * ptr;
-	size_t bytecount;
+	int	func;	char func_[PAD_(int)];
+	void *	ptr;	char ptr_[PAD_(void *)];
+	size_t	bytecount;	char bytecount_[PAD_(size_t)];
 };
 struct	linux_adjtimex_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_sigprocmask_args {
-	int how;
-	linux_sigset_t * mask;
-	linux_sigset_t * omask;
+	int	how;	char how_[PAD_(int)];
+	linux_sigset_t *	mask;	char mask_[PAD_(linux_sigset_t *)];
+	linux_sigset_t *	omask;	char omask_[PAD_(linux_sigset_t *)];
 };
 struct	linux_create_module_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_init_module_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_delete_module_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_get_kernel_syms_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_quotactl_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_getpgid_args {
-	int pid;
+	int	pid;	char pid_[PAD_(int)];
 };
 struct	linux_bdflush_args {
-	int dummy;
+	register_t dummy;
 };
 struct	linux_personality_args {
-	int per;
+	int	per;	char per_[PAD_(int)];
 };
 struct	linux_llseek_args {
-	int fd;
-	u_int32_t ohigh;
-	u_int32_t olow;
-	caddr_t res;
-	int whence;
+	int	fd;	char fd_[PAD_(int)];
+	u_int32_t	ohigh;	char ohigh_[PAD_(u_int32_t)];
+	u_int32_t	olow;	char olow_[PAD_(u_int32_t)];
+	caddr_t	res;	char res_[PAD_(caddr_t)];
+	int	whence;	char whence_[PAD_(int)];
 };
 struct	linux_getdents_args {
-	int fd;
-	void * dent;
-	unsigned count;
+	int	fd;	char fd_[PAD_(int)];
+	void *	dent;	char dent_[PAD_(void *)];
+	unsigned	count;	char count_[PAD_(unsigned)];
 };
 struct	linux_newselect_args {
-	int nfds;
-	fd_set * readfds;
-	fd_set * writefds;
-	fd_set * exceptfds;
-	struct timeval * timeout;
+	int	nfds;	char nfds_[PAD_(int)];
+	fd_set *	readfds;	char readfds_[PAD_(fd_set *)];
+	fd_set *	writefds;	char writefds_[PAD_(fd_set *)];
+	fd_set *	exceptfds;	char exceptfds_[PAD_(fd_set *)];
+	struct timeval *	timeout;	char timeout_[PAD_(struct timeval *)];
 };
 struct	linux_msync_args {
-	caddr_t addr;
-	int len;
-	int fl;
+	caddr_t	addr;	char addr_[PAD_(caddr_t)];
+	int	len;	char len_[PAD_(int)];
+	int	fl;	char fl_[PAD_(int)];
+};
+struct	linux_mremap_args {
+	caddr_t	addr;	char addr_[PAD_(caddr_t)];
+	int	old_len;	char old_len_[PAD_(int)];
+	int	new_len;	char new_len_[PAD_(int)];
+	int	flags;	char flags_[PAD_(int)];
+};
+struct	linux_chown_args {
+	char *	path;	char path_[PAD_(char *)];
+	int	uid;	char uid_[PAD_(int)];
+	int	gid;	char gid_[PAD_(int)];
 };
 int	linux_setup __P((struct proc *, struct linux_setup_args *, int []));
 int	linux_fork __P((struct proc *, struct linux_fork_args *, int []));
@@ -376,6 +392,7 @@
 int	linux_mknod __P((struct proc *, struct linux_mknod_args *, int []));
 int	linux_chmod __P((struct proc *, struct linux_chmod_args *, int []));
 int	linux_chown __P((struct proc *, struct linux_chown_args *, int []));
+int	linux_lchown __P((struct proc *, struct linux_lchown_args *, int []));
 int	linux_break __P((struct proc *, struct linux_break_args *, int []));
 int	linux_stat __P((struct proc *, struct linux_stat_args *, int []));
 int	linux_lseek __P((struct proc *, struct linux_lseek_args *, int []));
@@ -457,11 +474,14 @@
 int	linux_llseek __P((struct proc *, struct linux_llseek_args *, int []));
 int	linux_getdents __P((struct proc *, struct linux_getdents_args *, int []));
 int	linux_newselect __P((struct proc *, struct linux_newselect_args *, int []));
+int	linux_mremap __P((struct proc *, struct linux_mremap_args *, int []));
 int	linux_msync __P((struct proc *, struct linux_msync_args *, int []));
 
 #ifdef COMPAT_43
 
 
 #endif /* COMPAT_43 */
+
+#undef PAD_
 
 #endif /* !_LINUX_SYSPROTO_H_ */
diff -ru sys/i386/linux/linux_socket.c /sys/i386/linux/linux_socket.c
--- sys/i386/linux/linux_socket.c	Mon Dec 15 10:10:38 1997
+++ /sys/i386/linux/linux_socket.c	Thu Aug  6 09:43:21 1998
@@ -35,6 +35,7 @@
 #include <sys/systm.h>
 #include <sys/sysproto.h>
 #include <sys/proc.h>
+#include <sys/fcntl.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 
@@ -176,7 +177,7 @@
 {
 /*
  * linux_ip_copysize defines how many bytes we should copy
- * from the beginning of the IP packet before we change it for BSD.
+ * from the beginning of the IP packet before we customize it for BSD.
  * It should include all the fields we modify (ip_len and ip_off)
  * and be as small as possible to minimize copying overhead.
  */
@@ -198,6 +199,12 @@
     if (bsd_args->len < linux_ip_copysize)
 	return EINVAL;
 
+    /*
+     * Tweaking the user buffer in place would be bad manners.
+     * We create a corrected IP header with just the needed length,
+     * then use an iovec to glue it to the rest of the user packet
+     * when calling sendmsg().
+     */
     sg = stackgap_init();
     packet = (struct ip *)stackgap_alloc(&sg, linux_ip_copysize);
     msg = (struct msghdr *)stackgap_alloc(&sg, sizeof(*msg));
@@ -207,7 +214,7 @@
     if ((error = copyin(bsd_args->buf, (caddr_t)packet, linux_ip_copysize)))
         return error;
 
-    /* Convert it from Linux to BSD raw IP socket format */
+    /* Convert fields from Linux to BSD raw IP socket format */
     packet->ip_len = bsd_args->len;
     packet->ip_off = ntohs(packet->ip_off);
 
@@ -258,7 +265,7 @@
 
     retval_socket = socket(p, &bsd_args, retval);
 
-    if (retval_socket != -1
+    if (retval_socket >= 0
 	&& bsd_args.type == SOCK_RAW
 	&& bsd_args.domain == AF_INET
 	&& (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0)) {
@@ -272,20 +279,20 @@
 	} */ bsd_setsockopt_args;
 
 	int retval_setsockopt, r;
-	caddr_t sg, hdrincl;
-	int hdrinclval = 1;
+	caddr_t sg;
+//, hdrincl;
+//	int hdrinclval = 1;
+	int *hdrincl;
 
 	sg = stackgap_init();
-	hdrincl = stackgap_alloc(&sg, sizeof hdrinclval);
-
-	if ((error=copyout(&hdrinclval, hdrincl, sizeof hdrinclval)))
-	   return error;
+	hdrincl = (int *)stackgap_alloc(&sg, sizeof(*hdrincl));
+	*hdrincl = 1;
 
 	bsd_setsockopt_args.s = *retval;
 	bsd_setsockopt_args.level = IPPROTO_IP;
 	bsd_setsockopt_args.name = IP_HDRINCL;
-	bsd_setsockopt_args.val = hdrincl;
-	bsd_setsockopt_args.valsize = sizeof hdrinclval;
+	bsd_setsockopt_args.val = (caddr_t)hdrincl;
+	bsd_setsockopt_args.valsize = sizeof(*hdrincl);
 	r = setsockopt(p, &bsd_setsockopt_args, &retval_setsockopt);
     }
     return retval_socket;
@@ -338,7 +345,58 @@
     bsd_args.s = linux_args.s;
     bsd_args.name = (caddr_t)linux_args.name;
     bsd_args.namelen = linux_args.namelen;
-    return connect(p, &bsd_args, retval);
+    error = connect(p, &bsd_args, retval);
+    if (error == EISCONN) {
+	/*
+	 * Linux doesn't return EISCONN the first time it occurs,
+	 * when on a non-blocking socket. Instead it returns the
+	 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
+	 */
+	struct fcntl_args /* {
+	    int fd;
+	    int cmd;
+	    int arg;
+	} */ bsd_fcntl_args;
+	struct getsockopt_args /* {
+	    int s;
+	    int level;
+	    int name;
+	    caddr_t val;
+	    int *avalsize;
+	} */ bsd_getsockopt_args;
+	void *status, *statusl;
+	int stat, statl = sizeof stat;
+	caddr_t sg;
+
+	/* Check for non-blocking */
+	bsd_fcntl_args.fd = linux_args.s;
+	bsd_fcntl_args.cmd = F_GETFL;
+	bsd_fcntl_args.arg = 0;
+	error = fcntl(p, &bsd_fcntl_args, retval);
+	if (error == 0 && (*retval & O_NONBLOCK)) {
+	    sg = stackgap_init();
+	    status = stackgap_alloc(&sg, sizeof stat);
+	    statusl = stackgap_alloc(&sg, sizeof statusl);
+
+	    if ((error = copyout(&statl, statusl, sizeof statl)))
+		return error;
+
+	    bsd_getsockopt_args.s = linux_args.s;
+	    bsd_getsockopt_args.level = SOL_SOCKET;
+	    bsd_getsockopt_args.name = SO_ERROR;
+	    bsd_getsockopt_args.val = status;
+	    bsd_getsockopt_args.avalsize = statusl;
+
+	    error = getsockopt(p, &bsd_getsockopt_args, retval);
+	    if (error)
+		return error;
+	    if ((error = copyin(status, &stat, sizeof stat)))
+		return error;
+	    *retval = stat;
+	    return 0;
+	}
+    }
+    return error;
 }
 
 struct linux_listen_args {
@@ -651,6 +709,10 @@
     case IPPROTO_IP:
 	name = linux_to_bsd_ip_sockopt(linux_args.optname);
 	break;
+    case IPPROTO_TCP:
+	/* Linux TCP option values match BSD's */
+	name = linux_args.optname;
+	break;
     default:
 	return EINVAL;
     }
@@ -693,6 +755,10 @@
 	break;
     case IPPROTO_IP:
 	name = linux_to_bsd_ip_sockopt(linux_args.optname);
+	break;
+    case IPPROTO_TCP:
+	/* Linux TCP option values match BSD's */
+	name = linux_args.optname;
 	break;
     default:
 	return EINVAL;
diff -ru sys/i386/linux/linux_syscall.h /sys/i386/linux/linux_syscall.h
--- sys/i386/linux/linux_syscall.h	Tue Mar  5 05:03:10 1996
+++ /sys/i386/linux/linux_syscall.h	Thu Aug  6 08:54:01 1998
@@ -21,7 +21,7 @@
 #define	LINUX_SYS_linux_time	13
 #define	LINUX_SYS_linux_mknod	14
 #define	LINUX_SYS_linux_chmod	15
-#define	LINUX_SYS_linux_chown	16
+#define	LINUX_SYS_linux_lchown	16
 #define	LINUX_SYS_linux_break	17
 #define	LINUX_SYS_linux_stat	18
 #define	LINUX_SYS_linux_lseek	19
@@ -148,4 +148,19 @@
 #define	LINUX_SYS_linux_msync	144
 #define	LINUX_SYS_readv	145
 #define	LINUX_SYS_writev	146
-#define	LINUX_SYS_MAXSYSCALL	147
+#define	LINUX_SYS_mlock	150
+#define	LINUX_SYS_munlock	151
+#define	LINUX_SYS_mlockall	152
+#define	LINUX_SYS_munlockall	153
+#define	LINUX_SYS_sched_setparam	154
+#define	LINUX_SYS_sched_getparam	155
+#define	LINUX_SYS_sched_setscheduler	156
+#define	LINUX_SYS_sched_getscheduler	157
+#define	LINUX_SYS_sched_yield	158
+#define	LINUX_SYS_sched_get_priority_max	159
+#define	LINUX_SYS_sched_get_priority_min	160
+#define	LINUX_SYS_sched_rr_get_interval	161
+#define	LINUX_SYS_nanosleep	162
+#define	LINUX_SYS_linux_mremap	163
+#define	LINUX_SYS_linux_chown	182
+#define	LINUX_SYS_MAXSYSCALL	183
diff -ru sys/i386/linux/linux_sysent.c /sys/i386/linux/linux_sysent.c
--- sys/i386/linux/linux_sysent.c	Tue Mar  5 05:03:11 1996
+++ /sys/i386/linux/linux_sysent.c	Thu Aug  6 09:45:30 1998
@@ -37,7 +37,7 @@
 	{ 1, (sy_call_t *)linux_time },			/* 13 = linux_time */
 	{ 3, (sy_call_t *)linux_mknod },		/* 14 = linux_mknod */
 	{ 2, (sy_call_t *)linux_chmod },		/* 15 = linux_chmod */
-	{ 3, (sy_call_t *)linux_chown },		/* 16 = linux_chown */
+	{ 3, (sy_call_t *)linux_lchown },		/* 16 = linux_lchown */
 	{ 1, (sy_call_t *)linux_break },		/* 17 = linux_break */
 	{ 2, (sy_call_t *)linux_stat },			/* 18 = linux_stat */
 	{ 3, (sy_call_t *)linux_lseek },		/* 19 = linux_lseek */
@@ -55,7 +55,7 @@
 	{ 0, (sy_call_t *)linux_stty },			/* 31 = linux_stty */
 	{ 0, (sy_call_t *)linux_gtty },			/* 32 = linux_gtty */
 	{ 2, (sy_call_t *)linux_access },		/* 33 = linux_access */
-	{ 0, (sy_call_t *)linux_nice },			/* 34 = linux_nice */
+	{ 1, (sy_call_t *)linux_nice },			/* 34 = linux_nice */
 	{ 0, (sy_call_t *)linux_ftime },		/* 35 = linux_ftime */
 	{ 0, (sy_call_t *)sync },			/* 36 = sync */
 	{ 2, (sy_call_t *)linux_kill },			/* 37 = linux_kill */
@@ -168,4 +168,40 @@
 	{ 3, (sy_call_t *)linux_msync },		/* 144 = linux_msync */
 	{ 3, (sy_call_t *)readv },			/* 145 = readv */
 	{ 3, (sy_call_t *)writev },			/* 146 = writev */
+	{ 0, (sy_call_t *)nosys },			/* 147 = getsid */
+	{ 0, (sy_call_t *)nosys },			/* 148 = fdatasync */
+	{ 0, (sy_call_t *)nosys },			/* 149 = _sysctl */
+	{ 2, (sy_call_t *)mlock },			/* 150 = mlock */
+	{ 2, (sy_call_t *)munlock },			/* 151 = munlock */
+	{ 0, (sy_call_t *)nosys },			/* 152 = mlockall */
+	{ 0, (sy_call_t *)nosys },			/* 153 = munlockall */
+	{ 0, (sy_call_t *)nosys },		/* 154 = sched_setparam */
+	{ 0, (sy_call_t *)nosys },		/* 155 = sched_getparam */
+	{ 0, (sy_call_t *)nosys },		/* 156 = sched_setscheduler */
+	{ 0, (sy_call_t *)nosys },		/* 157 = sched_getscheduler */
+	{ 0, (sy_call_t *)nosys },		/* 158 = sched_yield */
+	{ 0, (sy_call_t *)nosys },		/* 159 = sched_get_priority_max */
+	{ 0, (sy_call_t *)nosys },		/* 160 = sched_get_priority_min */
+	{ 0, (sy_call_t *)nosys },		/* 161 = sched_rr_get_interval */
+	{ 0, (sy_call_t *)nosys },			/* 162 = nanosleep */
+	{ 4, (sy_call_t *)linux_mremap },		/* 163 = linux_mremap */
+	{ 0, (sy_call_t *)nosys },			/* 164 = setresuid */
+	{ 0, (sy_call_t *)nosys },			/* 165 = getresuid */
+	{ 0, (sy_call_t *)nosys },			/* 166 = new_vm86 */
+	{ 0, (sy_call_t *)nosys },			/* 167 = query_module */
+	{ 0, (sy_call_t *)nosys },			/* 168 = poll */
+	{ 0, (sy_call_t *)nosys },			/* 169 = nfsservctl */
+	{ 0, (sy_call_t *)nosys },			/* 170 = setresgid */
+	{ 0, (sy_call_t *)nosys },			/* 171 = getresgid */
+	{ 0, (sy_call_t *)nosys },			/* 172 = prctl */
+	{ 0, (sy_call_t *)nosys },			/* 173 = rt_sigreturn */
+	{ 0, (sy_call_t *)nosys },			/* 174 = rt_sigaction */
+	{ 0, (sy_call_t *)nosys },			/* 175 = rt_sigprocmask */
+	{ 0, (sy_call_t *)nosys },			/* 176 = rt_sigpending */
+	{ 0, (sy_call_t *)nosys },			/* 177 = rt_sigtimedwait */
+	{ 0, (sy_call_t *)nosys },			/* 178 = rt_sigqueueinfo */
+	{ 0, (sy_call_t *)nosys },			/* 179 = rt_sigsuspend */
+	{ 0, (sy_call_t *)nosys },			/* 180 = pread */
+	{ 0, (sy_call_t *)nosys },			/* 181 = pwrite */
+	{ 3, (sy_call_t *)linux_chown },		/* 182 = linux_chown */
 };
diff -ru sys/i386/linux/linux_sysvec.c /sys/i386/linux/linux_sysvec.c
--- sys/i386/linux/linux_sysvec.c	Wed May 13 15:04:46 1998
+++ /sys/i386/linux/linux_sysvec.c	Thu Aug  6 09:49:00 1998
@@ -65,15 +65,19 @@
 #include <i386/linux/linux.h>
 #include <i386/linux/linux_proto.h>
 
-int	linux_fixup __P((int **stack_base, struct image_params *iparams));
-int	elf_linux_fixup __P((int **stack_base, struct image_params *iparams));
-void	linux_prepsyscall __P((struct trapframe *tf, int *args, u_int *code, caddr_t *params));
-void    linux_sendsig __P((sig_t catcher, int sig, int mask, u_long code));
+static int	linux_fixup __P((int **stack_base,
+				struct image_params *iparams));
+static int	elf_linux_fixup __P((int **stack_base,
+				    struct image_params *iparams));
+static void	linux_prepsyscall __P((struct trapframe *tf, int *args,
+				       u_int *code, caddr_t *params));
+static void    linux_sendsig __P((sig_t catcher, int sig, int mask,
+				 u_long code));
 
 /*
  * Linux syscalls return negative errno's, we do positive and map them
  */
-int bsd_to_linux_errno[ELAST] = {
+static int bsd_to_linux_errno[ELAST] = {
   	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
  	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
  	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
@@ -82,7 +86,7 @@
 	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
 	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
 	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
-  	-6, 
+  	-6 
 };
 
 int bsd_to_linux_signal[NSIG] = {
@@ -123,7 +127,8 @@
 	}
 }
 
-int linux_fixup(int **stack_base, struct image_params *imgp)
+static int
+linux_fixup(int **stack_base, struct image_params *imgp)
 {
 	int *argv, *envp;
 
@@ -138,7 +143,8 @@
 	return 0;
 }
 
-int elf_linux_fixup(int **stack_base, struct image_params *imgp)
+static int
+elf_linux_fixup(int **stack_base, struct image_params *imgp)
 {
 	Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs;
 	int *pos;
@@ -185,7 +191,7 @@
  * specified pc, psl.
  */
 
-void
+static void
 linux_sendsig(sig_t catcher, int sig, int mask, u_long code)
 {
 	register struct proc *p = curproc;
@@ -439,5 +445,17 @@
  * XXX: this is WRONG, it needs to be SI_SUB_EXEC, but this is just at the
  * "proof of concept" stage and will be fixed shortly
  */
-SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, elf_insert_brand_entry, &linux_brand);
+static void linux_elf_init __P((void *dummy));
+
+static void
+linux_elf_init(dummy)
+	void *dummy;
+{
+	if (elf_insert_brand_entry(&linux_brand) < 0)
+		printf("cannot insert Linux elf brand handler\n");
+	else if (bootverbose)
+		printf("Linux-ELF exec handler installed\n");
+}
+
+SYSINIT(linuxelf, SI_SUB_VFS, SI_ORDER_ANY, linux_elf_init, NULL);
 #endif
diff -ru sys/i386/linux/syscalls.master /sys/i386/linux/syscalls.master
--- sys/i386/linux/syscalls.master	Tue Mar  5 04:58:47 1996
+++ /sys/i386/linux/syscalls.master	Thu Aug  6 09:30:43 1998
@@ -49,7 +49,7 @@
 13	STD	LINUX	{ int linux_time(linux_time_t *tm); }
 14	STD	LINUX	{ int linux_mknod(char *path, int mode, int dev); }
 15	STD	LINUX	{ int linux_chmod(char *path, int mode); }
-16	STD	LINUX	{ int linux_chown(char *path, int uid, int gid); }
+16	STD	LINUX	{ int linux_lchown(char *path, int uid, int gid); }
 17	STD	LINUX	{ int linux_break(char *nsize); }
 18	STD	LINUX	{ int linux_stat(char *path, struct ostat *up); }
 19	STD	LINUX	{ int linux_lseek(int fdes, long off, int whence); }
@@ -67,7 +67,7 @@
 31	STD	LINUX	{ int linux_stty(void); }
 32	STD	LINUX	{ int linux_gtty(void); }
 33	STD	LINUX	{ int linux_access(char *path, int flags); }
-34	STD	LINUX	{ int linux_nice(void); }
+34	STD	LINUX	{ int linux_nice(int inc); }
 35	STD	LINUX	{ int linux_ftime(void); }
 36	NOPROTO	LINUX	{ int sync(void); }
 37	STD	LINUX	{ int linux_kill(int pid, int signum); }
@@ -209,3 +209,50 @@
 				u_int iovcnt); }
 146	NOPROTO	LINUX	{ int writev(int fd, struct iovec *iovp, \
 				u_int iovcnt); }
+
+; Turn on getsid after checking that it matches.
+
+147	UNIMPL	LINUX	getsid
+148	UNIMPL	LINUX	fdatasync
+149	UNIMPL	LINUX	_sysctl
+
+150	NOPROTO	BSD	{ int mlock(const void *addr, size_t len); }
+151	NOPROTO	BSD	{ int munlock(const void *addr, size_t len); }
+152	NOPROTO	BSD	{ int mlockall(int how); }
+153	NOPROTO	BSD	{ int munlockall(void); }
+
+154	NOPROTO	POSIX	{ int sched_setparam (pid_t pid, const struct sched_param *param); }
+155	NOPROTO	POSIX	{ int sched_getparam (pid_t pid, struct sched_param *param); }
+
+156	NOPROTO	POSIX	{ int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
+157	NOPROTO	POSIX	{ int sched_getscheduler (pid_t pid); }
+
+158	NOPROTO	POSIX	{ int sched_yield (void); }
+159	NOPROTO	POSIX	{ int sched_get_priority_max (int policy); }
+160	NOPROTO	POSIX	{ int sched_get_priority_min (int policy); }
+161	NOPROTO	POSIX	{ int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
+
+162	NOPROTO	POSIX	{ int nanosleep(const struct timespec *rqtp, \
+			    struct timespec *rmtp); }
+
+163	STD	LINUX	{ int linux_mremap(caddr_t addr, int old_len, \
+			    int new_len, int flags); }
+164	UNIMPL	LINUX	setresuid
+165	UNIMPL	LINUX	getresuid
+166	UNIMPL	LINUX	new_vm86
+167	UNIMPL	LINUX	query_module
+168	UNIMPL	LINUX	poll
+169	UNIMPL	LINUX	nfsservctl
+170	UNIMPL	LINUX	setresgid
+171	UNIMPL	LINUX	getresgid
+172	UNIMPL	LINUX	prctl
+173	UNIMPL	LINUX	rt_sigreturn
+174	UNIMPL	LINUX	rt_sigaction
+175	UNIMPL	LINUX	rt_sigprocmask
+176	UNIMPL	LINUX	rt_sigpending
+177	UNIMPL	LINUX	rt_sigtimedwait
+178	UNIMPL	LINUX	rt_sigqueueinfo
+179	UNIMPL	LINUX	rt_sigsuspend
+180	UNIMPL	LINUX	pread
+181	UNIMPL	LINUX	pwrite
+182	STD	LINUX	{ int linux_chown(char *path, int uid, int gid); }
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: gnats-admin->freebsd-bugs 
Responsible-Changed-By: steve 
Responsible-Changed-When: Mon Sep 7 14:43:07 PDT 1998 
Responsible-Changed-Why:  
Misfiled PR.  (I still haven't figured out why Avatar.) 
State-Changed-From-To: open->closed 
State-Changed-By: jkh 
State-Changed-When: Wed Sep 23 07:12:54 PDT 1998 
State-Changed-Why:  
Thanks, folded into -stable! 
>Unformatted:
