【UNIX-高级环境编程 3.2】不使用 fcntl 实现 dup2

反复调用 dup 直到返回的 fd 为新设置的 fd (dup 总是返回当前可用的最小的 fd)

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

#define MAXFD (sysconf(_SC_OPEN_MAX) - 1)

#define VALID 1
#define INVALID 0

int dup2(int fd1, int fd2) {
    if(fd1 < 0 || fd1 > MAXFD || fd2 < 0 || fd2 > MAXFD) {
        errno = EBADF;
        return -1;
    }

    int fd;
    int* dup2_opened_fd = (int*)calloc(fd2 + 1, sizeof(int));

    // check fd1 is valid
    if((fd = dup(fd1)) == -1)
        goto clear_unused_fd;
    else
        dup2_opened_fd[fd] = VALID;

    if(fd1 == fd2)
        fd = fd2;

    // loop to call dup(fd1), when return is equal fd2
    while(fd != fd2) {
        if((fd = dup(fd1)) == -1)
            goto clear_unused_fd;

        dup2_opened_fd[fd] = VALID;
    }

    int i;
clear_unused_fd:
    for(i=0; i<fd2; ++i)
        if(dup2_opened_fd[i] == VALID)
            close(i);
    free(dup2_opened_fd);

    if(fd == fd2)
        return fd2;

    return -1;
}

 

上一篇:Linux异步通讯


下一篇:Linux下快速拷贝单个大文件的秘诀