summaryrefslogtreecommitdiffstats
path: root/sys/alpha/linux/linux_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/alpha/linux/linux_machdep.c')
-rw-r--r--sys/alpha/linux/linux_machdep.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/sys/alpha/linux/linux_machdep.c b/sys/alpha/linux/linux_machdep.c
index fc8f96f..3e51d89 100644
--- a/sys/alpha/linux/linux_machdep.c
+++ b/sys/alpha/linux/linux_machdep.c
@@ -33,6 +33,7 @@
#include <sys/mount.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
+#include <sys/unistd.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -115,7 +116,62 @@ linux_vfork(struct proc *p, struct linux_vfork_args *args)
int
linux_clone(struct proc *p, struct linux_clone_args *args)
{
- return ENOSYS;
+ int error, ff = RFPROC;
+ struct proc *p2;
+ int exit_signal;
+ vm_offset_t start;
+ struct rfork_args rf_args;
+
+#ifdef DEBUG
+ if (args->flags & CLONE_PID)
+ printf("linux_clone(%ld): CLONE_PID not yet supported\n",
+ (long)p->p_pid);
+ uprintf("linux_clone(%ld): invoked with flags 0x%x and stack %p\n",
+ (long)p->p_pid, (unsigned int)args->flags,
+ args->stack);
+#endif
+
+ if (!args->stack)
+ return (EINVAL);
+
+ exit_signal = args->flags & 0x000000ff;
+ if (exit_signal >= LINUX_NSIG)
+ return (EINVAL);
+
+/* if (exit_signal <= LINUX_SIGTBLSZ)
+ exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)];
+*/
+ /* RFTHREAD probably not necessary here, but it shouldn't hurt */
+ ff |= RFTHREAD;
+
+ if (args->flags & CLONE_VM)
+ ff |= RFMEM;
+ if (args->flags & CLONE_SIGHAND)
+ ff |= RFSIGSHARE;
+ if (!(args->flags & CLONE_FILES))
+ ff |= RFFDG;
+
+ error = 0;
+ start = 0;
+
+ rf_args.flags = ff;
+ if ((error = rfork(p, &rf_args)) != 0)
+ return (error);
+
+ p2 = pfind(p->p_retval[0]);
+ if (p2 == 0)
+ return (ESRCH);
+
+ p2->p_sigparent = exit_signal;
+ p2->p_addr->u_pcb.pcb_hw.apcb_usp = (unsigned long)args->stack;
+
+#ifdef DEBUG
+ uprintf ("linux_clone(%ld): successful rfork to %ld, stack %p, sig = %d\n",
+(long)p->p_pid, (long)p2->p_pid, args->stack, exit_signal);
+#endif
+
+ return (0);
+
}
#define STACK_SIZE (2 * 1024 * 1024)
OpenPOWER on IntegriCloud