]>
Commit | Line | Data |
---|---|---|
1 | .\" Copyright (c) 2009 Bill O. Gallmeister (bgallmeister@gmail.com) | |
2 | .\" and Copyright 2010 Michael Kerrisk <mtk.manpages@gmail.com> | |
3 | .\" | |
4 | .\" %%%LICENSE_START(VERBATIM) | |
5 | .\" Permission is granted to make and distribute verbatim copies of this | |
6 | .\" manual provided the copyright notice and this permission notice are | |
7 | .\" preserved on all copies. | |
8 | .\" | |
9 | .\" Permission is granted to copy and distribute modified versions of this | |
10 | .\" manual under the conditions for verbatim copying, provided that the | |
11 | .\" entire resulting derived work is distributed under the terms of a | |
12 | .\" permission notice identical to this one. | |
13 | .\" | |
14 | .\" Since the Linux kernel and libraries are constantly changing, this | |
15 | .\" manual page may be incorrect or out-of-date. The author(s) assume no | |
16 | .\" responsibility for errors or omissions, or for damages resulting from | |
17 | .\" the use of the information contained herein. The author(s) may not | |
18 | .\" have taken the same level of care in the production of this manual, | |
19 | .\" which is licensed free of charge, as they might when working | |
20 | .\" professionally. | |
21 | .\" | |
22 | .\" Formatted or processed versions of this manual, if unaccompanied by | |
23 | .\" the source, must acknowledge the copyright and authors of this work. | |
24 | .\" %%%LICENSE_END | |
25 | .\" | |
26 | .\" References consulted: | |
27 | .\" Linux glibc source code | |
28 | .\" POSIX 1003.1-2004 documentation | |
29 | .\" (http://www.opengroup.org/onlinepubs/009695399) | |
30 | .\" | |
31 | .TH POSIX_SPAWN 3 2017-09-15 "GNU" "Linux Programmer's Manual" | |
32 | .SH NAME | |
33 | posix_spawn, posix_spawnp \- spawn a process | |
34 | .SH SYNOPSIS | |
35 | .nf | |
36 | .B #include <spawn.h> | |
37 | .PP | |
38 | .BI "int posix_spawn(pid_t *" pid ", const char *" path , | |
39 | .BI " const posix_spawn_file_actions_t *" file_actions , | |
40 | .BI " const posix_spawnattr_t *" attrp , | |
41 | .BI " char *const " argv[] ", char *const " envp[] ); | |
42 | .PP | |
43 | .BI "int posix_spawnp(pid_t *" pid ", const char *" file , | |
44 | .BI " const posix_spawn_file_actions_t *" file_actions , | |
45 | .BI " const posix_spawnattr_t *" attrp , | |
46 | .BI " char *const " argv[] ", char *const " envp[] ); | |
47 | .fi | |
48 | .SH DESCRIPTION | |
49 | The | |
50 | .BR posix_spawn () | |
51 | and | |
52 | .BR posix_spawnp () | |
53 | functions are used to create a new child process that executes | |
54 | a specified file. | |
55 | These functions were specified by POSIX to provide a standardized method | |
56 | of creating new processes on machines that lack the capability | |
57 | to support the | |
58 | .BR fork (2) | |
59 | system call. | |
60 | These machines are generally small, embedded systems lacking MMU support. | |
61 | .PP | |
62 | The | |
63 | .BR posix_spawn () | |
64 | and | |
65 | .BR posix_spawnp () | |
66 | functions provide the functionality of a combined | |
67 | .BR fork (2) | |
68 | and | |
69 | .BR exec (3), | |
70 | with some optional housekeeping steps in the child process before the | |
71 | .BR exec (3). | |
72 | These functions are not meant to replace the | |
73 | .BR fork (2) | |
74 | and | |
75 | .BR execve (2) | |
76 | system calls. | |
77 | In fact, they provide only a subset of the functionality | |
78 | that can be achieved by using the system calls. | |
79 | .PP | |
80 | The only difference between | |
81 | .BR posix_spawn () | |
82 | and | |
83 | .BR posix_spawnp () | |
84 | is the manner in which they specify the file to be executed by | |
85 | the child process. | |
86 | With | |
87 | .BR posix_spawn (), | |
88 | the executable file is specified as a pathname | |
89 | (which can be absolute or relative). | |
90 | With | |
91 | .BR posix_spawnp (), | |
92 | the executable file is specified as a simple filename; | |
93 | the system searches for this file in the list of directories specified by | |
94 | .BR PATH | |
95 | (in the same way as for | |
96 | .BR execvp (3)). | |
97 | For the remainder of this page, the discussion is phrased in terms of | |
98 | .BR posix_spawn (), | |
99 | with the understanding that | |
100 | .BR posix_spawnp () | |
101 | differs only on the point just described. | |
102 | .PP | |
103 | The remaining arguments to these two functions are as follows: | |
104 | .IP * 3 | |
105 | The | |
106 | .I pid | |
107 | argument points to a buffer that is used to return the process ID | |
108 | of the new child process. | |
109 | .IP * | |
110 | The | |
111 | .I file_actions | |
112 | argument points to a | |
113 | .I "spawn file actions object" | |
114 | that specifies file-related actions to be performed in the child | |
115 | between the | |
116 | .BR fork (2) | |
117 | and | |
118 | .BR exec (3) | |
119 | steps. | |
120 | This object is initialized and populated before the | |
121 | .BR posix_spawn () | |
122 | call using | |
123 | .BR posix_spawn_file_actions_init (3) | |
124 | and the | |
125 | .BR posix_spawn_file_actions_* () | |
126 | functions. | |
127 | .IP * | |
128 | The | |
129 | .I attrp | |
130 | argument points to an | |
131 | .I attributes objects | |
132 | that specifies various attributes of the created child process. | |
133 | This object is initialized and populated before the | |
134 | .BR posix_spawn () | |
135 | call using | |
136 | .BR posix_spawnattr_init (3) | |
137 | and the | |
138 | .BR posix_spawnattr_* () | |
139 | functions. | |
140 | .IP * | |
141 | The | |
142 | .I argv | |
143 | and | |
144 | .I envp | |
145 | arguments specify the argument list and environment for the program | |
146 | that is executed in the child process, as for | |
147 | .BR execve (2). | |
148 | .PP | |
149 | Below, the functions are described in terms of a three-step process: the | |
150 | .BR fork() | |
151 | step, the | |
152 | .RB pre- exec () | |
153 | step (executed in the child), | |
154 | and the | |
155 | .BR exec () | |
156 | step (executed in the child). | |
157 | .SS fork() step | |
158 | The | |
159 | .BR posix_spawn () | |
160 | function commences by calling | |
161 | .BR fork (2), | |
162 | or possibly | |
163 | .BR vfork (2) | |
164 | (see below). | |
165 | .PP | |
166 | The PID of the new child process is placed in | |
167 | .IR *pid . | |
168 | The | |
169 | .BR posix_spawn () | |
170 | function then returns control to the parent process. | |
171 | .PP | |
172 | Subsequently, the parent can use one of the system calls described in | |
173 | .BR wait (2) | |
174 | to check the status of the child process. | |
175 | If the child fails in any of the housekeeping steps described below, | |
176 | or fails to execute the desired file, | |
177 | it exits with a status of 127. | |
178 | .PP | |
179 | The child process is created using | |
180 | .BR vfork (2) | |
181 | instead of | |
182 | .BR fork (2) | |
183 | when either of the following is true: | |
184 | .IP * 3 | |
185 | the | |
186 | .I spawn-flags | |
187 | element of the attributes object pointed to by | |
188 | .I attrp | |
189 | contains the GNU-specific flag | |
190 | .BR POSIX_SPAWN_USEVFORK ; | |
191 | or | |
192 | .IP * | |
193 | .I file_actions | |
194 | is NULL and the | |
195 | .I spawn-flags | |
196 | element of the attributes object pointed to by | |
197 | .I attrp | |
198 | does \fInot\fP contain | |
199 | .BR POSIX_SPAWN_SETSIGMASK , | |
200 | .BR POSIX_SPAWN_SETSIGDEF , | |
201 | .BR POSIX_SPAWN_SETSCHEDPARAM , | |
202 | .BR POSIX_SPAWN_SETSCHEDULER , | |
203 | .BR POSIX_SPAWN_SETPGROUP , | |
204 | or | |
205 | .BR POSIX_SPAWN_RESETIDS . | |
206 | .PP | |
207 | In other words, | |
208 | .BR vfork (2) | |
209 | is used if the caller requests it, | |
210 | or if there is no cleanup expected in the child before it | |
211 | .BR exec (3)s | |
212 | the requested file. | |
213 | .PP | |
214 | .SS pre-exec() step: housekeeping | |
215 | In between the | |
216 | .BR fork (2) | |
217 | and the | |
218 | .BR exec (3), | |
219 | a child process may need to perform a set of housekeeping actions. | |
220 | The | |
221 | .BR posix_spawn () | |
222 | and | |
223 | .BR posix_spawnp () | |
224 | functions support a small, well-defined set of system tasks that the child | |
225 | process can accomplish before it executes the executable file. | |
226 | These operations are controlled by the attributes object pointed to by | |
227 | .IR attrp | |
228 | and the file actions object pointed to by | |
229 | .IR file_actions . | |
230 | In the child, processing is done in the following sequence: | |
231 | .IP 1. 3 | |
232 | Process attribute actions: signal mask, signal default handlers, | |
233 | scheduling algorithm and parameters, | |
234 | process group, and effective user and group IDs | |
235 | are changed as specified by the attributes object pointed to by | |
236 | .IR attrp . | |
237 | .IP 2. | |
238 | File actions, as specified in the | |
239 | .I file_actions | |
240 | argument, | |
241 | are performed in the order that they were specified using calls to the | |
242 | .BR posix_spawn_file_actions_add* () | |
243 | functions. | |
244 | .IP 3. | |
245 | File descriptors with the | |
246 | .B FD_CLOEXEC | |
247 | flag set are closed. | |
248 | .PP | |
249 | All process attributes in the child, | |
250 | other than those affected by attributes specified in the | |
251 | object pointed to by | |
252 | .IR attrp | |
253 | and the file actions in the object pointed to by | |
254 | .IR file_actions , | |
255 | will be affected as though the child was created with | |
256 | .BR fork (2) | |
257 | and it executed the program with | |
258 | .BR execve (2). | |
259 | .PP | |
260 | The process attributes actions are defined by the attributes object | |
261 | pointed to by | |
262 | .IR attrp . | |
263 | The | |
264 | .I spawn-flags | |
265 | attribute (set using | |
266 | .BR posix_spawnattr_setflags (3)) | |
267 | controls the general actions that occur, | |
268 | and other attributes in the object specify values | |
269 | to be used during those actions. | |
270 | .PP | |
271 | The effects of the flags that may be specified in | |
272 | .IR spawn-flags | |
273 | are as follows: | |
274 | .TP 8 | |
275 | .B POSIX_SPAWN_SETSIGMASK | |
276 | Set the signal mask to the signal set specified in the | |
277 | .I spawn-sigmask | |
278 | attribute | |
279 | .\" FIXME . | |
280 | .\" (see | |
281 | .\" .BR posix_spawnattr_setsigmask (3)) | |
282 | of the object pointed to by | |
283 | .IR attrp . | |
284 | If the | |
285 | .B POSIX_SPAWN_SETSIGMASK | |
286 | flag is not set, then the child inherits the parent's signal mask. | |
287 | .TP | |
288 | .B POSIX_SPAWN_SETSIGDEF | |
289 | Reset the disposition of all signals in the set specified in the | |
290 | .I spawn-sigdefault | |
291 | attribute | |
292 | .\" FIXME . | |
293 | .\" (see | |
294 | .\" .BR posix_spawnattr_setsigdefault (3)) | |
295 | of the object pointed to by | |
296 | .IR attrp | |
297 | to the default. | |
298 | For the treatment of the dispositions of signals not specified in the | |
299 | .I spawn-sigdefault | |
300 | attribute, or the treatment when | |
301 | .B POSIX_SPAWN_SETSIGDEF | |
302 | is not specified, see | |
303 | .BR execve (2). | |
304 | .TP | |
305 | .B POSIX_SPAWN_SETSCHEDPARAM | |
306 | .\" (POSIX_PRIORITY_SCHEDULING only) | |
307 | If this flag is set, and the | |
308 | .B POSIX_SPAWN_SETSCHEDULER | |
309 | flag is not set, then set the scheduling parameters | |
310 | to the parameters specified in the | |
311 | .I spawn-schedparam | |
312 | attribute | |
313 | .\" FIXME . | |
314 | .\" (see | |
315 | .\" .BR posix_spawnattr_setschedparam (3)) | |
316 | of the object pointed to by | |
317 | .IR attrp . | |
318 | .TP | |
319 | .B POSIX_SPAWN_SETSCHEDULER | |
320 | Set the scheduling policy algorithm and parameters of the child, | |
321 | as follows: | |
322 | .RS | |
323 | .IP * 3 | |
324 | The scheduling policy is set to the value specified in the | |
325 | .I spawn-schedpolicy | |
326 | attribute | |
327 | .\" FIXME . | |
328 | .\" (see | |
329 | .\" .BR posix_spawnattr_setpolicy (3)) | |
330 | of the object pointed to by | |
331 | .IR attrp . | |
332 | .IP * | |
333 | The scheduling parameters are set to the value specified in the | |
334 | .I spawn-schedparam | |
335 | attribute | |
336 | .\" FIXME . | |
337 | .\" (see | |
338 | .\" .BR posix_spawnattr_setschedparam (3)) | |
339 | of the object pointed to by | |
340 | .IR attrp | |
341 | (but see BUGS). | |
342 | .PP | |
343 | If the | |
344 | .B POSIX_SPAWN_SETSCHEDPARAM | |
345 | and | |
346 | .B POSIX_SPAWN_SETSCHEDPOLICY | |
347 | flags are not specified, | |
348 | the child inherits the corresponding scheduling attributes from the parent. | |
349 | .RE | |
350 | .TP | |
351 | .B POSIX_SPAWN_RESETIDS | |
352 | If this flag is set, | |
353 | reset the effective UID and GID to the | |
354 | real UID and GID of the parent process. | |
355 | If this flag is not set, | |
356 | then the child retains the effective UID and GID of the parent. | |
357 | In either case, if the set-user-ID and set-group-ID permission | |
358 | bits are enabled on the executable file, their effect will override | |
359 | the setting of the effective UID and GID (se | |
360 | .BR execve (2)). | |
361 | .TP | |
362 | .B POSIX_SPAWN_SETPGROUP | |
363 | Set the process group to the value specified in the | |
364 | .I spawn-pgroup | |
365 | attribute | |
366 | .\" FIXME . | |
367 | .\" (see | |
368 | .\" .BR posix_spawnattr_setpgroup (3)) | |
369 | of the object pointed to by | |
370 | .IR attrp . | |
371 | If the | |
372 | .I spawn-pgroup | |
373 | attribute has the value 0, | |
374 | the child's process group ID is made the same as its process ID. | |
375 | If the | |
376 | .B POSIX_SPAWN_SETPGROUP | |
377 | flag is not set, the child inherits the parent's process group ID. | |
378 | .PP | |
379 | If | |
380 | .I attrp | |
381 | is NULL, then the default behaviors described above for each flag apply. | |
382 | .\" mtk: I think we probably don't want to say the following, since it | |
383 | .\" could lead people to do the wrong thing | |
384 | .\" The POSIX standard tells you to call | |
385 | .\" this function to de-initialize the attributes object pointed to by | |
386 | .\" .I attrp | |
387 | .\" when you are done with it; | |
388 | .\" however, on Linux systems this operation is a no-op. | |
389 | .PP | |
390 | The | |
391 | .I file_actions | |
392 | argument specifies a sequence of file operations | |
393 | that are performed in the child process after | |
394 | the general processing described above, and before it performs the | |
395 | .BR exec (3). | |
396 | If | |
397 | .I file_actions | |
398 | is NULL, then no special action is taken, and standard | |
399 | .BR exec (3) | |
400 | semantics apply--file descriptors open before the exec | |
401 | remain open in the new process, | |
402 | except those for which the | |
403 | .B FD_CLOEXEC | |
404 | flag has been set. | |
405 | File locks remain in place. | |
406 | .PP | |
407 | If | |
408 | .I file_actions | |
409 | is not NULL, then it contains an ordered set of requests to | |
410 | .BR open (2), | |
411 | .BR close (2), | |
412 | and | |
413 | .BR dup2 (2) | |
414 | files. | |
415 | These requests are added to the | |
416 | .I file_actions | |
417 | by | |
418 | .BR posix_spawn_file_actions_addopen (3), | |
419 | .BR posix_spawn_file_actions_addclose (3), | |
420 | and | |
421 | .BR posix_spawn_file_actions_adddup2 (3). | |
422 | The requested operations are performed in the order they were added to | |
423 | .IR file_actions . | |
424 | .\" FIXME . I think the following is best placed in the | |
425 | .\" posix_spawn_file_actions_adddup2(3) page, and a similar statement is | |
426 | .\" also needed in posix_spawn_file_actions_addclose(3) | |
427 | .\" Note that you can specify file descriptors in | |
428 | .\" .I posix_spawn_file_actions_adddup2 (3) | |
429 | .\" which would not be usable if you called | |
430 | .\" .BR dup2 (2) | |
431 | .\" at that time--i.e., file descriptors that are opened or | |
432 | .\" closed by the earlier operations | |
433 | .\" added to | |
434 | .\" .I file_actions . | |
435 | .PP | |
436 | If any of the housekeeping actions fails | |
437 | (due to bogus values being passed or other reasons why signal handling, | |
438 | process scheduling, process group ID functions, | |
439 | and file descriptor operations might fail), | |
440 | the child process exits with exit value 127. | |
441 | .SS exec() step | |
442 | Once the child has successfully forked and performed | |
443 | all requested pre-exec steps, | |
444 | the child runs the requested executable. | |
445 | .PP | |
446 | The child process takes its environment from the | |
447 | .I envp | |
448 | argument, which is interpreted as if it had been passed to | |
449 | .BR execve (2). | |
450 | The arguments to the created process come from the | |
451 | .I argv | |
452 | argument, which is processed as for | |
453 | .BR execve (2). | |
454 | .SH RETURN VALUE | |
455 | Upon successful completion, | |
456 | .BR posix_spawn () | |
457 | and | |
458 | .BR posix_spawnp () | |
459 | place the PID of the child process in | |
460 | .IR pid , | |
461 | and return 0. | |
462 | If there is an error before or during the | |
463 | .BR fork (2), | |
464 | then no child is created, | |
465 | the contents of | |
466 | .IR *pid | |
467 | are unspecified, | |
468 | and these functions return an error number as described below. | |
469 | .PP | |
470 | Even when these functions return a success status, | |
471 | the child process may still fail for a plethora of reasons related to its | |
472 | pre-\fBexec\fR() initialization. | |
473 | In addition, the | |
474 | .BR exec (3) | |
475 | may fail. | |
476 | In all of these cases, the child process will exit with the exit value of 127. | |
477 | .SH ERRORS | |
478 | The | |
479 | .BR posix_spawn () | |
480 | and | |
481 | .BR posix_spawnp () | |
482 | functions fail only in the case where the underlying | |
483 | .BR fork (2) | |
484 | or | |
485 | .BR vfork (2) | |
486 | call fails; in these cases, these functions return an error number, | |
487 | which will be one of the errors described for | |
488 | .BR fork (2) | |
489 | or | |
490 | .BR vfork (2). | |
491 | .PP | |
492 | In addition, these functions fail if: | |
493 | .TP | |
494 | .B ENOSYS | |
495 | Function not supported on this system. | |
496 | .SH VERSIONS | |
497 | The | |
498 | .BR posix_spawn () | |
499 | and | |
500 | .BR posix_spawnp () | |
501 | functions are available since glibc 2.2. | |
502 | .SH CONFORMING TO | |
503 | .PP | |
504 | POSIX.1-2001, POSIX.1-2008. | |
505 | .\" FIXME . This piece belongs in spawnattr_setflags(3) | |
506 | .\" The | |
507 | .\" .B POSIX_SPAWN_USEVFORK | |
508 | .\" flag is a GNU extension; the | |
509 | .\" .B _GNU_SOURCE | |
510 | .\" feature test macro must be defined (before including any header files) | |
511 | .\" to obtain the definition of this constant. | |
512 | .SH NOTES | |
513 | The housekeeping activities in the child are controlled by | |
514 | the objects pointed to by | |
515 | .I attrp | |
516 | (for non-file actions) and | |
517 | .I file_actions | |
518 | In POSIX parlance, the | |
519 | .I posix_spawnattr_t | |
520 | and | |
521 | .I posix_spawn_file_actions_t | |
522 | data types are referred to as objects, | |
523 | and their elements are not specified by name. | |
524 | Portable programs should initialize these objects using | |
525 | only the POSIX-specified functions. | |
526 | (In other words, | |
527 | although these objects may be implemented as structures containing fields, | |
528 | portable programs must avoid dependence on such implementation details.) | |
529 | .PP | |
530 | According to POSIX, it unspecified whether fork handlers established with | |
531 | .BR pthread_atfork (3) | |
532 | are called when | |
533 | .BR posix_spawn () | |
534 | is invoked. | |
535 | On glibc, | |
536 | .\" Tested on glibc 2.12 | |
537 | fork handlers are called only if the child is created using | |
538 | .BR fork (2). | |
539 | .PP | |
540 | There is no "posix_fspawn" function (i.e., a function that is to | |
541 | .BR posix_spawn () | |
542 | as | |
543 | .BR fexecve (3) | |
544 | is to | |
545 | .BR execve (2)). | |
546 | However, this functionality can be obtained by specifying the | |
547 | .I path | |
548 | argument as one of the files in the caller's | |
549 | .IR /proc/self/fd | |
550 | directory. | |
551 | .SH BUGS | |
552 | POSIX.1 says that when | |
553 | .B POSIX_SPAWN_SETSCHEDULER | |
554 | is specified in | |
555 | .IR spawn-flags , | |
556 | then the | |
557 | .B POSIX_SPAWN_SETSCHEDPARAM | |
558 | (if present) is ignored. | |
559 | However, before glibc 2.14, calls to | |
560 | .BR posix_spawn () | |
561 | failed with an error if | |
562 | .\" http://sourceware.org/bugzilla/show_bug.cgi?id=12052 | |
563 | .BR POSIX_SPAWN_SETSCHEDULER | |
564 | was specified without also specifying | |
565 | .BR POSIX_SPAWN_SETSCHEDPARAM . | |
566 | .SH EXAMPLE | |
567 | The program below demonstrates the use of various functions in the | |
568 | POSIX spawn API. | |
569 | The program accepts command-line attributes that can be used | |
570 | to create file actions and attributes objects. | |
571 | The remaining command-line arguments are used as the executable name | |
572 | and command-line arguments of the program that is executed in the child. | |
573 | .PP | |
574 | In the first run, the | |
575 | .BR date (1) | |
576 | command is executed in the child, and the | |
577 | .BR posix_spawn () | |
578 | call employs no file actions or attributes objects. | |
579 | .PP | |
580 | .in +4 | |
581 | .EX | |
582 | $ \fB./a.out date\fP | |
583 | PID of child: 7634 | |
584 | Tue Feb 1 19:47:50 CEST 2011 | |
585 | Child status: exited, status=0 | |
586 | .EE | |
587 | .in | |
588 | .PP | |
589 | In the next run, the | |
590 | .I \-c | |
591 | command-line option is used to create a file actions object that closes | |
592 | standard output in the child. | |
593 | Consequently, | |
594 | .BR date (1) | |
595 | fails when trying to perform output and exits with a status of 1. | |
596 | .PP | |
597 | .in +4 | |
598 | .EX | |
599 | $ \fB./a.out -c date\fP | |
600 | PID of child: 7636 | |
601 | date: write error: Bad file descriptor | |
602 | Child status: exited, status=1 | |
603 | .EE | |
604 | .in | |
605 | .PP | |
606 | In the next run, the | |
607 | .I \-s | |
608 | command-line option is used to create an attributes object that | |
609 | specifies that all (blockable) signals in the child should be blocked. | |
610 | Consequently, trying to kill child with the default signal sent by | |
611 | .BR kill (1) | |
612 | (i.e., | |
613 | .BR SIGTERM ) | |
614 | fails, because that signal is blocked. | |
615 | Therefore, to kill the child, | |
616 | .BR SIGKILL | |
617 | is necessary | |
618 | .RB ( SIGKILL | |
619 | can't be blocked). | |
620 | .PP | |
621 | .in +4 | |
622 | .EX | |
623 | $ \fB./a.out -s sleep 60 &\fP | |
624 | [1] 7637 | |
625 | $ PID of child: 7638 | |
626 | ||
627 | $ \fBkill 7638\fP | |
628 | $ \fBkill -KILL 7638\fP | |
629 | $ Child status: killed by signal 9 | |
630 | [1]+ Done ./a.out -s sleep 60 | |
631 | .EE | |
632 | .in | |
633 | .PP | |
634 | When we try to execute a nonexistent command in the child, the | |
635 | .BR exec (3) | |
636 | fails and the child exits with a status of 127. | |
637 | .PP | |
638 | .in +4 | |
639 | .EX | |
640 | $ \fB./a.out xxxxx | |
641 | PID of child: 10190 | |
642 | Child status: exited, status=127 | |
643 | .EE | |
644 | .in | |
645 | .SS Program source | |
646 | \& | |
647 | .EX | |
648 | #include <spawn.h> | |
649 | #include <stdio.h> | |
650 | #include <unistd.h> | |
651 | #include <stdlib.h> | |
652 | #include <string.h> | |
653 | #include <wait.h> | |
654 | #include <errno.h> | |
655 | ||
656 | #define errExit(msg) do { perror(msg); \\ | |
657 | exit(EXIT_FAILURE); } while (0) | |
658 | ||
659 | #define errExitEN(en, msg) \\ | |
660 | do { errno = en; perror(msg); \\ | |
661 | exit(EXIT_FAILURE); } while (0) | |
662 | ||
663 | char **environ; | |
664 | ||
665 | int | |
666 | main(int argc, char *argv[]) | |
667 | { | |
668 | pid_t child_pid; | |
669 | int s, opt, status; | |
670 | sigset_t mask; | |
671 | posix_spawnattr_t attr; | |
672 | posix_spawnattr_t *attrp; | |
673 | posix_spawn_file_actions_t file_actions; | |
674 | posix_spawn_file_actions_t *file_actionsp; | |
675 | ||
676 | /* Parse command\-line options, which can be used to specify an | |
677 | attributes object and file actions object for the child. */ | |
678 | ||
679 | attrp = NULL; | |
680 | file_actionsp = NULL; | |
681 | ||
682 | while ((opt = getopt(argc, argv, "sc")) != \-1) { | |
683 | switch (opt) { | |
684 | case \(aqc\(aq: /* \-c: close standard output in child */ | |
685 | ||
686 | /* Create a file actions object and add a "close" | |
687 | action to it */ | |
688 | ||
689 | s = posix_spawn_file_actions_init(&file_actions); | |
690 | if (s != 0) | |
691 | errExitEN(s, "posix_spawn_file_actions_init"); | |
692 | ||
693 | s = posix_spawn_file_actions_addclose(&file_actions, | |
694 | STDOUT_FILENO); | |
695 | if (s != 0) | |
696 | errExitEN(s, "posix_spawn_file_actions_addclose"); | |
697 | ||
698 | file_actionsp = &file_actions; | |
699 | break; | |
700 | ||
701 | case \(aqs\(aq: /* \-s: block all signals in child */ | |
702 | ||
703 | /* Create an attributes object and add a "set signal mask" | |
704 | action to it */ | |
705 | ||
706 | s = posix_spawnattr_init(&attr); | |
707 | if (s != 0) | |
708 | errExitEN(s, "posix_spawnattr_init"); | |
709 | s = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK); | |
710 | if (s != 0) | |
711 | errExitEN(s, "posix_spawnattr_setflags"); | |
712 | ||
713 | sigfillset(&mask); | |
714 | s = posix_spawnattr_setsigmask(&attr, &mask); | |
715 | if (s != 0) | |
716 | errExitEN(s, "posix_spawnattr_setsigmask"); | |
717 | ||
718 | attrp = &attr; | |
719 | break; | |
720 | } | |
721 | } | |
722 | ||
723 | /* Spawn the child. The name of the program to execute and the | |
724 | command\-line arguments are taken from the command\-line arguments | |
725 | of this program. The environment of the program execed in the | |
726 | child is made the same as the parent\(aqs environment. */ | |
727 | ||
728 | s = posix_spawnp(&child_pid, argv[optind], file_actionsp, attrp, | |
729 | &argv[optind], environ); | |
730 | if (s != 0) | |
731 | errExitEN(s, "posix_spawn"); | |
732 | ||
733 | /* Destroy any objects that we created earlier */ | |
734 | ||
735 | if (attrp != NULL) { | |
736 | s = posix_spawnattr_destroy(attrp); | |
737 | if (s != 0) | |
738 | errExitEN(s, "posix_spawnattr_destroy"); | |
739 | } | |
740 | ||
741 | if (file_actionsp != NULL) { | |
742 | s = posix_spawn_file_actions_destroy(file_actionsp); | |
743 | if (s != 0) | |
744 | errExitEN(s, "posix_spawn_file_actions_destroy"); | |
745 | } | |
746 | ||
747 | printf("PID of child: %ld\\n", (long) child_pid); | |
748 | ||
749 | /* Monitor status of the child until it terminates */ | |
750 | ||
751 | do { | |
752 | s = waitpid(child_pid, &status, WUNTRACED | WCONTINUED); | |
753 | if (s == \-1) | |
754 | errExit("waitpid"); | |
755 | ||
756 | printf("Child status: "); | |
757 | if (WIFEXITED(status)) { | |
758 | printf("exited, status=%d\\n", WEXITSTATUS(status)); | |
759 | } else if (WIFSIGNALED(status)) { | |
760 | printf("killed by signal %d\\n", WTERMSIG(status)); | |
761 | } else if (WIFSTOPPED(status)) { | |
762 | printf("stopped by signal %d\\n", WSTOPSIG(status)); | |
763 | } else if (WIFCONTINUED(status)) { | |
764 | printf("continued\\n"); | |
765 | } | |
766 | } while (!WIFEXITED(status) && !WIFSIGNALED(status)); | |
767 | ||
768 | exit(EXIT_SUCCESS); | |
769 | } | |
770 | .EE | |
771 | .SH SEE ALSO | |
772 | .nh \" Disable hyphenation | |
773 | .ad l | |
774 | .BR close (2), | |
775 | .BR dup2 (2), | |
776 | .BR execl (2), | |
777 | .BR execlp (2), | |
778 | .BR fork (2), | |
779 | .BR open (2), | |
780 | .BR sched_setparam (2), | |
781 | .BR sched_setscheduler (2), | |
782 | .BR setpgid (2), | |
783 | .BR setuid (2), | |
784 | .BR sigaction (2), | |
785 | .BR sigprocmask (2), | |
786 | .BR posix_spawn_file_actions_addclose (3), | |
787 | .BR posix_spawn_file_actions_adddup2 (3), | |
788 | .BR posix_spawn_file_actions_addopen (3), | |
789 | .BR posix_spawn_file_actions_destroy (3), | |
790 | .BR posix_spawn_file_actions_init (3), | |
791 | .BR posix_spawnattr_destroy (3), | |
792 | .BR posix_spawnattr_getflags (3), | |
793 | .BR posix_spawnattr_getpgroup (3), | |
794 | .BR posix_spawnattr_getschedparam (3), | |
795 | .BR posix_spawnattr_getschedpolicy (3), | |
796 | .BR posix_spawnattr_getsigdefault (3), | |
797 | .BR posix_spawnattr_getsigmask (3), | |
798 | .BR posix_spawnattr_init (3), | |
799 | .BR posix_spawnattr_setflags (3), | |
800 | .BR posix_spawnattr_setpgroup (3), | |
801 | .BR posix_spawnattr_setschedparam (3), | |
802 | .BR posix_spawnattr_setschedpolicy (3), | |
803 | .BR posix_spawnattr_setsigdefault (3), | |
804 | .BR posix_spawnattr_setsigmask (3), | |
805 | .BR pthread_atfork (3), | |
806 | .BR <spawn.h>, | |
807 | Base Definitions volume of POSIX.1-2001, | |
808 | .I http://www.opengroup.org/unix/online.html |