/* * Copyright (C) 2004 Atmel Corporation * * This file is subject to the terms and conditions of the GNU Lesser General * Public License. See the file "COPYING.LIB" in the main directory of this * archive for more details. */ #include <errno.h> #include <sys/syscall.h> #include <unistd.h> /* * I don't know if we can be absolutely certain that the fn and arg * parameters are preserved when returning as the child. If the * compiler stores them in registers (r0-r7), they should be. */ int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) { register int (*_fn)(void *arg) = fn; register void *_arg = arg; int err; /* Sanity check the arguments */ err = -EINVAL; if (!fn) goto syscall_error; if (!child_stack) goto syscall_error; err = INLINE_SYSCALL(clone, 2, flags, child_stack); if (err < 0) goto syscall_error; else if (err != 0) return err; _exit(_fn(_arg)); syscall_error: __set_errno (-err); return -1; }