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