dup and dup2

用dup2可以修改任何文件描述符到任何实际文件,dup可以复制一个新的描述符到实际文件,以下是APUE(Advanced Programming in the Unix Environment)里关于他们的描述,后面还有一个小程序是实际修改STDOUT的,呵呵。

dup and dup2 Functions

An existing file descriptor is duplicated by either of the following functions.

 

#include <unistd.h>

int dup(int filedes);

int dup2(int filedes, int filedes2);

 

Both return: new file descriptor if OK, 1 on error


The new file descriptor returned by dup is guaranteed to be the lowest-numbered available file descriptor. With dup2, we specify the value of the new descriptor with the filedes2 argument. If filedes2 is already open, it is first closed. If filedes equals filedes2, then dup2 returns filedes2 without closing it.

The new file descriptor that is returned as the value of the functions shares the same file table entry as the filedes argument. We show this in Figure 3.8.

 

Figure 3.8. Kernel data structures after dup(1)

 

 

 


In this figure, we're assuming that when it's started, the process executes

    newfd = dup(1);

We assume that the next available descriptor is 3 (which it probably is, since 0, 1, and 2 are opened by the shell). Because both descriptors point to the same file table entry, they share the same file status flagsread, write, append, and so onand the same current file offset.

Each descriptor has its own set of file descriptor flags. As we describe in the next section, the close-on-exec file descriptor flag for the new descriptor is always cleared by the dup functions.

Another way to duplicate a descriptor is with the fcntl function, which we describe in Section 3.14. Indeed, the call

    dup(filedes);

is equivalent to

    fcntl(filedes, F_DUPFD, 0);

Similarly, the call

    dup2(filedes, filedes2);

is equivalent to

    close(filedes2);
    fcntl(filedes, F_DUPFD, filedes2);

In this last case, the dup2 is not exactly the same as a close followed by an fcntl. The differences are as follows.

  1. dup2 is an atomic operation, whereas the alternate form involves two function calls. It is possible in the latter case to have a signal catcher called between the close and the fcntl that could modify the file descriptors. (We describe signals in Chapter 10.)

  2. There are some errno differences between dup2 and fcntl.

    The dup2 system call originated with Version 7 and propagated through the BSD releases. The fcntl method for duplicating file descriptors appeared with System III and continued with System V. SVR3.2 picked up the dup2 function, and 4.2BSD picked up the fcntl function and the F_DUPFD functionality. POSIX.1 requires both dup2 and the F_DUPFD feature of fcntl.

 

 以下是代码,不是偶写的哦,出了问题不要怪偶。。。。

 

 

#include <unistd.h>;

                                                                                                                                              
int main(void)
{
        FILE *fp;
        int fd, id;
                                                                                                                                              
        id = dup(STDOUT_FILENO);//这时id和STDOUT_FILENO一起指向stdout
        if ((fp = fopen("install.log", "w")) == NULL) {
                perror("read error./n");
                exit(-1);
        }
        fd = fileno(fp);//得到fp的文件描述符
        dup2(fd, STDOUT_FILENO);//STDOUT_FILENO和stdout流断开,             //STDOUT_FILENO指向fd的对应文件,这样使输出到达fd的文件
                                //fd对应的是已经打开的文件install.log,//而stdout在这里指的是终端,现在任何的输入都输入到
                                //install.log中
        printf("hello/n");
                                                                                                                                              
        fflush(stdout);//刷新stdout上的缓冲区,这样前面的hello写入文件//install.log中
        dup2(id, STDOUT_FILENO);
        printf("world/n");
        fclose(fp);
                                                                                                                                              
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值