UNIX环境高级编程习题之第三章第二题

不调用fcntl函数实现dup2函数


问题描述

dup2函数头定义为int dup2(int fd, int fd2),返回值为fd2指定的文件描述符,指向fd指向的文件,如果fd2已经打开,则需先关闭;如果fd == fd2,则无需关闭fd2。

解题思路

1、寻找需要的文件描述符
不能调用fcntl,那么我们只能调用dup函数,这个函数会返回当前可用的文件描述符中的最小值,循环n次调用直到返回值等于fd2。

2、调用dup的负面影响
这个时候我们打开了n-1个无用的文件,这些并不是我们需要或者预期的,返回前需关闭。否则不但会占用大量系统资源,使得系统无法打开新的文件,甚至这些预期之外的文件描述符也可以访问或者修改文件,形成安全隐患。

3、消除dup造成的隐患
线性结构记录n-1个文件描述符,并依次关闭

4、错误error处理
dup调用错误:包括指定的fd2过大,打开的文件描述符超出限制。在不考虑其他程序也调用此函数的情况下,我们可以通过sysconf函数来获取打开上限。

5、测试问题
定义一个文件描述符x指向标准输出,并通过x写入一段特定的字符,查看是否会在标准输出是打印,也可以直接重定向到指定文件查看。

代码实现

本文采用c语言实现该逻辑:

#include "apue.h"
#include <myerr.h>
#include <limits.h>
#include <unistd.h>
#include <errno.h>

#ifdef OPEN_MAX
static long openmax = OPEN_MAX;
#else
static long openmax = 0;
#endif

int mydup(int fd, int fd2){
    //获取系统允许的最大的文件数
    errno = 0;
    if (openmax == 0)
        openmax = sysconf(_SC_OPEN_MAX);
    if (openmax < 0){
        if (errno != 0){ //这个值是不确定的
            printf("OPEN_MAX这个值是不确定的,设为默认100\n");
            openmax = 100;
        }
        else{ //获取OPEN_MAX错误
            printf("获取OPEN_MAX错误,设为默认100\n");
            openmax = 100;
        }
    }else
        printf("OPEN_MAX获取成功,其值是%ld\n", openmax);

    //关闭指定的fd2文件
    errno = close(fd2);
    //关闭文件不一定会成功,因为有可能这个文件本身就没有打开,所以错误也不退出
    if (errno == -1) 
        printf("关闭fd2错误:%d",errno);

    //获取待返回的文件描述符fd1
    long fd1 = -1;
    int arr[openmax-1], idx = 0,i;
    for (i = 0; i < openmax - 1; i++){// 初始化线性结构
        arr[i] = -1;
    }
    do{//循环调用dup函数直至返回的fd1 == fd2
        fd1 = dup(fd);
        if (fd1 > 0){//调用成功
            if (fd1 == fd2){//如果调用成功,退出循环
                break;
            }else{
                arr[idx] = fd1;
                idx++;
            }
        }
    }while(fd1 < fd2);

    //关闭打开的多余的文件
    for (i = 0; i < openmax - 1; i++){
        if (arr[i] == -1)
            break;
        else{
            errno = close(arr[i]);
            if (errno == -1){
                printf("关闭文件%ld错误",arr[i],stdout);
                if (idx != i){
                    idx = i;
                    i--; //关闭失败回退再关闭一次
                }
            }
        }
    }

    return fd1;
}

int main(void){
    int fdtest = dup(1);
    char buf[] = "hello, mydup for dup2!\n";
    printf("打开的文件是:%d,buf长度是%d\n",fdtest,strlen(buf));
    int fd = mydup(STDOUT_FIFLNO,fdtest);
    printf("mydup返回的文件是:%d\n",fd);

    //测试返回的文件符是否可以直接操作标准输出
    if (write(fd, buf, strlen(buf)) != strlen(buf))
        err_sys("buf write error\n");

    exit(0);
}

在Linux环境下的运行结果如下:

打开的文件是:3,buf长度是23
OPEN_MAX获取成功,其值是102400
mydup返回的文件是:3
hello, mydup for dup2!

可见测试的buf成功通过获取的文件描述符写入到了标准输出中,至此测试完毕。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《UNIX环境高级编程(第3版)文版》是一本经典的UNIX编程工具书籍。本书由W. Richard Stevens与Stephen A. Rago合著,是UNIX系统编程领域的权威参考书。下面将从内容、特点和使用等方面进行简单介绍。 首先,本书内容系统全面,详细介绍了UNIX系统编程的各个方面。从主要的系统调用、文件I/O、进程控制、进程间通信、网络编程高级I/O、线程和信号处理等方面进行了详细讲解,适合各种层次的读者使用。同时,本书还包括了大量的示例代码和实践项目,让读者能够更好地理解和掌握UNIX编程。 其次,本书特点鲜明,准确简洁。作者通过深入浅出的实例和讲解方式,将复杂的UNIX编程概念和原理变得易于理解和实践。此外,本书还提供了大量的代码片段和实践案例,读者可以通过实际操作来加深对UNIX编程的理解和应用。 最后,本书使用方法简单易懂。无论是初学者还是有一定UNIX编程基础的读者,都能够通过本书快速上手。每章都有清晰的目录和章节划分,内容逻辑紧密,结构严谨。同时,每个章节还附有习题和答案,供读者巩固知识和进行自我测试。 总而言之,《UNIX环境高级编程(第3版)文版》是一本非常得推荐的UNIX编程指南。无论是对于想要深入了解UNIX系统编程的读者,还是对于需要掌握UNIX编程技巧的软件工程师或系统管理员来说,本书都是一本不可多得的经典教材。通过阅读本书,读者可以全面系统地了解UNIX编程的核心概念和原理,从而提升自己的UNIX编程能力。 ### 回答2: 《UNIX环境高级编程(第3版)文版》是由W. Richard Stevens和Stephen A. Rago合著的一本经典的UNIX编程指南,是UNIX环境编程的权威参考。 这本书主要分为两个部分。第一部分介绍了UNIX系统的基础知识,包括文件I/O、进程控制、信号处理、进程间通信、线程以及网络编程等。通过深入浅出的方式,读者可以了解UNIX系统的基本概念和机制,并学会如何在UNIX环境下开发高效可靠的程序。 第二部分则介绍了一些高级,如高级I/O、进程间通信的高级特性、线程编程高级技术等。这些高级不仅对于程序员来说非常有用,而且对于系统管理员和网络工程师也非常重要。通过学习这些高级,读者可以进一步提高UNIX编程的能力,写出更加复杂和强大的程序。 这本书的优点在于它详细而全面地介绍了UNIX环境下的编程技术,是一本循序渐进、易学易懂的教材。作者通过丰富的实例和清晰的解释,让读者能够迅速理解和掌握各种编程技术。此外,书还提供了大量的参考资料和实用技巧,读者可以通过这些资料和技巧提升编程的效率和质量。 总之,《UNIX环境高级编程(第3版)文版》是一本非常好的UNIX编程指南,无论是初学者还是有经验的程序员,都可以从受益匪浅。通过学习这本书,读者可以掌握UNIX环境下的高级编程技术,写出更加高效和可靠的程序。 ### 回答3: 《UNIX环境高级编程(第3版)文版》是一本广泛应用于UNIX系统开发的经典图书,全书内容详尽,深入浅出地介绍了UNIX系统编程的核心概念和技术。 这本书首先介绍了UNIX系统编程的基础知识,包括文件IO、进程控制、信号处理等。对于初学者来说,这些基础知识是掌握UNIX编程的基础,书给出了大量的例子和练习,帮助读者巩固理解。 随后,书深入讲解了UNIX系统编程高级,包括进程间通信(IPC)、线程、网络编程等。这些主都是实际开发经常遇到的问,作者通过清晰的讲解和实例,帮助读者理解并掌握相关的编程技巧。 此外,本书还介绍了UNIX系统编程的其他重要概念和工具,如信号量、共享内存、套接字等。这些内容是开发复杂UNIX应用所必备的知识,书给出了详细的技术说明和示例,方便读者理解和实践。 总之,这本书适合有一定编程基础,希望深入学习UNIX系统编程的开发者阅读。它不仅能够帮助读者掌握UNIX系统编程的核心概念和技术,还能够提供实用的编程实例和技巧,方便读者在实际开发灵活运用。无论是想成为一名UNIX系统开发专家,还是希望扩展自己的技能,在UNIX环境高级编程(第3版)文版这本书都能找到所需的知识和指导。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值