1 /**
2  * D header file for spawn.h.
3  *
4  * Copyright: Copyright (C) 2018 by The D Language Foundation, All Rights Reserved
5  * Authors:   Petar Kirov
6  * License:   $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/druntime/src/core/sys/posix/spawn.d, _spawn.d)
8  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
9  */
10 module core.sys.posix.spawn;
11 
12 /*
13 Based on the following system headers:
14 
15 Glibc: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD
16 
17 Bionic libc: https://android.googlesource.com/platform/bionic.git/+/master/libc/include/spawn.h
18 
19 Musl libc: https://git.musl-libc.org/cgit/musl/tree/include/spawn.h
20 
21 uClibc: https://git.uclibc.org/uClibc/tree/include/spawn.h
22 
23 Darwin XNU:
24 https://opensource.apple.com/source/xnu/xnu-4570.71.2/libsyscall/wrappers/spawn/spawn.h.auto.html
25 https://opensource.apple.com/source/xnu/xnu-4570.71.2/bsd/sys/spawn.h.auto.html
26 https://github.com/opensource-apple/xnu (GitHub mirror)
27 
28 FreeBSD: https://github.com/freebsd/freebsd/blob/master/include/spawn.h
29 
30 NetBSD: https://github.com/NetBSD/src/blob/trunk/sys/sys/spawn.h
31 
32 OpenBSD: https://github.com/openbsd/src/blob/master/include/spawn.h
33 
34 DragonFlyBSD: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h
35 
36 Solaris: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h
37 */
38 
39 version (OSX) // macOS and iOS only as this API is prohibited on WatchOS and TVOS
40     version = Darwin;
41 else version (iOS)
42     version = Darwin;
43 
44 version (Posix):
45 public import core.sys.posix.sys.types : mode_t, pid_t;
46 public import core.sys.posix.signal : sigset_t;
47 public import core.sys.posix.sched : sched_param;
48 
49 extern(C):
50 @nogc:
51 nothrow:
52 
53 int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int);
54 int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int);
55 int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t*, int, const char*, int, mode_t);
56 int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*);
57 int posix_spawn_file_actions_init(posix_spawn_file_actions_t*);
58 int posix_spawnattr_destroy(posix_spawnattr_t*);
59 int posix_spawnattr_getflags(const posix_spawnattr_t*, short*);
60 int posix_spawnattr_getpgroup(const posix_spawnattr_t*, pid_t*);
61 
62 version (Darwin)
63 { } // Not supported
64 else
65 {
66     int posix_spawnattr_getschedparam(const posix_spawnattr_t*, sched_param*);
67     int posix_spawnattr_getschedpolicy(const posix_spawnattr_t*, int*);
68     int posix_spawnattr_setschedparam(posix_spawnattr_t*, const sched_param*);
69     int posix_spawnattr_setschedpolicy(posix_spawnattr_t*, int);
70 }
71 
72 int posix_spawnattr_getsigdefault(const posix_spawnattr_t*, sigset_t*);
73 int posix_spawnattr_getsigmask(const posix_spawnattr_t*, sigset_t*);
74 int posix_spawnattr_init(posix_spawnattr_t*);
75 int posix_spawnattr_setflags(posix_spawnattr_t*, short);
76 int posix_spawnattr_setpgroup(posix_spawnattr_t*, pid_t);
77 int posix_spawnattr_setsigdefault(posix_spawnattr_t*, const sigset_t*);
78 int posix_spawnattr_setsigmask(posix_spawnattr_t*, const sigset_t*);
79 int posix_spawn(pid_t*pid, const char* path,
80                 const posix_spawn_file_actions_t* file_actions,
81                 const posix_spawnattr_t* attrp,
82                 const char** argv, const char** envp);
83 int posix_spawnp(pid_t* pid, const char* file,
84                  const posix_spawn_file_actions_t* file_actions,
85                  const posix_spawnattr_t* attrp,
86                  const char** argv, const char** envp);
87 
88 version (linux)
89 {
90     version (CRuntime_Glibc)
91     {
92         // Source: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD
93         enum
94         {
95             POSIX_SPAWN_RESETIDS = 0x01,
96             POSIX_SPAWN_SETPGROUP = 0x02,
97             POSIX_SPAWN_SETSIGDEF = 0x04,
98             POSIX_SPAWN_SETSIGMASK = 0x08,
99             POSIX_SPAWN_SETSCHEDPARAM = 0x10,
100             POSIX_SPAWN_SETSCHEDULER = 0x20
101         }
102         import core.sys.posix.config : _GNU_SOURCE;
103         static if (_GNU_SOURCE)
104         {
105             enum
106             {
107                 POSIX_SPAWN_USEVFORK = 0x40,
108                 POSIX_SPAWN_SETSID = 0x80
109             }
110         }
111         struct posix_spawnattr_t
112         {
113             short __flags;
114             pid_t __pgrp;
115             sigset_t __sd;
116             sigset_t __ss;
117             sched_param __sp;
118             int __policy;
119             int[16] __pad;
120         }
121         struct __spawn_action;
122         struct posix_spawn_file_actions_t
123         {
124             int __allocated;
125             int __used;
126             __spawn_action* __actions;
127             int[16] __pad;
128         }
129     }
130     else version (CRuntime_Bionic)
131     {
132         // Source: https://android.googlesource.com/platform/bionic.git/+/master/libc/include/spawn.h
133         enum
134         {
135             POSIX_SPAWN_RESETIDS = 1,
136             POSIX_SPAWN_SETPGROUP = 2,
137             POSIX_SPAWN_SETSIGDEF = 4,
138             POSIX_SPAWN_SETSIGMASK = 8,
139             POSIX_SPAWN_SETSCHEDPARAM = 16,
140             POSIX_SPAWN_SETSCHEDULER = 32
141         }
142         import core.sys.posix.config : _GNU_SOURCE;
143         static if (_GNU_SOURCE)
144         {
145             enum
146             {
147                 POSIX_SPAWN_USEVFORK = 64,
148                 POSIX_SPAWN_SETSID = 128
149             }
150         }
151         alias posix_spawnattr_t = __posix_spawnattr*;
152         alias posix_spawn_file_actions_t = __posix_spawn_file_actions*;
153         struct __posix_spawnattr;
154         struct __posix_spawn_file_actions;
155     }
156     else version (CRuntime_Musl)
157     {
158         // Source: https://git.musl-libc.org/cgit/musl/tree/include/spawn.h
159         enum
160         {
161             POSIX_SPAWN_RESETIDS = 1,
162             POSIX_SPAWN_SETPGROUP = 2,
163             POSIX_SPAWN_SETSIGDEF = 4,
164             POSIX_SPAWN_SETSIGMASK = 8,
165             POSIX_SPAWN_SETSCHEDPARAM = 16,
166             POSIX_SPAWN_SETSCHEDULER = 32,
167             POSIX_SPAWN_USEVFORK = 64,
168             POSIX_SPAWN_SETSID = 128
169         }
170         struct posix_spawnattr_t
171         {
172             int __flags;
173             pid_t __pgrp;
174             sigset_t __def, __mask;
175             int __prio, __pol;
176             void* __fn;
177             char[64 - (void*).sizeof] __pad = void;
178         }
179         struct posix_spawn_file_actions_t
180         {
181             int[2] __pad0;
182             void* __actions;
183             int[16] __pad;
184         }
185     }
186     else version (CRuntime_UClibc)
187     {
188         // Source: https://git.uclibc.org/uClibc/tree/include/spawn.h
189         enum
190         {
191             POSIX_SPAWN_RESETIDS = 0x01,
192             POSIX_SPAWN_SETPGROUP = 0x02,
193             POSIX_SPAWN_SETSIGDEF = 0x04,
194             POSIX_SPAWN_SETSIGMASK = 0x08,
195             POSIX_SPAWN_SETSCHEDPARAM = 0x10,
196             POSIX_SPAWN_SETSCHEDULER = 0x20
197         }
198         import core.sys.posix.config : _GNU_SOURCE;
199         static if (_GNU_SOURCE)
200         {
201             enum
202             {
203                 POSIX_SPAWN_USEVFORK = 0x40,
204             }
205         }
206         struct posix_spawnattr_t
207         {
208             short __flags;
209             pid_t __pgrp;
210             sigset_t __sd;
211             sigset_t __ss;
212             sched_param __sp;
213             int __policy;
214             int[16] __pad;
215         }
216         struct __spawn_action;
217         struct posix_spawn_file_actions_t
218         {
219             int __allocated;
220             int __used;
221             __spawn_action* __actions;
222             int[16] __pad;
223         }
224     }
225     else
226         static assert(0, "Unsupported Linux libc");
227 }
228 else version (Darwin)
229 {
230     // Sources:
231     // https://opensource.apple.com/source/xnu/xnu-4570.71.2/libsyscall/wrappers/spawn/spawn.h.auto.html
232     // https://opensource.apple.com/source/xnu/xnu-4570.71.2/bsd/sys/spawn.h.auto.html
233     enum
234     {
235         POSIX_SPAWN_RESETIDS = 0x01,
236         POSIX_SPAWN_SETPGROUP = 0x02,
237         POSIX_SPAWN_SETSIGDEF = 0x04,
238         POSIX_SPAWN_SETSIGMASK = 0x08,
239         // POSIX_SPAWN_SETSCHEDPARAM = 0x10,  // not supported
240         // POSIX_SPAWN_SETSCHEDULER = 0x20,   // ditto
241         POSIX_SPAWN_SETEXEC = 0x40,
242         POSIX_SPAWN_START_SUSPENDED = 0x80,
243         POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000
244     }
245     alias posix_spawnattr_t = void*;
246     alias posix_spawn_file_actions_t = void*;
247 }
248 else version (FreeBSD)
249 {
250     // Source: https://github.com/freebsd/freebsd/blob/master/include/spawn.h
251     enum
252     {
253         POSIX_SPAWN_RESETIDS = 0x01,
254         POSIX_SPAWN_SETPGROUP = 0x02,
255         POSIX_SPAWN_SETSCHEDPARAM = 0x04,
256         POSIX_SPAWN_SETSCHEDULER = 0x08,
257         POSIX_SPAWN_SETSIGDEF = 0x10,
258         POSIX_SPAWN_SETSIGMASK = 0x20
259     }
260     alias posix_spawnattr_t =  void*;
261     alias posix_spawn_file_actions_t =  void*;
262 }
263 else version (NetBSD)
264 {
265     // Source: https://github.com/NetBSD/src/blob/trunk/sys/sys/spawn.h
266     enum
267     {
268         POSIX_SPAWN_RESETIDS = 0x01,
269         POSIX_SPAWN_SETPGROUP = 0x02,
270         POSIX_SPAWN_SETSCHEDPARAM = 0x04,
271         POSIX_SPAWN_SETSCHEDULER = 0x08,
272         POSIX_SPAWN_SETSIGDEF = 0x10,
273         POSIX_SPAWN_SETSIGMASK = 0x20,
274         POSIX_SPAWN_RETURNERROR = 0x40 // NetBSD specific
275     }
276     struct posix_spawnattr
277     {
278         short sa_flags;
279         pid_t sa_pgroup;
280         sched_param sa_schedparam;
281         int sa_schedpolicy;
282         sigset_t sa_sigdefault;
283         sigset_t sa_sigmask;
284     }
285     struct posix_spawn_file_actions_entry_t;
286     struct posix_spawn_file_actions
287     {
288         uint size;
289         uint len;
290         posix_spawn_file_actions_entry_t* fae;
291     }
292     alias posix_spawnattr_t = posix_spawnattr;
293     alias posix_spawn_file_actions_t = posix_spawn_file_actions;
294 }
295 else version (OpenBSD)
296 {
297     // Source: https://github.com/openbsd/src/blob/master/include/spawn.h
298     enum
299     {
300         POSIX_SPAWN_RESETIDS = 0x01,
301         POSIX_SPAWN_SETPGROUP = 0x02,
302         POSIX_SPAWN_SETSCHEDPARAM = 0x04,
303         POSIX_SPAWN_SETSCHEDULER = 0x08,
304         POSIX_SPAWN_SETSIGDEF = 0x10,
305         POSIX_SPAWN_SETSIGMASK = 0x20
306     }
307     alias posix_spawnattr_t = __posix_spawnattr*;
308     alias posix_spawn_file_actions_t = __posix_spawn_file_actions*;
309     struct __posix_spawnattr;
310     struct __posix_spawn_file_actions;
311 }
312 else version (DragonFlyBSD)
313 {
314     // Source: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h
315     enum
316     {
317         POSIX_SPAWN_RESETIDS = 0x01,
318         POSIX_SPAWN_SETPGROUP = 0x02,
319         POSIX_SPAWN_SETSCHEDPARAM = 0x04,
320         POSIX_SPAWN_SETSCHEDULER = 0x08,
321         POSIX_SPAWN_SETSIGDEF = 0x10,
322         POSIX_SPAWN_SETSIGMASK = 0x20
323     }
324     alias posix_spawnattr_t = __posix_spawnattr*;
325     alias posix_spawn_file_actions_t = __posix_spawn_file_actions*;
326     struct __posix_spawnattr;
327     struct __posix_spawn_file_actions;
328 }
329 else version (Solaris)
330 {
331     // Source: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h
332     enum
333     {
334         POSIX_SPAWN_RESETIDS = 0x01,
335         POSIX_SPAWN_SETPGROUP = 0x02,
336         POSIX_SPAWN_SETSIGDEF = 0x04,
337         POSIX_SPAWN_SETSIGMASK = 0x08,
338         POSIX_SPAWN_SETSCHEDPARAM = 0x10,
339         POSIX_SPAWN_SETSCHEDULER = 0x20,
340     }
341     version (none)
342     {
343         // Non-portable Solaris extensions.
344         enum
345         {
346             POSIX_SPAWN_SETSIGIGN_NP = 0x0800,
347             POSIX_SPAWN_NOSIGCHLD_NP = 0x1000,
348             POSIX_SPAWN_WAITPID_NP = 0x2000,
349             POSIX_SPAWN_NOEXECERR_NP = 0x4000,
350         }
351     }
352     struct posix_spawnattr_t
353     {
354         void* __spawn_attrp;
355     }
356     struct posix_spawn_file_actions_t
357     {
358         void* __file_attrp;
359     }
360     version (none)
361     {
362         // Non-portable Solaris extensions.
363         alias boolean_t = int;
364         int posix_spawn_file_actions_addclosefrom_np(posix_spawn_file_actions_t* file_actions,
365                                                      int lowfiledes);
366         int posix_spawn_pipe_np(pid_t* pidp, int* fdp, const char* cmd, boolean_t write,
367                                 posix_spawn_file_actions_t* fact,
368                                 posix_spawnattr_t* attr);
369         int posix_spawnattr_getsigignore_np(const posix_spawnattr_t* attr, sigset_t* sigignore);
370         int posix_spawnattr_setsigignore_np(posix_spawnattr_t* attr, const sigset_t* sigignore);
371     }
372 }
373 else
374     static assert(0, "Unsupported OS");