1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2009.
5  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6  * Authors:   Sean Kelly, Alex Rønne Petersen
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 
10 /*          Copyright Sean Kelly 2005 - 2009.
11  * Distributed under the Boost Software License, Version 1.0.
12  *    (See accompanying file LICENSE or copy at
13  *          http://www.boost.org/LICENSE_1_0.txt)
14  */
15 module core.sys.posix.sys.wait;
16 
17 import core.sys.posix.config;
18 public import core.sys.posix.sys.types; // for id_t, pid_t
19 public import core.sys.posix.signal;    // for siginfo_t (XSI)
20 //public import core.sys.posix.resource; // for rusage (XSI)
21 
22 version (OSX)
23     version = Darwin;
24 else version (iOS)
25     version = Darwin;
26 else version (TVOS)
27     version = Darwin;
28 else version (WatchOS)
29     version = Darwin;
30 
31 version (Posix):
32 extern (C) nothrow @nogc:
33 
34 //
35 // Required
36 //
37 /*
38 WNOHANG
39 WUNTRACED
40 */
41 
42 version (linux)
43 {
44     enum WNOHANG        = 1;
45     enum WUNTRACED      = 2;
46 
47     private
48     {
49         enum __W_CONTINUED = 0xFFFF;
50     }
51 }
52 else version (Darwin)
53 {
54     enum WNOHANG        = 1;
55     enum WUNTRACED      = 2;
56 
57     private
58     {
59         enum _WSTOPPED = 0x7F; // octal 0177
60     }
61 }
62 else version (FreeBSD)
63 {
64     enum WNOHANG        = 1;
65     enum WUNTRACED      = 2;
66 
67     private
68     {
69         enum _WSTOPPED = 0x7F; // octal 0177
70         enum __W_CONTINUED = 0x13;
71     }
72 }
73 else version (NetBSD)
74 {
75     enum WNOHANG        = 1;
76     enum WUNTRACED      = 2;
77 
78     private
79     {
80         enum _WSTOPPED = 0x7F; // octal 0177
81     }
82 }
83 else version (OpenBSD)
84 {
85     enum WNOHANG        = 1;
86     enum WUNTRACED      = 2;
87 
88     private
89     {
90         enum _WSTOPPED   = 0x7F;   // octal 0177
91         enum _WCONTINUED = 0xFFFF; // octal 0177777
92     }
93 }
94 else version (DragonFlyBSD)
95 {
96     enum WNOHANG        = 1;
97     enum WUNTRACED      = 2;
98 
99     private
100     {
101         enum _WSTOPPED = 0x7F; // octal 0177
102     }
103 }
104 else version (Solaris)
105 {
106     enum WNOHANG        = 64;
107     enum WUNTRACED      = 4;
108 }
109 else
110 {
111     static assert(false, "Unsupported platform");
112 }
113 
114 /*
115 WEXITSTATUS
116 WIFCONTINUED
117 WIFEXITED
118 WIFSIGNALED
119 WIFSTOPPED
120 WSTOPSIG
121 WTERMSIG
122 */
123 
124 version (CRuntime_Glibc)
125 {
126     @safe pure:
127 
128     private
129     {
130         extern (D) int __WTERMSIG( int status ) { return status & 0x7F; }
131     }
132 
133     //
134     // NOTE: These macros assume __USE_MISC is not defined in the relevant
135     //       C headers as the parameter definition there is different and
136     //       much more complicated.
137     //
138     extern (D) int  WEXITSTATUS( int status )  { return ( status & 0xFF00 ) >> 8;   }
139     extern (D) int  WIFCONTINUED( int status ) { return status == __W_CONTINUED;    }
140     extern (D) bool WIFEXITED( int status )    { return __WTERMSIG( status ) == 0;  }
141     extern (D) bool WIFSIGNALED( int status )
142     {
143         return ( cast(byte) ( ( status & 0x7F ) + 1 ) >> 1 ) > 0;
144     }
145     extern (D) bool WIFSTOPPED( int status )   { return ( status & 0xFF ) == 0x7F;  }
146     extern (D) int  WSTOPSIG( int status )     { return WEXITSTATUS( status );      }
147     extern (D) int  WTERMSIG( int status )     { return status & 0x7F;              }
148 }
149 else version (Darwin)
150 {
151     @safe pure:
152 
153     extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }
154     extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }
155     extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }
156     extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }
157     extern (D) bool WIFSIGNALED( int status )
158     {
159         return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;
160     }
161     extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }
162     extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }
163     extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }
164 }
165 else version (FreeBSD)
166 {
167     @safe pure:
168 
169     extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }
170     extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }
171     extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }
172     extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }
173     extern (D) bool WIFSIGNALED( int status )
174     {
175         return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;
176     }
177     extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }
178     extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }
179     extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }
180 }
181 else version (NetBSD)
182 {
183     @safe pure:
184 
185     extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }
186     extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }
187     extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }
188     extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }
189     extern (D) bool WIFSIGNALED( int status )
190     {
191         return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;
192     }
193     extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }
194     extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }
195     extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }
196 }
197 else version (OpenBSD)
198 {
199     @safe pure:
200 
201     extern (D) int _WSTATUS(int status)         { return (status & 0x7F);                     }
202     extern (D) int  WEXITSTATUS(int status)   { return (status >> 8) & 0xFF;                  }
203     extern (D) int  WIFCONTINUED(int status)  { return (status & _WCONTINUED) == _WCONTINUED; }
204     extern (D) bool WIFEXITED(int status)     { return _WSTATUS(status) == 0;                 }
205     extern (D) bool WIFSIGNALED(int status)
206     {
207         return _WSTATUS(status) != _WSTOPPED && _WSTATUS(status) != 0;
208     }
209     extern (D) bool WIFSTOPPED(int status)   { return (status & 0xFF) == _WSTOPPED; }
210     extern (D) int  WSTOPSIG(int status)     { return (status >> 8) & 0xFF;         }
211     extern (D) int  WTERMSIG(int status)     { return _WSTATUS(status);             }
212 }
213 else version (DragonFlyBSD)
214 {
215     @safe pure:
216 
217     extern (D) int _WSTATUS(int status)         { return (status & 0x7F);           }
218     extern (D) int  WEXITSTATUS( int status )   { return (status >> 8);             }
219     extern (D) int  WIFCONTINUED( int status )  { return status == 0x13;            }
220     extern (D) bool WIFEXITED( int status )     { return _WSTATUS(status) == 0;     }
221     extern (D) bool WIFSIGNALED( int status )
222     {
223         return _WSTATUS( status ) != _WSTOPPED && _WSTATUS( status ) != 0;
224     }
225     extern (D) bool WIFSTOPPED( int status )   { return _WSTATUS( status ) == _WSTOPPED; }
226     extern (D) int  WSTOPSIG( int status )     { return status >> 8;                     }
227     extern (D) int  WTERMSIG( int status )     { return _WSTATUS( status );              }
228 }
229 else version (Solaris)
230 {
231     @safe pure:
232 
233     extern (D) int WEXITSTATUS(int status) { return (status >> 8) & 0xff; }
234     extern (D) int WIFCONTINUED(int status) { return (status & 0xffff) == 0xffff; }
235     extern (D) bool WIFEXITED(int status) { return (status & 0xff) == 0;     }
236     extern (D) bool WIFSIGNALED(int status) { return (status & 0xff) > 0 && (status & 0xff00) == 0; }
237     extern (D) bool WIFSTOPPED(int status) { return (status & 0xff) == 0x7f && (status & 0xff00) != 0; }
238     extern (D) int WSTOPSIG(int status) { return (status >> 8) & 0x7f; }
239     extern (D) int WTERMSIG(int status) { return (status & 0x7f); }
240 }
241 else version (CRuntime_Bionic)
242 {
243     @safe pure:
244     extern (D) int  WEXITSTATUS( int status ) { return ( status & 0xFF00 ) >> 8; }
245     extern (D) bool WIFEXITED( int status ) { return WTERMSIG(status) == 0; }
246     extern (D) bool WIFSIGNALED( int status ) { return WTERMSIG(status + 1) >= 2; }
247     extern (D) bool WIFSTOPPED( int status ) { return WTERMSIG(status) == 0x7F; }
248     extern (D) int  WSTOPSIG( int status ) { return WEXITSTATUS(status); }
249     extern (D) int  WTERMSIG( int status ) { return status & 0x7F; }
250 }
251 else version (CRuntime_Musl)
252 {
253     @safe pure:
254     extern (D) int  WEXITSTATUS( int status ) { return ( status & 0xFF00 ) >> 8; }
255     extern (D) int  WIFCONTINUED( int status ) { return status == 0xffff; }
256     extern (D) bool WIFEXITED( int status ) { return WTERMSIG( status ) == 0; }
257     extern (D) bool WIFSIGNALED( int status ) { return (status&0xffff)-1U < 0xffU; }
258     extern (D) bool WIFSTOPPED( int status ) { return cast(short)(((status&0xffff)*0x10001)>>8) > 0x7f00; }
259     extern (D) int  WTERMSIG( int status ) { return status & 0x7F; }
260     alias WEXITSTATUS WSTOPSIG;
261 }
262 else version (CRuntime_UClibc)
263 {
264     @safe pure:
265 
266     private
267     {
268         extern (D) int __WTERMSIG( int status ) { return status & 0x7F; }
269     }
270 
271     //
272     // NOTE: These macros assume __USE_BSD is not defined in the relevant
273     //       C headers as the parameter definition there is different and
274     //       much more complicated.
275     //
276     extern (D) int  WEXITSTATUS( int status )  { return ( status & 0xFF00 ) >> 8;   }
277     extern (D) int  WIFCONTINUED( int status ) { return status == __W_CONTINUED;    }
278     extern (D) bool WIFEXITED( int status )    { return __WTERMSIG( status ) == 0;  }
279     extern (D) bool WIFSIGNALED( int status )
280     {
281         return ( cast(ulong) ( ( status & 0xffff ) - 1U ) >> 1 ) < 0xffU;
282     }
283     version (MIPS32)
284     {
285         extern (D) bool WIFSTOPPED( int status )   { return ( status & 0xFF ) == 0x7F;  }
286     }
287     else
288     {
289         extern (D) bool WIFSTOPPED( int status )   { return ( status & 0xFF ) == 0x7F && ( status & 0xFF00 );  }
290     }
291     extern (D) int  WSTOPSIG( int status )     { return WEXITSTATUS( status );      }
292     extern (D) int  WTERMSIG( int status )     { return status & 0x7F;              }
293 }
294 else
295 {
296     static assert(false, "Unsupported platform");
297 }
298 
299 /*
300 pid_t wait(int*);
301 pid_t waitpid(pid_t, int*, int);
302 */
303 
304 pid_t wait(int*);
305 pid_t waitpid(pid_t, int*, int);
306 
307 //
308 // XOpen (XSI)
309 //
310 /*
311 WEXITED
312 WSTOPPED
313 WCONTINUED
314 WNOWAIT
315 
316 enum idtype_t
317 {
318     P_ALL,
319     P_PID,
320     P_PGID
321 }
322 */
323 
324 version (linux)
325 {
326     enum WEXITED    = 4;
327     enum WSTOPPED   = 2;
328     enum WCONTINUED = 8;
329     enum WNOWAIT    = 0x01000000;
330 
331     enum idtype_t
332     {
333         P_ALL,
334         P_PID,
335         P_PGID
336     }
337 }
338 else version (Darwin)
339 {
340     enum WEXITED    = 0x00000004;
341     enum WSTOPPED   = 0x00000008;
342     enum WCONTINUED = 0x00000010;
343     enum WNOWAIT    = 0x00000020;
344 
345     enum idtype_t
346     {
347         P_ALL,
348         P_PID,
349         P_PGID
350     }
351 }
352 else version (FreeBSD)
353 {
354     enum WSTOPPED       = WUNTRACED;
355     enum WCONTINUED     = 4;
356     enum WNOWAIT        = 8;
357     enum WEXITED        = 16;
358     enum WTRAPPED       = 32;
359 
360     enum idtype_t
361     {
362         P_UID,
363         P_GID,
364         P_SID,
365         P_JAILID,
366         P_PID,
367         P_PPID,
368         P_PGID,
369         P_CID,
370         P_ALL,
371         P_LWPID,
372         P_TASKID,
373         P_PROJID,
374         P_POOLID,
375         P_CTID,
376         P_CPUID,
377         P_PSETID
378     }
379 }
380 else version (NetBSD)
381 {
382     enum WSTOPPED       = WUNTRACED;
383     //enum WCONTINUED     = 4;
384     enum WNOWAIT        = 0x00010000;
385 }
386 else version (OpenBSD)
387 {
388     enum WCONTINUED     = 8;
389     enum WSTOPPED       = WUNTRACED;
390     enum WNOWAIT        = 16;
391 
392     enum idtype_t
393     {
394         P_ALL,
395         P_PID,
396         P_PGID
397     }
398 }
399 else version (DragonFlyBSD)
400 {
401     enum WSTOPPED       = WUNTRACED;
402     enum WCONTINUED     = 4;
403     enum WNOWAIT        = 8;
404 }
405 else version (Solaris)
406 {
407     enum WEXITED = 1;
408     enum WTRAPPED = 2;
409     enum WSTOPPED = WUNTRACED;
410     enum WCONTINUED = 8;
411     enum WNOWAIT = 128;
412 
413     enum idtype_t
414     {
415         P_PID,          /* A process identifier.                */
416         P_PPID,         /* A parent process identifier.         */
417         P_PGID,         /* A process group (job control group)  */
418                         /* identifier.                          */
419         P_SID,          /* A session identifier.                */
420         P_CID,          /* A scheduling class identifier.       */
421         P_UID,          /* A user identifier.                   */
422         P_GID,          /* A group identifier.                  */
423         P_ALL,          /* All processes.                       */
424         P_LWPID,        /* An LWP identifier.                   */
425         P_TASKID,       /* A task identifier.                   */
426         P_PROJID,       /* A project identifier.                */
427         P_POOLID,       /* A pool identifier.                   */
428         P_ZONEID,       /* A zone identifier.                   */
429         P_CTID,         /* A (process) contract identifier.     */
430         P_CPUID,        /* CPU identifier.                      */
431         P_PSETID,       /* Processor set identifier             */
432     }
433 }
434 else
435 {
436     static assert(false, "Unsupported platform");
437 }
438 
439 /*
440 int waitid(idtype_t, id_t, siginfo_t*, int);
441 */
442 
443 version (CRuntime_Glibc)
444 {
445     int waitid(idtype_t, id_t, siginfo_t*, int);
446 }
447 else version (Darwin)
448 {
449     int waitid(idtype_t, id_t, siginfo_t*, int);
450 }
451 else version (FreeBSD)
452 {
453     int waitid(idtype_t, id_t, siginfo_t*, int);
454 }
455 else version (NetBSD)
456 {
457 }
458 else version (OpenBSD)
459 {
460     int waitid(idtype_t, id_t, siginfo_t*, int);
461 }
462 else version (DragonFlyBSD)
463 {
464 }
465 else version (Solaris)
466 {
467     int waitid(idtype_t, id_t, siginfo_t*, int);
468 }
469 else version (CRuntime_Bionic)
470 {
471     int waitid(idtype_t, id_t, siginfo_t*, int);
472 }
473 else version (CRuntime_Musl)
474 {
475     int waitid(idtype_t, id_t, siginfo_t*, int);
476 }
477 else version (CRuntime_UClibc)
478 {
479     int waitid(idtype_t, id_t, siginfo_t*, int);
480 }
481 else
482 {
483     static assert(false, "Unsupported platform");
484 }