Create a new process
Synopsis:
#include <sys/types.h>
#include <unistd.h>
pid_t fork( void );
This function is declared in <process.h>, which <unistd.h>
includes.
Library:
libc
Use the -l c option to
qcc
to link against this library.
This library is usually included automatically.
Description:
The fork() function creates a new process.
The new process (child process) is an exact copy of the
calling process (parent process), except for the following:
- The child process has a unique process ID.
- The child process has a different parent process ID (which is
the process ID of the calling process).
- The child process has its own copy of the parent's file
descriptors. Each of the child's file descriptors refers to
the same open file description with the corresponding file
descriptor of the parent.
- The child process has its own copy of the parent's open directory
streams.
- The child process's values of tms_utime, tms_stime,
tms_cutime, and tms_cstime are set to zero.
- The child process has a single thread, regardless of the number that the parent process has.
- File locks previously set by the parent aren't inherited by the child.
- The child process doesn't inherit any timers, QNX Neutrino
message-passing objects, side channel connections (coids), or channels (chids).
- The set of signals pending for the child process is initialized
to the empty set.
- The child process doesn't inherit any memory locks that the parent
set.
For more information, see
"Locking memory"
in the Process Manager chapter of the System Architecture guide.
Note that:
- A named semaphore
(sem_open())
increments and decrements the same count in the parent and the child,
but an unnamed semaphore
(sem_init())
increments and decrements a different count (with the same initial value)
in the parent and child, unless that unnamed semaphore is in a shared memory object.
- The child inherits any message queue descriptors from the parent, whether you're using the traditional
(mqueue)
or alternate
(mq)
implementation of message queues.
- The parent's ability configuration (see
procmgr_ability())
is copied to the child verbatim,
regardless of the PROCMGR_AOP_INHERIT_NO status of each of
the abilities.
In order to successfully call this function, your process must have the
PROCMGR_AID_FORK ability enabled.
For more information, see
procmgr_ability().
You can use
pthread_atfork()
to register fork handler functions to be called before or after the fork occurs.
Note:
POSIX requires that the child process use only functions that are async-signal-safe
until it calls one of the
exec*() functions.
If your program uses mutexes, you might need to register a
pthread_atfork() handler
that locks all the mutexes before you fork.
For more information, see
"Using fork() in a multithreaded process"
in the
"Processes and Threads" chapter of
Getting Started with QNX Neutrino.
Returns:
A value of zero to the child process, and the process ID of the child process to the parent process.
Both processes continue to execute from the fork() function.
If an error occurs, fork() returns -1 to the parent and sets
errno.
Errors:
- EAGAIN
- Insufficient resources are available to create the child process.
For example, you might have exceeded the maximum number of processes
permitted; see the RLIMIT_NPROC resource for
getrlimit().
- EBADF
- A problem occurred when fork() was duplicating a file descriptor.
For example, another thread might have opened or closed a file descriptor while the
fork() was occurring.
You can add synchronization around the operations that involve file descriptors,
or try calling fork() again.
- ENOMEM
- The process requires more memory than the system is able to supply.
- ENOSYS
- The fork() function isn't implemented for this memory protection model.
- EPERM
- The calling process doesn't have the required permission; see
procmgr_ability().
Examples:
This program demonstrates forking.
You run it like this:
fork_example program [arguments]
The child runs program (passing it the arguments, if any),
and the parent waits for the child to exit.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main( int argc, char **argv )
{
pid_t pid;
pid_t wpid;
int status;
if (argc == 1) {
printf ("Usage: %s <program> [<arguments>]\n", argv[0]);
return EXIT_FAILURE;
}
if( ( pid = fork() ) == -1 ) {
perror( "fork" );
return EXIT_FAILURE;
}
if( pid == 0 ) {
printf ("Child: My pid is %d.\n", getpid() );
/* Use exec to become the specified program. */
execvp( argv[1], argv+1 );
/* This can happen only if execvp() fails; print a message, and then exit. */
perror( argv[1] );
return EXIT_FAILURE;
} else {
printf ("Parent: My pid is %d.\n", getpid() );
/* Wait for the child to finish. */
do {
wpid = waitpid( pid, &status, 0 );
} while( WIFEXITED( status ) == 0 );
printf ("Parent: Child %d has exited with status %d; we're done!\n",
wpid, WEXITSTATUS( status ));
return WEXITSTATUS( status );
}
}
Classification:
POSIX 1003.1
Safety: |
|
Cancellation point |
No |
Interrupt handler |
No |
Signal handler |
Yes |
Thread |
Read the Caveats |
Caveats
It's possible to call fork() from a multithreaded process, but it can be very difficult
to do so safely, so we recommend that you call it only from single-threaded processes.
For more information, see
"Using fork() in a multithreaded process"
in the "Processes and Threads" chapter of Getting Started with QNX Neutrino.