Unix环境高级编程习题3.2

  • 题目

        3.2 Write your own dup2 function that performs the same service as the dup2 function described in Section 3.12, without calling the fcntl function. Be sure to handle errors correctly.(实现自己的dup2函数,不能使用fcntl函数,注意处理错误值。)

  • 函数原型
        int dup2(int filedes, int filedes2);
  • 函数功能
        makes filedes2 be the copy of filedes, closing newfd first if necessary.(复制filedes到filedes2,若filedes2打开,则先关闭)
  • 思路
        要判断filedes2是否存在,可以使用dup函数,判断返回值。若ok或者,返回-1时的错误值不为EBADF,则表明filedes2是打开的。
  • 我的解
        参见如下代码。测试环境(cygwin)

#include <apue.h>

// excise 3.2 by fred yu
// implementation your own dup2 function without using fcntl.
int my_dup2(int fd, int fd2)
{
    int tmpfd = -1, i, lastfd;
    int * fds;

    if (fd2 < 0
#ifdef OPEN_MAX
            || fd2 > OPEN_MAX
#endif
       ) {
        errno = EBADF;
        printf("my_dup2, %d] fd2 is not a valid number.\n", __LINE__);
        return -1;
    }

    tmpfd = dup(fd2);
    if (tmpfd == -1) {
        switch (errno) {
            case EBADF:
                // fd2 is not opened.
                break;
            case EMFILE:
                if (close(fd2) == -1) {
                    printf("my_dup2, %d] close fd2 failed.\n", __LINE__);
                    return -1;
                }
                break;
            default:
                printf("my_dup2, %d] dup fd2 failed.\n", __LINE__);
                return -1;
        }
    } else {
        if (close(tmpfd) == -1) {
            printf("my_dup2, %d] close tmpfd failed.\n", __LINE__);
            return -1;
        }
        if (close(fd2) == -1) {
            printf("my_dup2, %d] close fd2 failed.\n", __LINE__);
            return -1;
        }
    }

    fds = (int *)malloc(fd2 * sizeof(int));
    if (!fds) {
        printf("my_dup2, %d] malloc fds failed.\n", __LINE__);
        errno = ENOMEM;
        return -1;
    }

    for (i = 0; i < fd2; ++i) {
        fds[i] = -1;
    }

    lastfd = -1;
    while (tmpfd = dup(fd)) {
        if (tmpfd == -1) {
            printf("my_dup2, %d] dup fd failed, fd=%d, lastfd=%d, err=%d.\n", __LINE__, fd, lastfd, errno);
            goto FAIL_EXIT;
        } else if (tmpfd == fd2) {
            break;
        } else {
            fds[tmpfd] = tmpfd;
            lastfd = tmpfd;
        }
    }
    
    for (i = 0; i < fd2; ++i) {
        if (fds[i] != -1) close(fds[i]);
    }

    free(fds);
    return fd2;

FAIL_EXIT:
    for (i = 0; i < fd2; ++i) {
        if (fds[i] != -1) close(fds[i]);
    }
    free(fds);
    return -1;
}

int test_my_dup2(int argc, char * argv[])
{
    int fd;

    if (argc < 3) {
        printf("usage: excise oldfd newfd\n");
        return 0;
    }

    fd = my_dup2(atoi(argv[1]), atoi(argv[2]));
    if (fd == -1) {
        printf("dup2 fd failed\n");
        return -1;
    }
    printf("return fd by my_dup2 is %d", fd);

    return 0;
}

int main(int argc, char * argv[])
{
    test_my_dup2(argc, argv);
    exit(0);
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值