Linux C dup和dup2函数详解

 

一、dup函数介绍

      系统调用dup()创建文件描述符oldfd的一个副本,使用编号最低的未使用描述符作为新描述符。

      成功返回后,新旧文件描述符可以互换使用。它们引用相同的打开文件描述,因此共享文件偏移量和文件状态标志;

      例如,如果在其中一个描述符上使用lseek(2)修改文件偏移量,则另一个描述符的偏移量也会更改。

      这两个描述符不共享文件描述符标志(exec关闭标志)。重复描述符的close on exec标志(FD_CLOEXEC;

      请参见fcntl(2))已关闭。

二、头文件和函数定义

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

 代码示例:

   

#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#define MAX_BUF_LEN 1024

int main()
{
    int oldfd = open("tmp.txt", O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
    if(oldfd < 0)
    {
        printf("Open failed!\n");
        return -1;
    }

    int fd2 = dup(oldfd);
    if(fd2 < 0 )
    {
        close(oldfd);
        printf("dup() failed!\n");
        return -1;
    }

    char buf[MAX_BUF_LEN];
    int bytes;
    /* 将标准输入写入buf,这里的0表示的是标准输入描述符,<unistd.h> 定义是 STDIN_FILENO */
    while((bytes = read(0, buf, MAX_BUF_LEN - 1)) > 0)
    {
        if (buf[0] == 'q') {
            break;
        }
        printf("read bytes = %d\n", bytes);
        /* 将buf中数据写入fd2,实际写入oldfd */
        if(write(fd2, buf, bytes) < bytes)
        {
            printf("Write failed!\n");
            return 0;
        }
        memset(buf, 0, MAX_BUF_LEN);
    }

    if (close(fd2) != 0) {
        printf("close fd2 error!\n");
    }
    if (close(oldfd) != 0) {
        printf("close oldfd error!\n");
    }
    return 0;
}

三.dup2函数介绍

        dup2()系统调用执行与dup()相同的任务,但它不使用编号最低的未使用文件描述符,而是使用newfd中指定的描述符编号。如果描述符newfd以前是打开的,那么它在被重用之前是静默关闭的。

关闭和重用文件描述符newfd的步骤是以原子方式执行的。这一点很重要,因为尝试使用close(2)和dup()实现等效功能会受到竞争条件的影响,因此newfd可能会在两个步骤之间重用。这种重用可能是因为主程序被分配文件描述符的信号处理程序中断,或者是因为并行线程分配了文件描述符。

注意以下几点:

  1. 如果oldfd不是有效的文件描述符,则调用失败,newfd未关闭。
  2. 如果oldfd是有效的文件描述符,并且newfd的值与oldfd相同,那么dup2()不执行任何操作,并返回newfd。

代码示例:

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

int main()
{
    int oldfd;
    int fd;

    char *buf;
    if((oldfd = open("ifconfig.txt", O_RDWR | O_CREAT, 0644)) == -1) {
        printf("open error\n");
        exit(-1);
    }
    fd = dup2(oldfd, fileno(stdout));
    if(fd == -1)
    {
        printf("dup2 error\n");
        return -1;
    }

    system("ifconfig");

    if (close(oldfd) != 0) {
        printf("close oldfd error!\n");
        return -1;
    }

    if (close(fd) != 0) {
        printf("close fd error!\n");
        return -1;
    }
    return 0;
}

  system函数执行过程中,将标准输出重定向到oldfd中,程序执行完会生成ifconfig.txt文件,内容如下:

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值