waitid.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Copyright (C) 2007 Erik Andersen <andersen@uclibc.org>
  4. *
  5. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  6. */
  7. #include <features.h>
  8. #if defined __USE_SVID || defined __USE_XOPEN
  9. # include <string.h>
  10. # include <sys/types.h>
  11. # include <sys/wait.h>
  12. # include <sys/syscall.h>
  13. # ifdef __NR_waitid
  14. # ifdef __UCLIBC_HAS_THREADS_NATIVE__
  15. # include <sysdep-cancel.h>
  16. # else
  17. # define SINGLE_THREAD_P 1
  18. # endif
  19. /* The waitid() POSIX interface takes 4 arguments, but the kernel function
  20. * actually takes 5. The fifth is a pointer to struct rusage. Make sure
  21. * we pass NULL rather than letting whatever was in the register bleed up.
  22. */
  23. #define __NR_waitid5 __NR_waitid
  24. static __always_inline
  25. _syscall5(int, waitid5, idtype_t, idtype, id_t, id, siginfo_t*, infop,
  26. int, options, struct rusage*, ru)
  27. # endif
  28. int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
  29. {
  30. # ifdef __NR_waitid
  31. if (SINGLE_THREAD_P)
  32. return waitid5(idtype, id, infop, options, NULL);
  33. # ifdef __UCLIBC_HAS_THREADS_NATIVE__
  34. int oldtype = LIBC_CANCEL_ASYNC ();
  35. int result = waitid5(idtype, id, infop, options, NULL);
  36. LIBC_CANCEL_RESET (oldtype);
  37. return result;
  38. # endif
  39. # elif defined __NR_waitpid
  40. switch (idtype) {
  41. case P_PID:
  42. if (id <= 0)
  43. goto invalid;
  44. break;
  45. case P_PGID:
  46. if (id < 0 || id == 1)
  47. goto invalid;
  48. id = -id;
  49. break;
  50. case P_ALL:
  51. id = -1;
  52. break;
  53. default:
  54. invalid:
  55. __set_errno(EINVAL);
  56. return -1;
  57. }
  58. memset(infop, 0, sizeof *infop);
  59. infop->si_pid = waitpid(id, &infop->si_status, options
  60. # ifdef WEXITED
  61. &~ WEXITED
  62. # endif
  63. );
  64. if (infop->si_pid < 0)
  65. return infop->si_pid;
  66. return 0;
  67. # else
  68. __set_errno(ENOSYS);
  69. return -1;
  70. # endif
  71. }
  72. #endif