1c4dd129bSPeter Avalos /*-
2c4dd129bSPeter Avalos * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
3c4dd129bSPeter Avalos * All rights reserved.
4c4dd129bSPeter Avalos *
5c4dd129bSPeter Avalos * Redistribution and use in source and binary forms, with or without
6c4dd129bSPeter Avalos * modification, are permitted provided that the following conditions
7c4dd129bSPeter Avalos * are met:
8c4dd129bSPeter Avalos * 1. Redistributions of source code must retain the above copyright
9c4dd129bSPeter Avalos * notice, this list of conditions and the following disclaimer.
10c4dd129bSPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
11c4dd129bSPeter Avalos * notice, this list of conditions and the following disclaimer in the
12c4dd129bSPeter Avalos * documentation and/or other materials provided with the distribution.
13c4dd129bSPeter Avalos *
14c4dd129bSPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15c4dd129bSPeter Avalos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16c4dd129bSPeter Avalos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17c4dd129bSPeter Avalos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18c4dd129bSPeter Avalos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19c4dd129bSPeter Avalos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20c4dd129bSPeter Avalos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21c4dd129bSPeter Avalos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22c4dd129bSPeter Avalos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23c4dd129bSPeter Avalos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24c4dd129bSPeter Avalos * SUCH DAMAGE.
25c4dd129bSPeter Avalos *
26c4dd129bSPeter Avalos * $FreeBSD: src/lib/libc/gen/posix_spawn.c,v 1.6 2008/10/23 15:32:06 rdivacky Exp $
27c4dd129bSPeter Avalos */
28c4dd129bSPeter Avalos
29c4dd129bSPeter Avalos #include "namespace.h"
30c4dd129bSPeter Avalos #include <sys/queue.h>
31c4dd129bSPeter Avalos
32c4dd129bSPeter Avalos #include <errno.h>
33c4dd129bSPeter Avalos #include <fcntl.h>
34c4dd129bSPeter Avalos #include <sched.h>
35c4dd129bSPeter Avalos #include <spawn.h>
36c4dd129bSPeter Avalos #include <signal.h>
37c4dd129bSPeter Avalos #include <stdlib.h>
38c4dd129bSPeter Avalos #include <string.h>
39c4dd129bSPeter Avalos #include <unistd.h>
40c4dd129bSPeter Avalos #include "un-namespace.h"
41c4dd129bSPeter Avalos #include "libc_private.h"
42c4dd129bSPeter Avalos
43c4dd129bSPeter Avalos extern char **environ;
44c4dd129bSPeter Avalos
45c4dd129bSPeter Avalos struct __posix_spawnattr {
46c4dd129bSPeter Avalos short sa_flags;
47c4dd129bSPeter Avalos pid_t sa_pgroup;
48c4dd129bSPeter Avalos struct sched_param sa_schedparam;
49c4dd129bSPeter Avalos int sa_schedpolicy;
50c4dd129bSPeter Avalos sigset_t sa_sigdefault;
51c4dd129bSPeter Avalos sigset_t sa_sigmask;
52c4dd129bSPeter Avalos };
53c4dd129bSPeter Avalos
54c4dd129bSPeter Avalos struct __posix_spawn_file_actions {
55c4dd129bSPeter Avalos STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list;
56c4dd129bSPeter Avalos };
57c4dd129bSPeter Avalos
58c4dd129bSPeter Avalos typedef struct __posix_spawn_file_actions_entry {
59c4dd129bSPeter Avalos STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list;
60c4dd129bSPeter Avalos enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action;
61c4dd129bSPeter Avalos
62c4dd129bSPeter Avalos int fae_fildes;
63c4dd129bSPeter Avalos union {
64c4dd129bSPeter Avalos struct {
65c4dd129bSPeter Avalos char *path;
66c4dd129bSPeter Avalos #define fae_path fae_data.open.path
67c4dd129bSPeter Avalos int oflag;
68c4dd129bSPeter Avalos #define fae_oflag fae_data.open.oflag
69c4dd129bSPeter Avalos mode_t mode;
70c4dd129bSPeter Avalos #define fae_mode fae_data.open.mode
71c4dd129bSPeter Avalos } open;
72c4dd129bSPeter Avalos struct {
73c4dd129bSPeter Avalos int newfildes;
74c4dd129bSPeter Avalos #define fae_newfildes fae_data.dup2.newfildes
75c4dd129bSPeter Avalos } dup2;
76c4dd129bSPeter Avalos } fae_data;
77c4dd129bSPeter Avalos } posix_spawn_file_actions_entry_t;
78c4dd129bSPeter Avalos
79c4dd129bSPeter Avalos /*
80c4dd129bSPeter Avalos * Spawn routines
81c4dd129bSPeter Avalos */
82c4dd129bSPeter Avalos
83c4dd129bSPeter Avalos static int
process_spawnattr(const posix_spawnattr_t sa)84c4dd129bSPeter Avalos process_spawnattr(const posix_spawnattr_t sa)
85c4dd129bSPeter Avalos {
86c4dd129bSPeter Avalos struct sigaction sigact = { .sa_flags = 0, .sa_handler = SIG_DFL };
87c4dd129bSPeter Avalos int i;
88c4dd129bSPeter Avalos
89c4dd129bSPeter Avalos /*
90c4dd129bSPeter Avalos * POSIX doesn't really describe in which order everything
91c4dd129bSPeter Avalos * should be set. We'll just set them in the order in which they
92c4dd129bSPeter Avalos * are mentioned.
93c4dd129bSPeter Avalos */
94c4dd129bSPeter Avalos
95c4dd129bSPeter Avalos /* Set process group */
96c4dd129bSPeter Avalos if (sa->sa_flags & POSIX_SPAWN_SETPGROUP) {
97c4dd129bSPeter Avalos if (setpgid(0, sa->sa_pgroup) != 0)
98c4dd129bSPeter Avalos return (errno);
99c4dd129bSPeter Avalos }
100c4dd129bSPeter Avalos
101c4dd129bSPeter Avalos /* Set scheduler policy */
102c4dd129bSPeter Avalos if (sa->sa_flags & POSIX_SPAWN_SETSCHEDULER) {
103c4dd129bSPeter Avalos if (sched_setscheduler(0, sa->sa_schedpolicy,
104c4dd129bSPeter Avalos &sa->sa_schedparam) != 0)
105c4dd129bSPeter Avalos return (errno);
106c4dd129bSPeter Avalos } else if (sa->sa_flags & POSIX_SPAWN_SETSCHEDPARAM) {
107c4dd129bSPeter Avalos if (sched_setparam(0, &sa->sa_schedparam) != 0)
108c4dd129bSPeter Avalos return (errno);
109c4dd129bSPeter Avalos }
110c4dd129bSPeter Avalos
111c4dd129bSPeter Avalos /* Reset user ID's */
112c4dd129bSPeter Avalos if (sa->sa_flags & POSIX_SPAWN_RESETIDS) {
113c4dd129bSPeter Avalos if (setegid(getgid()) != 0)
114c4dd129bSPeter Avalos return (errno);
115c4dd129bSPeter Avalos if (seteuid(getuid()) != 0)
116c4dd129bSPeter Avalos return (errno);
117c4dd129bSPeter Avalos }
118c4dd129bSPeter Avalos
119c4dd129bSPeter Avalos /* Set signal masks/defaults */
120c4dd129bSPeter Avalos if (sa->sa_flags & POSIX_SPAWN_SETSIGMASK) {
121c4dd129bSPeter Avalos _sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL);
122c4dd129bSPeter Avalos }
123c4dd129bSPeter Avalos
124c4dd129bSPeter Avalos if (sa->sa_flags & POSIX_SPAWN_SETSIGDEF) {
125c4dd129bSPeter Avalos for (i = 1; i <= _SIG_MAXSIG; i++) {
126c4dd129bSPeter Avalos if (sigismember(&sa->sa_sigdefault, i))
127c4dd129bSPeter Avalos if (_sigaction(i, &sigact, NULL) != 0)
128c4dd129bSPeter Avalos return (errno);
129c4dd129bSPeter Avalos }
130c4dd129bSPeter Avalos }
131c4dd129bSPeter Avalos
132c4dd129bSPeter Avalos return (0);
133c4dd129bSPeter Avalos }
134c4dd129bSPeter Avalos
135c4dd129bSPeter Avalos static int
process_file_actions_entry(posix_spawn_file_actions_entry_t * fae)136c4dd129bSPeter Avalos process_file_actions_entry(posix_spawn_file_actions_entry_t *fae)
137c4dd129bSPeter Avalos {
138c4dd129bSPeter Avalos int fd;
139c4dd129bSPeter Avalos
140c4dd129bSPeter Avalos switch (fae->fae_action) {
141c4dd129bSPeter Avalos case FAE_OPEN:
142c4dd129bSPeter Avalos /* Perform an open(), make it use the right fd */
143c4dd129bSPeter Avalos fd = _open(fae->fae_path, fae->fae_oflag, fae->fae_mode);
144c4dd129bSPeter Avalos if (fd < 0)
145c4dd129bSPeter Avalos return (errno);
146c4dd129bSPeter Avalos if (fd != fae->fae_fildes) {
147c4dd129bSPeter Avalos if (_dup2(fd, fae->fae_fildes) == -1)
148c4dd129bSPeter Avalos return (errno);
149c4dd129bSPeter Avalos if (_close(fd) != 0) {
150c4dd129bSPeter Avalos if (errno == EBADF)
151c4dd129bSPeter Avalos return (EBADF);
152c4dd129bSPeter Avalos }
153c4dd129bSPeter Avalos }
154c4dd129bSPeter Avalos if (_fcntl(fae->fae_fildes, F_SETFD, 0) == -1)
155c4dd129bSPeter Avalos return (errno);
156c4dd129bSPeter Avalos break;
157c4dd129bSPeter Avalos case FAE_DUP2:
158c4dd129bSPeter Avalos /* Perform a dup2() */
159c4dd129bSPeter Avalos if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1)
160c4dd129bSPeter Avalos return (errno);
161c4dd129bSPeter Avalos if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1)
162c4dd129bSPeter Avalos return (errno);
163c4dd129bSPeter Avalos break;
164c4dd129bSPeter Avalos case FAE_CLOSE:
165c4dd129bSPeter Avalos /* Perform a close() */
166c4dd129bSPeter Avalos if (_close(fae->fae_fildes) != 0) {
167c4dd129bSPeter Avalos if (errno == EBADF)
168c4dd129bSPeter Avalos return (EBADF);
169c4dd129bSPeter Avalos }
170c4dd129bSPeter Avalos break;
171c4dd129bSPeter Avalos }
172c4dd129bSPeter Avalos return (0);
173c4dd129bSPeter Avalos }
174c4dd129bSPeter Avalos
175c4dd129bSPeter Avalos static int
process_file_actions(const posix_spawn_file_actions_t fa)176c4dd129bSPeter Avalos process_file_actions(const posix_spawn_file_actions_t fa)
177c4dd129bSPeter Avalos {
178c4dd129bSPeter Avalos posix_spawn_file_actions_entry_t *fae;
179c4dd129bSPeter Avalos int error;
180c4dd129bSPeter Avalos
181c4dd129bSPeter Avalos /* Replay all file descriptor modifications */
182c4dd129bSPeter Avalos STAILQ_FOREACH(fae, &fa->fa_list, fae_list) {
183c4dd129bSPeter Avalos error = process_file_actions_entry(fae);
184c4dd129bSPeter Avalos if (error)
185c4dd129bSPeter Avalos return (error);
186c4dd129bSPeter Avalos }
187c4dd129bSPeter Avalos return (0);
188c4dd129bSPeter Avalos }
189c4dd129bSPeter Avalos
190c4dd129bSPeter Avalos static int
do_posix_spawn(pid_t * pid,const char * path,const posix_spawn_file_actions_t * fa,const posix_spawnattr_t * sa,char * const argv[],char * const envp[],int use_env_path)191c4dd129bSPeter Avalos do_posix_spawn(pid_t *pid, const char *path,
192c4dd129bSPeter Avalos const posix_spawn_file_actions_t *fa,
193c4dd129bSPeter Avalos const posix_spawnattr_t *sa, char * const argv[],
194c4dd129bSPeter Avalos char * const envp[], int use_env_path)
195c4dd129bSPeter Avalos {
196c4dd129bSPeter Avalos pid_t p;
197c4dd129bSPeter Avalos volatile int error = 0;
198c4dd129bSPeter Avalos
199c4dd129bSPeter Avalos p = vfork();
200c4dd129bSPeter Avalos switch (p) {
201c4dd129bSPeter Avalos case -1:
202c4dd129bSPeter Avalos return (errno);
203c4dd129bSPeter Avalos case 0:
204c4dd129bSPeter Avalos if (sa != NULL) {
205c4dd129bSPeter Avalos error = process_spawnattr(*sa);
206c4dd129bSPeter Avalos if (error)
207c4dd129bSPeter Avalos _exit(127);
208c4dd129bSPeter Avalos }
209c4dd129bSPeter Avalos if (fa != NULL) {
210c4dd129bSPeter Avalos error = process_file_actions(*fa);
211c4dd129bSPeter Avalos if (error)
212c4dd129bSPeter Avalos _exit(127);
213c4dd129bSPeter Avalos }
214c4dd129bSPeter Avalos if (use_env_path)
215c4dd129bSPeter Avalos _execvpe(path, argv, envp != NULL ? envp : environ);
216c4dd129bSPeter Avalos else
217c4dd129bSPeter Avalos _execve(path, argv, envp != NULL ? envp : environ);
218c4dd129bSPeter Avalos error = errno;
219c4dd129bSPeter Avalos _exit(127);
220c4dd129bSPeter Avalos default:
221c4dd129bSPeter Avalos if (pid != NULL)
222c4dd129bSPeter Avalos *pid = p;
223c4dd129bSPeter Avalos return (error);
224c4dd129bSPeter Avalos }
225c4dd129bSPeter Avalos }
226c4dd129bSPeter Avalos
227c4dd129bSPeter Avalos int
posix_spawn(pid_t * __restrict pid,const char * __restrict path,const posix_spawn_file_actions_t * fa,const posix_spawnattr_t * __restrict sa,char * const argv[__restrict_arr],char * const envp[__restrict_arr])228*d33005aaSSascha Wildner posix_spawn(pid_t * __restrict pid, const char * __restrict path,
229*d33005aaSSascha Wildner const posix_spawn_file_actions_t *fa,
230*d33005aaSSascha Wildner const posix_spawnattr_t * __restrict sa, char * const argv[__restrict_arr],
231*d33005aaSSascha Wildner char * const envp[__restrict_arr])
232c4dd129bSPeter Avalos {
233c4dd129bSPeter Avalos return do_posix_spawn(pid, path, fa, sa, argv, envp, 0);
234c4dd129bSPeter Avalos }
235c4dd129bSPeter Avalos
236c4dd129bSPeter Avalos int
posix_spawnp(pid_t * __restrict pid,const char * __restrict path,const posix_spawn_file_actions_t * fa,const posix_spawnattr_t * __restrict sa,char * const argv[__restrict_arr],char * const envp[__restrict_arr])237*d33005aaSSascha Wildner posix_spawnp(pid_t * __restrict pid, const char * __restrict path,
238*d33005aaSSascha Wildner const posix_spawn_file_actions_t *fa,
239*d33005aaSSascha Wildner const posix_spawnattr_t * __restrict sa, char * const argv[__restrict_arr],
240*d33005aaSSascha Wildner char * const envp[__restrict_arr])
241c4dd129bSPeter Avalos {
242c4dd129bSPeter Avalos return do_posix_spawn(pid, path, fa, sa, argv, envp, 1);
243c4dd129bSPeter Avalos }
244c4dd129bSPeter Avalos
245c4dd129bSPeter Avalos /*
246c4dd129bSPeter Avalos * File descriptor actions
247c4dd129bSPeter Avalos */
248c4dd129bSPeter Avalos
249c4dd129bSPeter Avalos int
posix_spawn_file_actions_init(posix_spawn_file_actions_t * ret)250c4dd129bSPeter Avalos posix_spawn_file_actions_init(posix_spawn_file_actions_t *ret)
251c4dd129bSPeter Avalos {
252c4dd129bSPeter Avalos posix_spawn_file_actions_t fa;
253c4dd129bSPeter Avalos
254c4dd129bSPeter Avalos fa = malloc(sizeof(struct __posix_spawn_file_actions));
255c4dd129bSPeter Avalos if (fa == NULL)
256c4dd129bSPeter Avalos return (-1);
257c4dd129bSPeter Avalos
258c4dd129bSPeter Avalos STAILQ_INIT(&fa->fa_list);
259c4dd129bSPeter Avalos *ret = fa;
260c4dd129bSPeter Avalos return (0);
261c4dd129bSPeter Avalos }
262c4dd129bSPeter Avalos
263c4dd129bSPeter Avalos int
posix_spawn_file_actions_destroy(posix_spawn_file_actions_t * fa)264c4dd129bSPeter Avalos posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa)
265c4dd129bSPeter Avalos {
266c4dd129bSPeter Avalos posix_spawn_file_actions_entry_t *fae;
267c4dd129bSPeter Avalos
268c4dd129bSPeter Avalos while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) {
269c4dd129bSPeter Avalos /* Remove file action entry from the queue */
270c4dd129bSPeter Avalos STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list);
271c4dd129bSPeter Avalos
272c4dd129bSPeter Avalos /* Deallocate file action entry */
273c4dd129bSPeter Avalos if (fae->fae_action == FAE_OPEN)
274c4dd129bSPeter Avalos free(fae->fae_path);
275c4dd129bSPeter Avalos free(fae);
276c4dd129bSPeter Avalos }
277c4dd129bSPeter Avalos
278c4dd129bSPeter Avalos free(*fa);
279c4dd129bSPeter Avalos return (0);
280c4dd129bSPeter Avalos }
281c4dd129bSPeter Avalos
282c4dd129bSPeter Avalos int
posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa,int fildes,const char * __restrict path,int oflag,mode_t mode)283c4dd129bSPeter Avalos posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa,
284c4dd129bSPeter Avalos int fildes, const char * __restrict path,
285c4dd129bSPeter Avalos int oflag, mode_t mode)
286c4dd129bSPeter Avalos {
287c4dd129bSPeter Avalos posix_spawn_file_actions_entry_t *fae;
288c4dd129bSPeter Avalos int error;
289c4dd129bSPeter Avalos
290c4dd129bSPeter Avalos if (fildes < 0)
291c4dd129bSPeter Avalos return (EBADF);
292c4dd129bSPeter Avalos
293c4dd129bSPeter Avalos /* Allocate object */
294c4dd129bSPeter Avalos fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
295c4dd129bSPeter Avalos if (fae == NULL)
296c4dd129bSPeter Avalos return (errno);
297c4dd129bSPeter Avalos
298c4dd129bSPeter Avalos /* Set values and store in queue */
299c4dd129bSPeter Avalos fae->fae_action = FAE_OPEN;
300c4dd129bSPeter Avalos fae->fae_path = strdup(path);
301c4dd129bSPeter Avalos if (fae->fae_path == NULL) {
302c4dd129bSPeter Avalos error = errno;
303c4dd129bSPeter Avalos free(fae);
304c4dd129bSPeter Avalos return (error);
305c4dd129bSPeter Avalos }
306c4dd129bSPeter Avalos fae->fae_fildes = fildes;
307c4dd129bSPeter Avalos fae->fae_oflag = oflag;
308c4dd129bSPeter Avalos fae->fae_mode = mode;
309c4dd129bSPeter Avalos
310c4dd129bSPeter Avalos STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
311c4dd129bSPeter Avalos return (0);
312c4dd129bSPeter Avalos }
313c4dd129bSPeter Avalos
314c4dd129bSPeter Avalos int
posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t * fa,int fildes,int newfildes)315c4dd129bSPeter Avalos posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa,
316c4dd129bSPeter Avalos int fildes, int newfildes)
317c4dd129bSPeter Avalos {
318c4dd129bSPeter Avalos posix_spawn_file_actions_entry_t *fae;
319c4dd129bSPeter Avalos
320c4dd129bSPeter Avalos if (fildes < 0 || newfildes < 0)
321c4dd129bSPeter Avalos return (EBADF);
322c4dd129bSPeter Avalos
323c4dd129bSPeter Avalos /* Allocate object */
324c4dd129bSPeter Avalos fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
325c4dd129bSPeter Avalos if (fae == NULL)
326c4dd129bSPeter Avalos return (errno);
327c4dd129bSPeter Avalos
328c4dd129bSPeter Avalos /* Set values and store in queue */
329c4dd129bSPeter Avalos fae->fae_action = FAE_DUP2;
330c4dd129bSPeter Avalos fae->fae_fildes = fildes;
331c4dd129bSPeter Avalos fae->fae_newfildes = newfildes;
332c4dd129bSPeter Avalos
333c4dd129bSPeter Avalos STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
334c4dd129bSPeter Avalos return (0);
335c4dd129bSPeter Avalos }
336c4dd129bSPeter Avalos
337c4dd129bSPeter Avalos int
posix_spawn_file_actions_addclose(posix_spawn_file_actions_t * fa,int fildes)338c4dd129bSPeter Avalos posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa,
339c4dd129bSPeter Avalos int fildes)
340c4dd129bSPeter Avalos {
341c4dd129bSPeter Avalos posix_spawn_file_actions_entry_t *fae;
342c4dd129bSPeter Avalos
343c4dd129bSPeter Avalos if (fildes < 0)
344c4dd129bSPeter Avalos return (EBADF);
345c4dd129bSPeter Avalos
346c4dd129bSPeter Avalos /* Allocate object */
347c4dd129bSPeter Avalos fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
348c4dd129bSPeter Avalos if (fae == NULL)
349c4dd129bSPeter Avalos return (errno);
350c4dd129bSPeter Avalos
351c4dd129bSPeter Avalos /* Set values and store in queue */
352c4dd129bSPeter Avalos fae->fae_action = FAE_CLOSE;
353c4dd129bSPeter Avalos fae->fae_fildes = fildes;
354c4dd129bSPeter Avalos
355c4dd129bSPeter Avalos STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
356c4dd129bSPeter Avalos return (0);
357c4dd129bSPeter Avalos }
358c4dd129bSPeter Avalos
359c4dd129bSPeter Avalos /*
360c4dd129bSPeter Avalos * Spawn attributes
361c4dd129bSPeter Avalos */
362c4dd129bSPeter Avalos
363c4dd129bSPeter Avalos int
posix_spawnattr_init(posix_spawnattr_t * ret)364c4dd129bSPeter Avalos posix_spawnattr_init(posix_spawnattr_t *ret)
365c4dd129bSPeter Avalos {
366c4dd129bSPeter Avalos posix_spawnattr_t sa;
367c4dd129bSPeter Avalos
368c4dd129bSPeter Avalos sa = calloc(1, sizeof(struct __posix_spawnattr));
369c4dd129bSPeter Avalos if (sa == NULL)
370c4dd129bSPeter Avalos return (errno);
371c4dd129bSPeter Avalos
372c4dd129bSPeter Avalos /* Set defaults as specified by POSIX, cleared above */
373c4dd129bSPeter Avalos *ret = sa;
374c4dd129bSPeter Avalos return (0);
375c4dd129bSPeter Avalos }
376c4dd129bSPeter Avalos
377c4dd129bSPeter Avalos int
posix_spawnattr_destroy(posix_spawnattr_t * sa)378c4dd129bSPeter Avalos posix_spawnattr_destroy(posix_spawnattr_t *sa)
379c4dd129bSPeter Avalos {
380c4dd129bSPeter Avalos free(*sa);
381c4dd129bSPeter Avalos return (0);
382c4dd129bSPeter Avalos }
383c4dd129bSPeter Avalos
384c4dd129bSPeter Avalos int
posix_spawnattr_getflags(const posix_spawnattr_t * __restrict sa,short * __restrict flags)385c4dd129bSPeter Avalos posix_spawnattr_getflags(const posix_spawnattr_t * __restrict sa,
386c4dd129bSPeter Avalos short * __restrict flags)
387c4dd129bSPeter Avalos {
388c4dd129bSPeter Avalos *flags = (*sa)->sa_flags;
389c4dd129bSPeter Avalos return (0);
390c4dd129bSPeter Avalos }
391c4dd129bSPeter Avalos
392c4dd129bSPeter Avalos int
posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict sa,pid_t * __restrict pgroup)393c4dd129bSPeter Avalos posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict sa,
394c4dd129bSPeter Avalos pid_t * __restrict pgroup)
395c4dd129bSPeter Avalos {
396c4dd129bSPeter Avalos *pgroup = (*sa)->sa_pgroup;
397c4dd129bSPeter Avalos return (0);
398c4dd129bSPeter Avalos }
399c4dd129bSPeter Avalos
400c4dd129bSPeter Avalos int
posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict sa,struct sched_param * __restrict schedparam)401c4dd129bSPeter Avalos posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict sa,
402c4dd129bSPeter Avalos struct sched_param * __restrict schedparam)
403c4dd129bSPeter Avalos {
404c4dd129bSPeter Avalos *schedparam = (*sa)->sa_schedparam;
405c4dd129bSPeter Avalos return (0);
406c4dd129bSPeter Avalos }
407c4dd129bSPeter Avalos
408c4dd129bSPeter Avalos int
posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict sa,int * __restrict schedpolicy)409c4dd129bSPeter Avalos posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict sa,
410c4dd129bSPeter Avalos int * __restrict schedpolicy)
411c4dd129bSPeter Avalos {
412c4dd129bSPeter Avalos *schedpolicy = (*sa)->sa_schedpolicy;
413c4dd129bSPeter Avalos return (0);
414c4dd129bSPeter Avalos }
415c4dd129bSPeter Avalos
416c4dd129bSPeter Avalos int
posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict sa,sigset_t * __restrict sigdefault)417c4dd129bSPeter Avalos posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict sa,
418c4dd129bSPeter Avalos sigset_t * __restrict sigdefault)
419c4dd129bSPeter Avalos {
420c4dd129bSPeter Avalos *sigdefault = (*sa)->sa_sigdefault;
421c4dd129bSPeter Avalos return (0);
422c4dd129bSPeter Avalos }
423c4dd129bSPeter Avalos
424c4dd129bSPeter Avalos int
posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa,sigset_t * __restrict sigmask)425c4dd129bSPeter Avalos posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa,
426c4dd129bSPeter Avalos sigset_t * __restrict sigmask)
427c4dd129bSPeter Avalos {
428c4dd129bSPeter Avalos *sigmask = (*sa)->sa_sigmask;
429c4dd129bSPeter Avalos return (0);
430c4dd129bSPeter Avalos }
431c4dd129bSPeter Avalos
432c4dd129bSPeter Avalos int
posix_spawnattr_setflags(posix_spawnattr_t * sa,short flags)433c4dd129bSPeter Avalos posix_spawnattr_setflags(posix_spawnattr_t *sa, short flags)
434c4dd129bSPeter Avalos {
435c4dd129bSPeter Avalos (*sa)->sa_flags = flags;
436c4dd129bSPeter Avalos return (0);
437c4dd129bSPeter Avalos }
438c4dd129bSPeter Avalos
439c4dd129bSPeter Avalos int
posix_spawnattr_setpgroup(posix_spawnattr_t * sa,pid_t pgroup)440c4dd129bSPeter Avalos posix_spawnattr_setpgroup(posix_spawnattr_t *sa, pid_t pgroup)
441c4dd129bSPeter Avalos {
442c4dd129bSPeter Avalos (*sa)->sa_pgroup = pgroup;
443c4dd129bSPeter Avalos return (0);
444c4dd129bSPeter Avalos }
445c4dd129bSPeter Avalos
446c4dd129bSPeter Avalos int
posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict sa,const struct sched_param * __restrict schedparam)447c4dd129bSPeter Avalos posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict sa,
448c4dd129bSPeter Avalos const struct sched_param * __restrict schedparam)
449c4dd129bSPeter Avalos {
450c4dd129bSPeter Avalos (*sa)->sa_schedparam = *schedparam;
451c4dd129bSPeter Avalos return (0);
452c4dd129bSPeter Avalos }
453c4dd129bSPeter Avalos
454c4dd129bSPeter Avalos int
posix_spawnattr_setschedpolicy(posix_spawnattr_t * sa,int schedpolicy)455c4dd129bSPeter Avalos posix_spawnattr_setschedpolicy(posix_spawnattr_t *sa, int schedpolicy)
456c4dd129bSPeter Avalos {
457c4dd129bSPeter Avalos (*sa)->sa_schedpolicy = schedpolicy;
458c4dd129bSPeter Avalos return (0);
459c4dd129bSPeter Avalos }
460c4dd129bSPeter Avalos
461c4dd129bSPeter Avalos int
posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict sa,const sigset_t * __restrict sigdefault)462c4dd129bSPeter Avalos posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict sa,
463c4dd129bSPeter Avalos const sigset_t * __restrict sigdefault)
464c4dd129bSPeter Avalos {
465c4dd129bSPeter Avalos (*sa)->sa_sigdefault = *sigdefault;
466c4dd129bSPeter Avalos return (0);
467c4dd129bSPeter Avalos }
468c4dd129bSPeter Avalos
469c4dd129bSPeter Avalos int
posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa,const sigset_t * __restrict sigmask)470c4dd129bSPeter Avalos posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa,
471c4dd129bSPeter Avalos const sigset_t * __restrict sigmask)
472c4dd129bSPeter Avalos {
473c4dd129bSPeter Avalos (*sa)->sa_sigmask = *sigmask;
474c4dd129bSPeter Avalos return (0);
475c4dd129bSPeter Avalos }
476