打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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 {              //fd2是打开了的
if(fd == fd2){   // 如果fd == fd2,则返回fd2,而不关闭
return;
}
        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)) { //在循环中复制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) {     //直到复制的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);  
}  

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux系统编程 | 共享内存之mmap
linux下标准输入输出的重定向与恢复
UNIX环境编程学习笔记(5)
wav2pcm
Linux 下的 dup 和 dup2 函数简介
dup & dup2
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服