clone.c 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /*
  2. * libc/sysdeps/linux/v850/clone.c -- `clone' syscall for linux/v850
  3. *
  4. * Copyright (C) 2002 NEC Electronics Corporation
  5. * Copyright (C) 2002 Miles Bader <miles@gnu.org>
  6. *
  7. * This file is subject to the terms and conditions of the GNU General
  8. * Public License. See the file COPYING in the main directory of this
  9. * archive for more details.
  10. *
  11. * Written by Miles Bader <miles@gnu.org>
  12. */
  13. #include <errno.h>
  14. #include <sys/syscall.h>
  15. int
  16. clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg)
  17. {
  18. register unsigned long rval asm (SYSCALL_RET) = -EINVAL;
  19. if (fn && child_stack)
  20. {
  21. register unsigned long syscall asm (SYSCALL_NUM);
  22. register unsigned long arg0 asm (SYSCALL_ARG0);
  23. /* Clone this thread. */
  24. arg0 = flags;
  25. syscall = __NR_clone;
  26. asm volatile ("trap " SYSCALL_SHORT_TRAP
  27. : "=r" (rval), "=r" (syscall)
  28. : "1" (syscall), "r" (arg0)
  29. : SYSCALL_SHORT_CLOBBERS);
  30. if (rval == 0)
  31. /* In child thread, call FN and exit. */
  32. {
  33. arg0 = (*fn) (arg);
  34. syscall = __NR_exit;
  35. asm volatile ("trap " SYSCALL_SHORT_TRAP
  36. : "=r" (rval), "=r" (syscall)
  37. : "1" (syscall), "r" (arg0)
  38. : SYSCALL_SHORT_CLOBBERS);
  39. }
  40. }
  41. __syscall_return (int, rval);
  42. }