Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Nov 1998 12:52:35 -0500 (EST)
From:      Brian Feldman <green@zone.syracuse.net>
To:        current@FreeBSD.ORG
Subject:   linux_clone news
Message-ID:  <Pine.BSF.4.05.9811031248150.29837-100000@zone.syracuse.net>

next in thread | raw e-mail | index | archive | help
Linux_clone() works! Or at least it seems to work correctly now. I have
a proper patchset now as well, attached at the end of this message. Bad
news: linuxthreads still does not work right. Altho I seem to have
corrected and redone the inaccurate parts of my code (thanks SO MUCH
Luoqi, you were really key in helping me here :), there seems to be some
kind of spinning pthread_create(). If anyone would like to apply my Linux
emulation patches, download LinuxThreads, and work on helping the state of
FreeBSD's Linux emulation out here, please do!

Cheers,
Brian Feldman

--cut here---patch begins---
diff -u usr/src/sys/i386/linux/linux_dummy.c
/usr/src/sys/i386/linux/linux_dummy.c
--- usr/src/sys/i386/linux/linux_dummy.c	Thu Nov  6 14:28:52 1997
+++ /usr/src/sys/i386/linux/linux_dummy.c	Mon Nov  2 20:40:16 1998
@@ -212,13 +212,6 @@
 }
 
 int
-linux_clone(struct proc *p, struct linux_clone_args *args)
-{
-    printf("Linux-emul(%d): clone() not supported\n", p->p_pid);
-    return ENOSYS;
-}
-
-int
 linux_uname(struct proc *p, struct linux_uname_args *args)
 {
     printf("Linux-emul(%d): uname() not supported\n", p->p_pid);
diff -u usr/src/sys/i386/linux/linux_misc.c
/usr/src/sys/i386/linux/linux_misc.c
--- usr/src/sys/i386/linux/linux_misc.c	Mon Oct  5 08:40:42 1998
+++ /usr/src/sys/i386/linux/linux_misc.c	Tue Nov  3 10:55:49 1998
@@ -41,6 +41,7 @@
 #include <sys/resourcevar.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
+#include <sys/unistd.h>
 #include <sys/vnode.h>
 #include <sys/wait.h>
 #include <sys/time.h>
@@ -557,6 +558,50 @@
 	return error;
     if (p->p_retval[1] == 1)
 	p->p_retval[0] = 0;
+    return 0;
+}
+
+#define CLONE_VM	0x100
+#define CLONE_FS	0x200
+#define CLONE_FILES	0x400
+#define CLONE_SIGHAND	0x800
+#define CLONE_PID	0x1000
+
+int
+linux_clone(struct proc *p, struct linux_clone_args *args)
+{
+    int error, ff = RFPROC, top;
+    struct proc *p2;
+
+#ifdef DEBUG_CLONE
+    printf("linux_clone(%#x, %#x)\n", ((int *)args)[0],
+	((int *)args)[1]);
+    if (args->flags & CLONE_PID)
+	printf("linux_clone: CLONE_PID not yet supported\n");
+    if (args->flags & CLONE_FS)
+	printf("linux_clone: CLONE_FS not yet supported\n");
+    if (args->flags & CLONE_SIGHAND)
+	printf("linux_clone: CLONE_SIGHAND not yet supported\n");
+#endif
+    if (args->flags & CLONE_VM)
+	ff |= RFMEM;
+    ff |= (args->flags & CLONE_FILES) ? RFFDG : RFCFDG;
+    if (error = fork1(p, ff))
+	return error;
+    p2 = pfind(p->p_retval[0]);
+    if (p2 == 0)
+	return ESRCH;
+    if (args->stack) {
+	copyin(args->stack, &top, 4);
+	p2->p_md.md_regs->tf_esp = (int)args->stack;
+	p2->p_md.md_regs->tf_eip = top;
+     }
+#ifdef DEBUG_CLONE
+    copyin(args->stack + 4, &top, 4);
+    printf("linux_clone: pids %d, %d; child eip=%#x, esp=%#x,
*esp=%#x\n",
+	p->p_pid, p2->p_pid, p2->p_md.md_regs->tf_eip,
p2->p_md.md_regs->tf_esp,
+	top);
+#endif
     return 0;
 }
 
diff -u usr/src/sys/i386/linux/linux_proto.h
/usr/src/sys/i386/linux/linux_proto.h
--- usr/src/sys/i386/linux/linux_proto.h	Fri Jul 10 18:30:04 1998
+++ /usr/src/sys/i386/linux/linux_proto.h	Tue Nov  3 09:31:51 1998
@@ -2,7 +2,7 @@
  * System call prototypes.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from	Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde
Exp 
+ * created from	Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh
Exp 
  */
 
 #ifndef _LINUX_SYSPROTO_H_
@@ -301,7 +301,8 @@
 	struct linux_sigcontext *	scp;	char scp_[PAD_(struct
linux_sigcontext *)];
 };
 struct	linux_clone_args {
-	register_t dummy;
+	int	flags;	char flags_[PAD_(int)];
+	void *	stack;	char stack_[PAD_(void *)];
 };
 struct	linux_newuname_args {
 	struct linux_newuname_t *	buf;	char buf_[PAD_(struct
linux_newuname_t *)];
Only in usr/src/sys/i386/linux/: linux_proto.h.bak
diff -u usr/src/sys/i386/linux/linux_syscall.h
/usr/src/sys/i386/linux/linux_syscall.h
--- usr/src/sys/i386/linux/linux_syscall.h	Fri Jul 10 18:30:06 1998
+++ /usr/src/sys/i386/linux/linux_syscall.h	Tue Nov  3 09:31:51 1998
@@ -2,7 +2,7 @@
  * System call numbers.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from	Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde
Exp 
+ * created from	Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh
Exp 
  */
 
 #define	LINUX_SYS_linux_setup	0
Only in usr/src/sys/i386/linux/: linux_syscall.h.bak
diff -u usr/src/sys/i386/linux/linux_sysent.c
/usr/src/sys/i386/linux/linux_sysent.c
--- usr/src/sys/i386/linux/linux_sysent.c	Fri Jul 10 18:30:07 1998
+++ /usr/src/sys/i386/linux/linux_sysent.c	Tue Nov  3 09:31:51 1998
@@ -2,7 +2,7 @@
  * System call switch table.
  *
  * DO NOT EDIT-- this file is automatically generated.
- * created from	Id: syscalls.master,v 1.11 1998/06/09 03:28:14 bde
Exp 
+ * created from	Id: syscalls.master,v 1.12 1998/07/10 22:30:08 jkh
Exp 
  */
 
 #include "opt_compat.h"
@@ -134,7 +134,7 @@
 	{ 5, (sy_call_t *)linux_ipc },			/* 117 = linux_ipc
*/
 	{ 1, (sy_call_t *)fsync },			/* 118 = fsync */
 	{ 1, (sy_call_t *)linux_sigreturn },		/* 119 =
linux_sigreturn */
-	{ 0, (sy_call_t *)linux_clone },		/* 120 =
linux_clone */
+	{ 2, (sy_call_t *)linux_clone },		/* 120 =
linux_clone */
 	{ 2, (sy_call_t *)setdomainname },		/* 121 =
setdomainname */
 	{ 1, (sy_call_t *)linux_newuname },		/* 122 =
linux_newuname */
 	{ 3, (sy_call_t *)linux_modify_ldt },		/* 123 =
linux_modify_ldt */
Only in usr/src/sys/i386/linux/: linux_sysent.c.bak
diff -u usr/src/sys/i386/linux/syscalls.master
/usr/src/sys/i386/linux/syscalls.master
--- usr/src/sys/i386/linux/syscalls.master	Fri Jul 10 18:30:08 1998
+++ /usr/src/sys/i386/linux/syscalls.master	Tue Nov  3 09:31:44 1998
@@ -171,7 +171,7 @@
 			    caddr_t ptr); }
 118	NOPROTO	LINUX	{ int fsync(int fd); }
 119	STD	LINUX	{ int linux_sigreturn(struct linux_sigcontext
*scp); }
-120	STD	LINUX	{ int linux_clone(void); }
+120	STD	LINUX	{ int linux_clone(int flags, void *stack); }
 121	NOPROTO	LINUX	{ int setdomainname(char *name, \
 			    int len); }
 122	STD	LINUX	{ int linux_newuname(struct linux_newuname_t
*buf); }



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9811031248150.29837-100000>