wait4.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * wait4() for uClibc
  3. *
  4. * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  5. *
  6. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  7. */
  8. #include <sys/syscall.h>
  9. #include <sys/wait.h>
  10. #include <sys/resource.h>
  11. #if defined(__NR_wait4)
  12. # define __NR___syscall_wait4 __NR_wait4
  13. static __always_inline _syscall4(int, __syscall_wait4, __kernel_pid_t, pid,
  14. int *, status, int, opts, struct rusage *, rusage)
  15. pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage)
  16. {
  17. #if defined(__UCLIBC_USE_TIME64__)
  18. char *arg_rusage = rusage ? (char *)&rusage->ru_maxrss - 4 * sizeof(__S32_TYPE) : 0;
  19. int __ret = __syscall_wait4(pid, status, opts, (struct rusage *)arg_rusage);
  20. if (__ret > 0 && rusage) {
  21. __S32_TYPE __rusage[4];
  22. memcpy(__rusage, arg_rusage, 4 * sizeof(__S32_TYPE));
  23. struct timeval tv_utime = {.tv_sec = __rusage[0], .tv_usec = __rusage[1]};
  24. struct timeval tv_stime = {.tv_sec = __rusage[2], .tv_usec = __rusage[2]};
  25. rusage->ru_utime = tv_utime;
  26. rusage->ru_stime = tv_stime;
  27. }
  28. return __ret;
  29. #else
  30. return __syscall_wait4(pid, status, opts, rusage);
  31. #endif
  32. }
  33. #else
  34. pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage)
  35. {
  36. idtype_t type;
  37. int __res;
  38. siginfo_t info;
  39. info.si_pid = 0;
  40. if (pid < -1) {
  41. type = P_PGID;
  42. pid = -pid;
  43. } else if (pid == -1) {
  44. type = P_ALL;
  45. } else if (pid == 0) {
  46. type = P_PGID;
  47. } else {
  48. type = P_PID;
  49. }
  50. __res = INLINE_SYSCALL(waitid, 5, type, pid, &info, opts|WEXITED, rusage);
  51. if ( __res < 0 )
  52. return __res;
  53. if (info.si_pid && status) {
  54. int sw = 0;
  55. switch (info.si_code) {
  56. case CLD_CONTINUED:
  57. sw = 0xffff;
  58. break;
  59. case CLD_DUMPED:
  60. sw = (info.si_status & 0x7f) | 0x80;
  61. break;
  62. case CLD_EXITED:
  63. sw = (info.si_status & 0xff) << 8;
  64. break;
  65. case CLD_KILLED:
  66. sw = info.si_status & 0x7f;
  67. break;
  68. case CLD_STOPPED:
  69. case CLD_TRAPPED:
  70. sw = (info.si_status << 8) + 0x7f;
  71. break;
  72. }
  73. *status = sw;
  74. }
  75. return info.si_pid;
  76. }
  77. #endif
  78. #ifdef __USE_BSD
  79. strong_alias(__wait4_nocancel,wait4)
  80. #endif