posix_spawn(), posix_spawnp()

Spawn a process

Synopsis:

#include <spawn.h>

int posix_spawn(pid_t *_Restrict pid,
                const char *_Restrict path,
                const posix_spawn_file_actions_t * file_actions,
                const posix_spawnattr_t *_Restrict attrp,
                char * const argv[_Restrict_arr],
                char * const envp[_Restrict_arr] );

int posix_spawnp(pid_t *_Restrict pid,
                 const char *_Restrict file,
                 const posix_spawn_file_actions_t * file_actions,
                 const posix_spawnattr_t *_Restrict attrp,
                 char * const argv[_Restrict_arr],
                 char * const envp[_Restrict_arr] );

Arguments:

pid
NULL, or a pointer to a location where the function can store the process ID of the child process.
path
(posix_spawn() only) An absolute path to the executable. Use posix_spawnp() to search for the executable to spawn.
file
(posix_spawnp() only) The name of the executable file, which is used to construct a pathname that identifies the new process image file. If the file parameter contains a slash character, the file parameter is used as the pathname for the new process image file. Otherwise, the path prefix for this file is obtained by a search of the directories passed as the environment variable PATH. If this environment variable isn't defined, the results of the search are implementation-defined.
file_actions
NULL, or a pointer to an opaque spawn file actions object that specifies the actions you want to perform on the file descriptors in the child process. For more information, see File actions, below.
attrp
NULL, or a pointer to an opaque spawn attributes object that describes attributes to be applied during the spawn. If attrp is NULL, then the default attribute values are used. For more information, see the Attributes section, below.
argv
A pointer to an argument vector. The value in argv[0] should represent the filename of the program being loaded, but can be NULL if no arguments are being passed. The last member of argv must be NULL.

As a QNX Neutrino extension, the value of argv can be NULL. In this case, the behavior is exactly as if argv were a pointer to the two-element array:

  • {path, NULL} for posix_spawn()
  • {file, NULL} for posix_spawnp()
envp
A pointer to an array of character pointers, each pointing to a string defining an environment variable. The array is terminated with a NULL pointer. Each pointer points to a character string of the form:
variable=value
  

that's used to define an environment variable. If the value of envp is NULL, then the child process inherits the environment of the parent process.

If a variable appears more than once in the envp array, the behavior is undefined.

The _Restrict_arr attribute informs the compiler that the argv and envp pointers don't alias each other, and that the compiler is therefore free to perform certain optimizations that otherwise might not be legal.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The posix_spawn() and posix_spawnp() functions create a new process (child process) from the specified process image. The new process image is constructed from a regular executable file called the new process image file. The difference between these two functions is only in the means by which they specify the new process image file:

  • posix_spawn() takes an absolute path to the executable
  • posix_spawnp() performs a path search for the file

A running process has two sets of credentials of importance during its execution: the real user and group IDs (ruid and rgid respectively) and the effective user and group IDs (euid and egid respectively). Typically, when a new process (a child process) is spawned, both sets of credentials (real and effective) are taken from the spawning (parent) process. The exception to this is if the executable file being spawned has either its setuid and/or setgid mode bits set, in which case the euid is set to the uid of the executable, and/or the egid is set to the gid of the executable. POSIX doesn't define a way to directly specify the ruid and rgid of a spawned process. If you want to do this, call posix_spawnattr_setcred() —a QNX Neutrino extension—before spawning the child process.

The ability to do certain operations is controlled by procmgr_ability() :

The ability to: Is controlled by:
Spawn new processes PROCMGR_AID_SPAWN
Set the group ID of the child process PROCMGR_AID_SPAWN_SETGID
Set the user ID of the child process PROCMGR_AID_SPAWN_SETUID

When a C program is executed as the result of calling posix_spawn() or posix_spawnp(), it's entered as a C-language function call as follows:

int main(int argc, char *argv[]);

where argc is the argument count and argv is an array of character pointers to the arguments themselves.

In addition, the global environ variable is initialized as a pointer to an array of character pointers to the environment strings. The argument argv is an array of character pointers to NULL-terminated strings. The last member of this array is a NULL pointer and isn't counted in argc. These strings constitute the argument list available to the new process image. The value in argv[0] should point to a filename that's associated with the process image that you're starting.

The number of bytes available for the child process's combined argument and environment lists is {ARG_MAX}.

On successful completion, posix_spawn() and posix_spawnp() store the process ID of the child process in the variable pointed to by a non-NULL pid argument, and return zero as the function return value. Otherwise, no child process is created, the value stored in the variable pointed to by a non-NULL pid is unspecified, and the functions return an error number. If the pid argument is NULL, the process ID of the child isn't returned to the caller.

File actions

If file_actions is NULL, then the file descriptors that are open in the calling process remain open in the child process, except for those whose close-on-exec flag, FD_CLOEXEC, is set. For those file descriptors that remain open, all attributes of the corresponding open file descriptions, including file locks, remain unchanged. For more information about FD_CLOEXEC and file locks, see fcntl() .

If file_actions isn't NULL, then the file descriptors open in the child process are those open in the calling process as modified by the spawn file actions object pointed to by file_actions and the FD_CLOEXEC flag for each remaining open file descriptor after the spawn file actions have been processed. The effective order of processing the spawn file actions is:

  1. The set of open file descriptors for the child process is initially the same set as is open for the calling process. All attributes of the corresponding open file descriptions, including file locks, remain unchanged.
  2. The signal mask, signal default actions, and the effective user and group IDs for the child process are changed as specified in the attributes object referenced by attrp.
  3. The file actions specified by the spawn file actions object are performed in the order in which they were added to the spawn file actions object.
  4. Any file descriptor that has its FD_CLOEXEC flag set is closed.

To initialize a file actions object, call posix_spawn_file_actions_init() , and then:

Call: To specify a file descriptor that you want to:
posix_spawn_file_actions_addclose() Close
posix_spawn_file_actions_adddup2() Duplicate with dup2()
posix_spawn_file_actions_addopen() Open

To destroy the file actions object, call posix_spawn_file_actions_destroy() .

Attributes

The spawn attributes are defined in an opaque posix_spawnattr_t object. Use posix_spawnattr_init() to initialize the object, and posix_spawnattr_destroy() to destroy it.

In order to set an attribute, you must typically call the appropriate posix_spawnattr_*() function and set the corresponding flag.

You can do the following by using the attributes defined by POSIX. You can get and set the POSIX flags by calling the POSIX posix_spawnattr_getflags() and posix_spawnattr_setflags() routines, or the QNX Neutrino posix_spawnattr_getxflags() and posix_spawnattr_setxflags() routines.

If you want to: Then
Explicitly specify the process group for the child process Set the POSIX_SPAWN_SETPGROUP flag, and call posix_spawnattr_setpgroup() , specifying a nonzero process group ID.
Put the child in a new process group with a process group ID equal to its process ID Set the POSIX_SPAWN_SETPGROUP flag, and call posix_spawnattr_setpgroup() , specifying a process group ID of zero.
Make the child process inherit the parent's process group. Don't set the POSIX_SPAWN_SETPGROUP flag.
Set the initial signal mask of the child process Set POSIX_SPAWN_SETSIGMASK and call posix_spawnattr_setsigmask() , specifying the set of signals you want to mask
Set the actions for certain signals to the default action in the child process Set POSIX_SPAWN_SETSIGDEF and call posix_spawnattr_setsigdefault() , specifying the set of signals.

Signals set to the default action in the parent process are set to the default action in the child process.

Signals set to be caught by the calling process are set to the default action in the child process.

Except for SIGCHLD, signals set to be ignored by the calling process image are set to be ignored by the child process, unless otherwise specified by the POSIX_SPAWN_SETSIGDEF flag and the set of signals you specify with posix_spawnattr_setsigdefault().

If the SIGCHLD signal is set to be ignored by the calling process, it's unspecified whether the SIGCHLD signal is set to be ignored or to the default action in the child process, unless otherwise specified by the POSIX_SPAWN_SETSIGDEF flag and the set of signals you specify with posix_spawnattr_setsigdefault().

Make the child process use the same scheduling policy and parameters as the parent Set neither the POSIX_SPAWN_SETSCHEDULER nor the POSIX_SPAWN_SETSCHEDPARAM flag
Explicitly set the child process's scheduling policy and parameters Set the POSIX_SPAWN_SETSCHEDULER flag (in which case the setting of the POSIX_SPAWN_SETSCHEDPARAM flag doesn't matter), call posix_spawnattr_setschedpolicy() to specify the scheduling policy, and call posix_spawnattr_setschedparam() to specify the scheduling parameters.
Set the child process's scheduling parameters, but use the parent's scheduling policy Set the POSIX_SPAWN_SETSCHEDPARAM flag and call posix_spawnattr_setschedparam() to specify the scheduling parameters.
Make the child process inherit the parent's effective user and group IDs Don't set the POSIX_SPAWN_RESETIDS flag

If the setuid bit is set for the process image file, the child process's effective user ID becomes the file's owner ID before the process starts. Similarly, if the setgid bit is set for the process image file, the child process's effective group ID becomes the file's group ID before the process starts.

Reset the child process's effective user and group IDs to the parent's real user and group IDs, and make the child process inherit the parent's real (rather than the effective) user and group IDs. Set the POSIX_SPAWN_RESETIDS flag.

If the setuid bit is set for the process image file, the child process's effective user ID becomes the file's owner ID before the process starts. Similarly, if the setgid bit is set for the process image file, the child process's effective group ID becomes the file's group ID before the process starts.

You can do the following by using the attributes defined as extensions by QNX Neutrino. You can get and set the QNX Neutrino and POSIX flags by calling posix_spawnattr_getxflags() and posix_spawnattr_setxflags() . Both of these routines are QNX Neutrino extensions.

If you want to: Then
Make the child process ignore specific signals Set POSIX_SPAWN_SETSIGIGN and call posix_spawnattr_setsigignore() , specifying the signals you want to ignore
Restrict the CPUs that the child process can run on Set POSIX_SPAWN_EXPLICIT_CPU and call posix_spawnattr_setrunmask() , specifying the CPU affinity/runmask.

If you don't set flag, the child inherits the inherit mask of the calling thread.

Specify the user and group IDs for the child process Set POSIX_SPAWN_SETCRED and call posix_spawnattr_setcred() , specifying the IDs.
Set the maximum stack size for the child process Set POSIX_SPAWN_SETSTACKMAX and call posix_spawnattr_setstackmax() , specifying the stack size.

If you don't set POSIX_SPAWN_SETSTACKMAX, there's no maximum. You can retrieve the default value with a call to posix_spawnattr_getstackmax() using an initialized posix_spawnattr_t object.

Prevent the child process from becoming a zombie on its death Set POSIX_SPAWN_NOZOMBIE. No child return or exit information will be available.
Hold the child process for debugging purposes Set POSIX_SPAWN_HOLD
Use the system default settings for alignment Set POSIX_SPAWN_ALIGN_DEFAULT
Attempt to always fault data misalignment references Set POSIX_SPAWN_ALIGN_FAULT
Make the child process not fault on misalignment; attempt to fix it instead (this approach might be slow) Set POSIX_SPAWN_ALIGN_NOFAULT
Toggle the Address Space Layout Randomization bit. If the parent has ASLR, turn it off for the child; if the parent's bit is off, turn it on for the child. Set POSIX_SPAWN_ASLR_INVERT

If the value of the attrp pointer is NULL, then the default values are used.

All process attributes—other than those influenced by the spawn attributes or the file actions—appear in the new process image as though fork() had been called to create a child process, and then a member of the exec() family of functions had been called by the child process to execute the new process image.

It is implementation-defined whether the fork() handlers are run when posix_spawn() or posix_spawnp() is called.

Returns:

EOK
The child was successfully spawned.
EINVAL
An argument was invalid; the spawn attributes or file actions object is invalid, or the name of the process image file is NULL or an empty string.

If you specify an invalid value in the file actions or spawn attributes, posix_spawn() or posix_spawnp() might fail; if the value causes an error to occur after the child has been successfully spawned, the child process may exit with a status of 127.

EIO
An internal error occurred in the library.
ENOENT
  • For posix_spawn(), the executable specified by the path argument couldn't be found. The path must be the full path to the executable. Use posix_spawnp() if you want to search for the executable to spawn.
  • For posix_spawnp(), the executable specified by the file argument couldn't be found in any of the PATH environment variable locations.
ENOMEM
The memory required to create the message to send to procnto couldn't be allocated memory to create the new process and its associated data structures couldn't be allocated.
EPERM
The calling process doesn't have the required permission; see procmgr_ability() .
ETXTBSY
The text file that you're trying to execute is busy (e.g. it might be open for writing).

If posix_spawn() or posix_spawnp() fails for any of the reasons that would cause fork() or one of the exec() family of functions to fail, an error value is returned as described by fork() and exec(), respectively (or, if the error occurs after the calling process successfully returns, the child process exits with exit status 127).

If POSIX_SPAWN_SETPGROUP is set in the spawn-flags attribute of the object referenced by attrp, and posix_spawn() or posix_spawnp() fails while changing the child's process group, an error value is returned as described by setpgid() (or, if the error occurs after the calling process successfully returns, the child process exits with exit status 127).

If POSIX_SPAWN_SETSCHEDPARAM is set and POSIX_SPAWN_SETSCHEDULER isn't set in the spawn-flags attribute of the object referenced by attrp, then if posix_spawn() or posix_spawnp() fails for any of the reasons that would cause sched_setparam() to fail, an error value is returned as described by sched_setparam() (or, if the error occurs after the calling process successfully returns, the child process exits with exit status 127).

If POSIX_SPAWN_SETSCHEDULER is set in the spawn-flags attribute of the object referenced by attrp, and if posix_spawn() or posix_spawnp() fails for any of the reason that would cause sched_setscheduler() to fail, an error value is returned as described by sched_setscheduler() (or, if the error occurs after the calling process successfully returns, the child process exits with exit status 127).

If the file_actions argument isn't NULL, and specifies any close(), dup2(), or open() actions to be performed, and if posix_spawn() or posix_spawnp() fails for any of the reasons that would cause close(), dup2(), or open() to fail, an error value is returned as described by close(), dup2(), and open(), respectively (or, if the error occurs after the calling process successfully returns, the child process exits with exit status 127). An open() file action may, by itself, result in any of the errors described by close() or dup2(), in addition to those described by open()).

The posix_spawn() and posix_spawnp() functions can also return any error returned by a stat() on path.

Classification:

POSIX 1003.1 SPN

Safety:
Cancellation point No
Interrupt handler Yes
Signal handler Yes
Thread Yes