Linux系统编程18-dup和dup2.md

dup

在Linux中,dup函数用于复制一个文件描述符。具体而言,dup函数会复制参数fd所指向的文件描述符,并返回一个新的文件描述符,新的文件描述符和原文件描述符指向同一个文件表项,也就是说,它们共享同一文件偏移量和文件状态标志等信息。新的文件描述符和原文件描述符的值可能不同。

#include <unistd.h>

int dup(int oldfd);
    作用: 复制一个新的文件描述符,指向同一个文件,
			从空闲的文件描述符表中找一个最小的作为新文件描述符
    参数:
        - oldfd 旧的文件描述符
    返回:
        新描述符
        -1 错误

实例: 复制一个文件描述符,并且为所指向的文件写入数据

dup.c

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    int fd = open("dup.txt", O_RDWR | O_CREAT, 0664);
    int fd1 = dup(fd);
    if (fd == -1)
    {
        perror("dup err");
        return -1;
    }
    printf("fd : %d, fd1 : %d\n", fd, fd1);
    close(fd);
    char *str = "hello world";
    int ret = write(fd1, str, strlen(str));
    if (ret == -1)
    {
        perror("write err");
        return -1;
    }
    close(fd1);

    return 0;
}

需要注意的是,由于dup函数返回的新文件描述符和原文件描述符共享同一文件表项,因此在使用完这两个文件描述符后,需要分别将它们关闭,否则可能导致文件描述符泄漏。

dup2

#include <unistd.h>
int dup2(int oldfd, int newfd);
    作用: 重定向文件描述符
        例如 oldfd 指向 a.txt, newfd 指向 b.txt
        调用函数成功后, newfd 的 b.txt 做 close, newfd指向了a.txt;
        oldfd 必须是一个有效的文件描述符
        如果 oldfd 和 newfd 值相同,相当于什么都没有做
    返回: 与newfd相同的新文件描述符

其中 oldfd 是需要被复制的文件描述符,newfd 是新的文件描述符,它与 oldfd 共享同一个文件表项。如果 newfd 之前已经打开了,则 dup2 会先关闭 newfd,再将 oldfd 复制到 newfd,使得 newfdoldfd 指向同一个文件表项。

实例:

dup2.c

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    //创建dup2.txt
    int fd = open("dup2.txt", O_RDWR | O_CREAT, 0664);
    if (fd == -1)
    {
        perror("open err");
        return -1;
    }
	//创建dup3.txt
    int fd1 = open("dup3.txt", O_RDWR | O_CREAT, 0664);
    if (fd1 == -1)
    {
        perror("open err");
        return -1;
    }
    printf("fd : %d, fd1 : %d\n", fd, fd1);

    // fd1不再指向dup3.txt, 而是指向和fd的同一个文件dup2.txt
    int fd2 = dup2(fd, fd1);
    if (fd2 == -1)
    {
        perror("dup2 err");
        return -1;
    }

    //通过fd1 去写数据
    char *str = "hello, dup2";
    int len = write(fd1, str, strlen(str));
    if (len == -1)
    {
        perror("write err");
        return -1;
    }

    printf("fd : %d, fd1 : %d, fd2 : %d\n", fd, fd1, fd2);
    // fd : 3, fd1 : 4
    // fd : 3, fd1 : 4, fd2 : 4
    close(fd);
    close(fd1);

    return 0;
}
posted @ 2022-10-14 22:15  言叶以上  阅读(104)  评论(0编辑  收藏  举报