Unix环境高级编程习题3.2

来源:互联网 发布:casiofx991es矩阵求逆 编辑:程序博客网 时间:2024/05/05 11:14

  • 题目

        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);}


原创粉丝点击