Unix 网络编程 dup和dup2函数

dup和dup2也是两个很实用的调用,它们的做用都是用来复制一个文件的描写叙述符。数据结构

它们经常常使用来重定向进程的stdin、stdout和stderr。这两个函数的原形例如如下:app

#include <unistd.h>
int dup( int oldfd );
int dup2( int oldfd, int targetfd );

dup()函数:

利用函数dup。咱们可以复制一个描写叙述符。

传给该函数一个既有的描写叙述符,它就会返回一个新的描写叙述符,这个新的描写叙述符是传给它的描写叙述符的拷贝。这意味着,这两个描写叙述符共享同一个数据结构。好比,假设咱们对一个文件描写叙述符运行lseek操做,获得的第一个文件的位置和第二个是同样的。如下是用来讲明dup函数用法的代码片断:
函数

int fd1, fd2;
...
fd2 = dup( fd1 );

需要注意的是,咱们可以在调用fork以前创建一个描写叙述符。这与调用dup创建描写叙述符的效果是同样的。子进程也相同会收到一个复制出来的描写叙述符。



dup2()函数:

dup2函数跟dup函数类似,但dup2函数赞成调用者规定一个有效描写叙述符和目标描写叙述符的id。dup2函数成功返回时,目标描写叙述符(dup2函数的第二个參数)将变成源描写叙述符(dup2函数的第一个參数)的复制品,换句话说,两个文件描写叙述符现在都指向同一个文件,并且是函数第一个參数指向的文件。如下咱们用一段代码加以说明:
spa

 int oldfd;
 oldfd = open("app_log", (O_RDWR | O_CREATE), 0644 );
 dup2( oldfd, 1 );
 close( oldfd );

在本例中,咱们打开了一个新文件,称为“app_log”,并收到一个文件描写叙述符,该描写叙述符叫作fd1。咱们调用dup2函数。參数为oldfd和1,这会致使用咱们新打开的文件描写叙述符替换掉由1表明的文件描写叙述符(即stdout,因为标准输出文件的id为1)。不论什么写到stdout的东西,现在都将改成写入名为“app_log”的文件里。需要注意的是,dup2函数在复制了oldfd以后,会立刻将其关闭,但不会关掉新近打开的文件描写叙述符,因为文件描写叙述符1现在也指向它。



如下咱们介绍一个更加深刻的演示样例代码。回顾一下命令行管道,咱们可以将ls –l命令的标准输出做为标准输入链接到wc –l命令。接下来。咱们就用一个C程序来加以说明这个过程的实现。代码例如如下所看到的。命令行


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

int main()
{
    int pfds[2];

    if ( fork() == 0 ) {

        close(1);
        dup2( pfds[1], 1 );
        close( pfds[0] );
        execlp( "ls", "ls", "-l", NULL );

    } else {

        close(0);
        dup2( pfds[0], 0 );
        close( pfds[1] );
        execlp( "wc", "wc", "-l", NULL );

    }

    return 0;
}

在演示样例代码中,首先创建一个管道,而后将应用程序分红两个进程:一个子进程和一个父进程。接下来,在子进程中首先关闭stdout描写叙述符(第13行)。而后提供了ls –l命令功能。只是它不是写到stdout,而是写到咱们创建的管道的输出端。这是经过dup2函数来完毕重定向的。使用dup2 函数把stdout重定向到管道(pfds[1])。

以后,当即关掉管道的输入端。而后,使用execlp函数把子进程的映像替换为命令ls –l的进程映像,一旦该命令运行,它的不论什么输出都将发给管道的输入端。

现在来研究一下管道的接收端。从代码中可以看出,管道的接收端是由父进程来担当的。首先关闭stdin描写叙述符,因为咱们不会从机器的键盘等标准设备文件来接收数据的输入,而是从其余程序的输出中接收数据。code

而后,再一次用到dup2函数。让管道的输入端做为输入,这是经过让文件描写叙述符0(即常规的stdin)重定向到pfds[0]实现的。关闭管道的stdout端(pfds[1]),因为在这里用不到它。最后,使用 execlp函数把父进程的映像替换为命令wc -l的进程映像,命令wc -l把管道的内容做为它的输入。blog

相关文章
相关标签/搜索