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