Linux- dup()系统调用

2023-09-21 15:40:08

dup()

dup()(duplicate)是一个UNIX系统调用,用于创建一个现有文件描述符的副本。这个新的文件描述符与原始文件描述符在许多方面是相同的:它们共享同一个文件表项,这意味着它们指向相同的文件、套接字或其他I/O通道,并共享相同的文件偏移量、访问权限等。

函数原型

dup()函数的原型如下:

#include <unistd.h>

int dup(int oldfd);

其中,oldfd是要复制的现有文件描述符。

返回值

成功时,返回新的文件描述符;失败时,返回-1。

具体行为

  1. 最小可用描述符dup()会返回当前可用的最小整数值作为新的文件描述符。
  2. 文件状态标志:新的文件描述符会有自己独立的一组文件状态标志(FD_CLOEXEC等),但它会共享所有其他的状态,包括文件偏移量和访问模式(读、写、读写)。
  3. 共享锁和其他状态:由于新旧文件描述符共享同一文件表项,所以文件锁、操作模式、文件偏移量等也是共享的。

示例

dup()经常用于重定向标准输入、输出和错误流。例如,在一个进程中,我们可能想把标准输出(通常是文件描述符1)重定向到一个文件。这可以通过以下步骤完成:

  1. 使用open()打开一个文件,获取其文件描述符。
  2. 使用dup()来复制这个文件描述符,并覆盖标准输出的文件描述符。

可以用close()dup()组合或者使用dup2()函数两种方式来操作。

方式一

使用close()dup()组合来进行I/O重定向是一种更底层和直接的方式。下面是一个简单的示例,演示如何将标准输出(文件描述符1)重定向到一个文件:

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    // 打开一个文件
    int fd = open("output.txt", O_WRONLY | O_CREAT, 0666);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    // 关闭标准输出(文件描述符1)
    close(1);

    // 使用dup复制fd,这将返回最低可用的文件描述符,即刚刚关闭的1
    int newfd = dup(fd);

    if (newfd < 0) {
        perror("dup");
        return 1;
    }

    // 此时,printf的输出将写入到"output.txt"
    printf("Hello, world!\n");

    // 关闭文件描述符
    close(fd);

    return 0;
}

这里的步骤如下:

  1. 使用open()打开一个文件,获取一个文件描述符fd
  2. 使用close(1)关闭标准输出(文件描述符1)。
  3. 使用dup(fd)复制fd到最低可用的文件描述符上,因为标准输出(文件描述符1)刚被关闭,所以dup()会返回1作为新的文件描述符。

现在,由于标准输出(文件描述符1)已经被重定向到output.txt,所有写入到标准输出的数据(例如,通过printf())都将被写入到该文件中。

这种方法的优点是它直接和明确,但缺点是需要确保在调用dup()之前正确地关闭了目标文件描述符。这通常不是问题,但在更复杂的程序中可能会导致错误或不一致的行为。因此,许多程序更倾向于使用dup2(),因为它提供了一个更为安全和一致的方式来进行文件描述符的复制和替换。

方式二

下面是一个简单的示例,展示如何用dup2()将标准输出重定向到一个文件:

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main() {
    // 打开一个文件
    int fd = open("output.txt", O_WRONLY | O_CREAT, 0666);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    // 将标准输出(文件描述符1)重定向到fd指向的文件
    if (dup2(fd, 1) < 0) {
        perror("dup2");
        return 1;
    }

    // 此时,printf的输出将写入到"output.txt"
    printf("Hello, world!\n");

    // 关闭文件描述符
    close(fd);

    return 0;
}

在这个示例中,dup2(fd, 1)调用会关闭标准输出(如果它还未被关闭)并复制fd,使其成为新的标准输出。因此,当调用printf()或其他写入到标准输出的函数时,输出会被写入到"output.txt"文件中。

这里,dup2()确保了新的文件描述符(在本例中是标准输出,文件描述符为1)指向与旧的文件描述符(在本例中是fd)相同的文件或其他资源。所以,它提供了一种方便的方式来实现I/O重定向。

更多推荐

操作系统备考学习 day5(2.2.5 - 2.3.1)

操作系统备考学习day5第二章进程与线程2.2处理机调度2.2.5调度算法先来先服务(FCFS)短作业优先(SJF)高响应比优先(HRRN)时间片轮转(RR)优先级调度算法多级反馈队列调度算法多级队列调度算法2.3同步与互斥2.3.1同步与互斥的基本概念第二章进程与线程2.2处理机调度2.2.5调度算法先来先服务(FC

网络安全日报 2023年09月21日

1、研究人员披露基于ERMAC木马的Hook家族银行木马https://research.nccgroup.com/2023/09/11/from-ermac-to-hook-investigating-the-technical-differences-between-two-android-malware-vari

卷积神经网络实现咖啡豆分类 - P7

🍨本文为🔗365天深度学习训练营中的学习记录博客🍖原作者:K同学啊|接辅导、项目定制🚀文章来源:K同学的学习圈子目录环境步骤环境设置包引用全局设备对象数据准备查看图像的信息制作数据集模型设计手动搭建的vgg16网络精简后的咖啡豆识别网络模型训练编写训练函数编写测试函数开始训练展示训练过程模型效果展示总结与心得体

四、二叉树-上(Binary tree)

文章目录一、算法核心思想二、算法模型(一)回溯1.[104.二叉树的最大深度](https://leetcode.cn/problems/maximum-depth-of-binary-tree/)(1)思路(2)代码(3)复杂度分析2.[144.二叉树的前序遍历](https://leetcode.cn/proble

基础组件(线程池、内存池、异步请求池、Mysql连接池)

文章目录1、概述2、线程池2、异步请求池3、内存池1、概述池化技术,减少了资源创建次数,提高了程序响应性能,特别是在高并发场景下,当程序7*24小时运行,创建资源可能会出现耗时较长和失败等问题,池化技术,主要是程序初始化之前创建多个可用连接,集中管理起来,后续直接使用,使用完并归还。2、线程池线程池主要解决问题:1、解

碳当量及相关指数

声明本文是学习GB-T713.1-2023承压设备用钢板和钢带第1部分:一般要求.而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们1范围本文件规定了承压设备用钢板和钢带的牌号表示方法、订货内容、尺寸、外形、重量、技术要求、检验规则、试验方法、包装、标志及质量证明书。本文件适用于锅炉、压力容器、压力管

ardupilot开发 --- 避障篇

避障的类型空中防碰撞ADSB,主要是防止与其他飞行器的碰撞;避障,防止与天花板地板障碍物的碰撞;实现避障必要的传感器ADSBreceiversRangefindersorProximitySensorsorRealsenseDepthCameraADSBhttps://ardupilot.org/copter/docs

基于微信小程序的语言课学习系统的设计与实现(源码+lw+部署文档+讲解等)

前言💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗👇🏻精彩专栏推荐订阅👇🏻2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选

PT@古典概型@等概率模型

文章目录abstract等可能概型(古典概型)🎈古典型概率公式基本性质导出性质例抽样方式放回抽样不放回抽样mmm次取求不放回和一次性取mmm个球例:取色球和古典概型古典概型经典问题放球问题两人同一天生日问题超几何分布概型整除取数问题抽签问题取最大号球问题@错位相减分组分配问题古典概型假设条件和实际推断原则其他古典概型

共享WiFi贴项目怎么实施与运营,微火为你提供高效解答!

共享WiFi贴是一项有前景的商业项目,不仅可以满足用户对网络的需求,还可以为创业者带来盈利的机会。那么,我们来看看如何有效地开展共享WiFi贴项目。最重要的是选择合适的位置。共享WiFi贴项目的成功与否很大程度上取决于位置选择。优先选择人流量较大、需求旺盛的地方,如商业区、写字楼、学校、咖啡馆等。通过深入了解目标用户群

LeetCode解法汇总2591. 将钱分给最多的儿童

目录链接:力扣编程题-解法汇总_分享+记录-CSDN博客GitHub同步刷题项目:https://github.com/September26/java-algorithms原题链接:力扣(LeetCode)官网-全球极客挚爱的技术成长平台描述:给你一个整数money,表示你总共有的钱数(单位为美元)和另一个整数chi

热文推荐