[Previous]
[Contents]
[Next]

qnx_spawn()

create a new process

Synopsis:

#include <process.h>
#include <sys/sched.h>
#include <sys/qnx_glob.h>
pid_t qnx_spawn( int exec,
                 struct _proc_spawn *msgbuf,
                 nid_t node,
                 int priority, 
                 int scheduler, 
                 int flags,
                 char *cmd, 
                 char *argv[], 
                 char *envp[],
                 char iov[],
                 int ctfd );

Description:

The qnx_spawn() function is the lowest level function for creating a new process other than by forking. You may create a new child process (spawn) or transform into the new process yourself (exec). This function is called by all the exec... and spawn... functions.


Note: The normal spawn... and exec... functions don't provide arguments for node, and so on. The qnx_spawn_options structure sets defaults that these functions use when calling qnx_spawn().

The arguments are as follows:

exec
This argument indicates whether or not a child process is to be created.

If exec is zero, a new child process is created, and the function returns the process ID of the child after it's loaded; the child may or may not have started execution. You may elect to wait on its death by calling wait() or waitpid(). If the child fails to load, -1 is returned and errno is set.

If exec is 1, the current process attempts to transform itself into the new process. You may not exec to another node. If the exec succeeds, there's no return value, since the process is replaced by a new process. If it fails, -1 is returned.

If the _FD_CLOSE_ON_EXEC flag is set on any open file, that file is closed in the new process.

msgbuf
You may pass a msgbuf to build the create message, or pass a zero and have the function call malloc() to get one of the required size. In this case, the buffer is released before the function returns. If you provide your own buffer, its size must be at least the sum of:
node
If node isn't equal to zero, the child is created on the indicated node, otherwise it is created on the local node.
priority
If priority is -1, the priority of the current process is used.
scheduler
If scheduler is -1, the scheduler of the current process is used. For other values, see qnx_scheduler().
flags
The following flags arguments are defined for the flags option:
_SPAWN_BGROUND
The process is started with SIGINT and SIGQUIT ignored.
_SPAWN_HOLD
The process is started in the STOPPED state. The high-level debugger (wd) uses this flag to hold the process until it can get control to plant breakpoints.
_SPAWN_NOHUP
The process is started with SIGHUP ignored.
_SPAWN_NEWPGRP
The new process starts a new process group. It is as though the new process did a qnx_setpgrp() just before its execution began.
_SPAWN_SIGCLR
The process doesn't inherit ignored signals from its parent. This is done just before _SPAWN_BGROUND and _SPAWN_NOHUP.
_SPAWN_TCSETPGRP
The new process starts a new terminal group. ALL keyboard breaks are directed at it. Should the new process die, breaks will NOT revert back to the current owner (typically the shell). It must issue a tcsetpgrp(), which the shell does for all nonbackground processes it runs. It is as though the new process called tcsetpgrp() just before its execution began.
_SPAWN_NOZOMBIE
When the new process terminates it won't become a zombie waiting for its parent to do a wait on its death. The parent (you) won't see the process die, and a SIGCHLD won't be set. If you don't wish to wait on your children, you should set this flag to prevent clogging up the system with zombie children that have died.

If you specify _SPAWN_NOZOMBIE and start a child on a remote node, qnx_spawn() returns 0, not the child's process ID.

_SPAWN_SETSID
The new process starts a new session. It's as though the new process called setsid() just before its execution began. It's unusual for an application program to start its own session. New sessions are typically started by the tinit utility when it brings up logins.
_SPAWN_XCACHE
Instruct the file system to place the executable in cache, in hope that it will be loaded again soon. Normally Fsys only caches executables that are less than 1/8 of its cache in size.
cmd
The new program to be executed.
Note: If the new process is a shell script, the first line must start with #!, followed by the path and arguments of the shell to be run to interpret the script. The script must also be marked as executable.

argv
Arguments to the new program are pointed to by the array of strings argv. This array is terminated by a NULL.
envp
The new process's environment is pointed to by the array of strings envp. This array is NULL-terminated. The value of envp cannot be NULL, but envp[0] can be a NULL pointer, if no environment strings are passed.
iov
This parameter should contain 10 chars that contain file descriptors to use for stdin, stdout, stderr, ... fd 9. If you wish to use the existing values (which is usually the case) you must pass -1 for each value in the array.

For example, if you placed a 5 in iov[0], the new process would have its file descriptor 0 (stdin) replaced by file descriptor 5 of the calling process. If you don't wish file descriptor 5 to be inherited, you should set its CLOSE_ON_EXEC flag using the fcntl() function. If you pass a NULL for iov, no redirection occurs (equivalent to passing -1 for all 10 file descriptors in iov). If an iov[] entry is specifically redirected, the CLOSE_ON_EXEC flag is ignored.

ctfd
The controlling terminal file descriptor. This parameter is only meaningful if the _SPAWN_SETSID flag is set in flags. In this case the terminal associated with this file descriptor becomes the controlling terminal for the newly created session. If you wish to start a new session without a controlling terminal, ctfd should be passed as -1.

Returns:

The process ID of the new process on success. On error, a -1 is returned, and errno is set.


Note:
  • If exec is 1, and the exec succeeds, this function never returns, since its process will have been replaced.
  • If you specify _SPAWN_NOZOMBIE in the flags argument and start a child on a remote node, qnx_spawn() returns 0 instead of the child's process ID.

Errors:

E2BIG
The sum of the bytes used by the new process image's argument list and environment list is too big.
EACCES
You don't have permissions to execute the program.
EAGAIN
No free process entry or local memory in the process manager to manage the new process.
EINVAL
The priority of the new process or the scheduling policy is invalid.
EIO
Input/output error. The loader is unable to get the resources needed to load the executable.
ENAMETOOLONG
The length of the cmd after being expanded to a fullpath exceeds PATH_MAX.
ENOENT
The file doesn't exist.
ENOEXEC
The load file isn't in the correct format.
ENOLIC
Insufficient licenses to use this function.
ENOMEM
Insufficient system memory to load the new process.
ENONDP
The program needs an 80x87, and neither it nor the emulator is installed.
ETXTBUSY
Load module is being written to.

Examples:

/*
 * The following program executes a command, specified
 * by argv[2]..argv[n], on the node specified by
 * argv[1].  The program exits without waiting for
 * command completion.
 * use:  this_cmd node_number cmd arg1 arg2 ...
 * example: this_cmd 0 /bin/tsk
 */

#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <sys/qnx_glob.h>


int main( int argc, char **argv, char **arge )
  {
    nid_t nodeid;
    pid_t pid;
    int status;

    nodeid = strtol( argv[1], NULL, 0 );
    pid = qnx_spawn( 
        0,       /*  create a new process */
        NULL,    /* let it alloc buffer */
        nodeid,  /* run on this node */
        -1,      /* inherit current priority */
        -1,      /* inherit current scheduler */
        0,       /* nothing fancy */
        argv[2], /* this is the command */
        argv+2,  /* the command and its args */
        arge,    /* pass along this environ   */
        NULL,    /* default: inherit all fds */
        -1
      );

    if( pid == -1 )
      {
      perror( argv[2] );
      exit( EXIT_FAILURE );
      }
    else {
      wait( &status );
      printf( "Exit status was %d.\n", status );
      }

    exit( EXIT_SUCCESS );
  }

Classification:

QNX

Safety:
Interrupt handler No
Signal handler No
Thread No

See also:

errno, exec... functions, fork(), qnx_scheduler(), qnx_spawn_options, spawn... functions, wait(), waitpid()


[Previous]
[Contents]
[Next]