dup (system call)

In Unix-like operating systems, dup and dup2 system calls create a copy of a given file descriptor. This new descriptor actually does not behave like a copy, but like an alias of the old one.

C library POSIX definition

These dup and dup2 calls are standardized by the POSIX specification

int dup (int oldfd);
int dup2 (int oldfd, int newfd);

The former allocates the first available descriptor, just like open() behaves; an alternative way to duplicate a file descriptor to an unspecified place is the fcntl system call with F_DUPFD command.

The latter places a copy to a specified location (index), closing a file descriptor if it already exists.

Importance of dup2 for Unix shells

Unix shells use dup2 for input/output redirection. Along with pipe(), it is a tool on which Unix pipes rely.

The following example uses pipe() and dup() in order to connect two separate processes (program1 and program2) using Unix pipes:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/* function prototypes */
void die(const char*);
 
int main(int argc, char **argv) {
	int pdes[2];
	pid_t child;
 
	if(pipe(pdes) == -1)
		die("pipe()");
 
	child = fork();
	if(child == (pid_t)(-1))
        	die("fork()"); /* fork failed */
 
	if(child == (pid_t)0) {
        	/* child process */

        	close(1);       /* close stdout */
        	
        	if(dup(pdes[1]) == -1)
        		die("dup()");
        	
        	/* now stdout and pdes[1] are equivalent (dup returns lowest free descriptor) */

        	if((execlp("program1", "program1", "arg1", NULL)) == -1)
        		die("execlp()");

		_exit(EXIT_SUCCESS);
	} else {
        	/* parent process */

        	close(0);       /* close stdin */
        	
        	if(dup(pdes[0]) == -1)
        		die("dup()");

        	/* now stdin and pdes[0] are equivalent (dup returns lowest free descriptor) */

        	if((execlp("program2", "program2", "arg1", NULL)) == -1)
        		die("execlp()");

		exit(EXIT_SUCCESS);
	}
 
	return 0;
}

void die(const char *msg) {
	perror(msg);
	exit(EXIT_FAILURE);
}

Use in Perl language

Perl does not provide these system calls directly. But dup2 to redefine one of standard streams may be invoked via "pipe opens" technique, using the vertical bar character in the file path for the open() call. Namely,

open FILE, "| shell command"

performs pipe(), fork(), dup2(,STDIN) and then executes a specified command. Likewise,

open FILE, "shell command |"

performs pipe(), fork(), dup2(,STDOUT) and then executes a specified command.


See also

References

    This article is issued from Wikipedia - version of the Tuesday, May 12, 2015. The text is available under the Creative Commons Attribution/Share Alike but additional terms may apply for the media files.