Declaration:
#include <unistd.h> int dup2(int filedes, int filedes2); /* returns new file descriptor if ok, -1 on error */
dup2()
causes the file descriptor filedes2
to reference
the same file as filedes
. If filedes2
is already open,
it is first closed. If filedes
= filedes2
,
then dup2
returns filedes2
without closing it
The following lines of code are taken from Program 14.2 on p.432 of Stevens.
They demonstrate how to redirect stdin
using dup2
:
... if (fd[0] != STDIN_FILENO) { if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { /* error message & die */ } close(fd[0]); /* don't need this after dup2 */ } ...
The check, if (fd[0] != STDIN_FILENO)
, is
good programming practice and should be used whenever dup2
is used
in combination with close
. Stevens offers a good explanation:
When we duplicate a descriptor onto another (fd[0]
onto
standard input in the child), we have to be careful that the descriptor
doesn't already have the desired value. If the descriptor already had the
desired value and we called dup2
and close
, the
single copy of the descriptor would be closed.
All varieties of exec()
system call perform the same function:
they transform the calling process by loading a new program into its
address space. If the exec()
is successful the calling program
is completely overlaid (replaced) by the new program, which is then started
from its beginning. The process ID does not change across an exec()
.
As a note of interest, the shell itself invokes commands by using one of the exec commands.
exec()
is commonly used with fork()
. The
fork
function creates a new process (the child) that then
causes another program to be executed by calling one of the exec
functions.
The declarations of the 6 different flavours of exec()
:
#include <unistd.h> int execl (const char *pathname, const char *arg0, ... ... /* (char *) 0 */ ); int execv (const char *pathname, char *const argv[]); int execle(const char *pathname, const char *arg0, ... ... /* (char *) 0, char *const envp[] */ ); int execve(const char *pathname, char *const argv[], char *const envp[]); int execlp(const char *filename, const char *arg0, ... ... /* (char *) 0 */ ); int execvp(const char *filename, char *const argv[]); /* All six return: -1 on error, no return on success */
The initial argument for these functions is the pathname of a file which is to be executed
The const char *arg
and subsequent ellipses in the
execl
, execlp
, and execle
functions can be thought of as arg0
, arg1
, ...,
argn
. Together
they describe a list of one or more
pointers to null-terminated strings that represent the argument list
available to the executed program. The first argument, by convention,
should point to the file name associated with the file being executed.
The list of arguments must be terminated by a NULL pointer.
The execv
and execvp
functions provide
an array of pointers to null-terminated strings that represent the
argument list available to the new program. The first argument,
by convention, should point to the file name associated with the
file being executed. The array of pointers must be terminated by a NULL pointer.
The letters in the functions names help identify the expected arguments:
References