1 /* @(#)waitid.c 1.3 19/04/28 Copyright 2015-2018 J. Schilling */
2 /*
3 * Emulate the waitid() syscall in case it is missing or disfunctional
4 *
5 * Copyright (c) 2015-2018 J. Schilling
6 */
7 /*
8 * The contents of this file are subject to the terms of the
9 * Common Development and Distribution License, Version 1.0 only
10 * (the "License"). You may not use this file except in compliance
11 * with the License.
12 *
13 * See the file CDDL.Schily.txt in this distribution for details.
14 * A copy of the CDDL is also available via the Internet at
15 * http://www.opensource.org/licenses/cddl1.txt
16 *
17 * When distributing Covered Code, include this CDDL HEADER in each
18 * file and include the License file CDDL.Schily.txt from this distribution.
19 */
20
21 #include <schily/wait.h>
22 #include <schily/schily.h>
23
24 #ifndef HAVE_WAITID
25 EXPORT int
waitid(idtype,id,infop,opts)26 waitid(idtype, id, infop, opts)
27 idtype_t idtype;
28 id_t id;
29 siginfo_t *infop; /* Must be != NULL */
30 int opts;
31 {
32 int exstat;
33 pid_t pid;
34 #ifdef __needed__
35 struct tms tms;
36 #endif
37
38 opts &= ~(WEXITED|WTRAPPED); /* waitpid() doesn't understand them */
39 #if WSTOPPED != WUNTRACED
40 if (opts & WSTOPPED) {
41 opts &= ~WSTOPPED;
42 opts |= WUNTRACED;
43 }
44 #endif
45
46 if (idtype == P_PID)
47 pid = id;
48 else if (idtype == P_PGID)
49 pid = -id;
50 else if (idtype == P_ALL)
51 pid = -1;
52 else
53 pid = 0;
54
55 #ifdef __needed__
56 /*
57 * We cannot clear infop->si_utime and infop->si_stime as they are
58 * missing on HP-UX-10.x.
59 */
60 infop->si_utime = 0;
61 infop->si_stime = 0;
62 if (WNOWAIT == 0 || (opts & WNOWAIT) == 0) {
63 times(&tms);
64 }
65 #endif
66 pid = waitpid(pid, &exstat, opts);
67 infop->si_pid = pid;
68 infop->si_code = 0;
69 infop->si_status = 0;
70
71 if (pid == (pid_t)-1)
72 return (-1);
73
74 #ifdef __needed__
75 if (WNOWAIT == 0 || (opts & WNOWAIT) == 0) {
76 infop->si_utime = tms.tms_cutime;
77 infop->si_stime = tms.tms_cstime;
78 times(&tms);
79 infop->si_utime = tms.tms_cutime - infop->si_utime;
80 infop->si_stime = tms.tms_cstime - infop->si_stime;
81 }
82 #endif
83
84 if (WIFEXITED(exstat)) {
85 infop->si_code = CLD_EXITED;
86 infop->si_status = WEXITSTATUS(exstat);
87 } else if (WIFSIGNALED(exstat)) {
88 if (WCOREDUMP(exstat))
89 infop->si_code = CLD_DUMPED;
90 else
91 infop->si_code = CLD_KILLED;
92 infop->si_status = WTERMSIG(exstat);
93 } else if (WIFSTOPPED(exstat)) {
94 #ifdef SIGTRAP
95 if (WSTOPSIG(exstat) == SIGTRAP)
96 infop->si_code = CLD_TRAPPED;
97 else
98 #endif
99 infop->si_code = CLD_STOPPED;
100 infop->si_status = WSTOPSIG(exstat);
101 } else if (WIFCONTINUED(exstat)) {
102 infop->si_code = CLD_CONTINUED;
103 #ifdef SIGCONT
104 infop->si_status = SIGCONT;
105 #else
106 infop->si_status = 0;
107 #endif
108 }
109
110 return (0);
111 }
112 #endif
113