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