]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/common/waitid.c
Inital import
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / common / waitid.c
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
8 #include <features.h>
9
10 #if defined __USE_SVID || defined __USE_XOPEN
11 # include <string.h>
12 # include <sys/types.h>
13 # include <sys/wait.h>
14 # include <sys/syscall.h>
15
16 # ifdef __NR_waitid
17 /* The waitid() POSIX interface takes 4 arguments, but the kernel function
18  * actually takes 5.  The fifth is a pointer to struct rusage.  Make sure
19  * we pass NULL rather than letting whatever was in the register bleed up.
20  */
21 #define __NR_waitid5 __NR_waitid
22 static _syscall5(int, waitid5, idtype_t, idtype, id_t, id, siginfo_t*, infop,
23                  int, options, struct rusage*, ru)
24 # endif
25
26 int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
27 {
28 # ifdef __NR_waitid
29         return waitid5(idtype, id, infop, options, NULL);
30 # else
31         switch (idtype) {
32                 case P_PID:
33                         if (id <= 0)
34                                 goto invalid;
35                         break;
36                 case P_PGID:
37                         if (id < 0 || id == 1)
38                                 goto invalid;
39                         id = -id;
40                         break;
41                 case P_ALL:
42                         id = -1;
43                         break;
44                 default:
45                 invalid:
46                         __set_errno(EINVAL);
47                         return -1;
48         }
49
50         memset(infop, 0, sizeof *infop);
51         infop->si_pid = waitpid(id, &infop->si_status, options
52 #  ifdef WEXITED
53                                            &~ WEXITED
54 #  endif
55                                           );
56         if (infop->si_pid < 0)
57                 return infop->si_pid;
58         return 0;
59 # endif
60 }
61
62 #endif