【Linux系统编程】文件描述符与重定向

news2025/3/10 18:36:15

  #include <unistd.h>

       int dup(int oldfd);
       int dup2(int oldfd, int newfd);

dup函数是让最低位没有被使用的文件描述符也指向oldfd这个文件描述符所指向的文件,成功返回最低那个没有被使用的文件描述符,失败返回-1。

dup2函数是让newfd这个文件描述符也指向oldfd这个文件描述符所指向的文件,如果newfd已经被使用了,那么就关闭它所指向的文件,让newfd指向oldfd指向的文件。成功返回newfd,失败返回-1。所以dup2就是进阶版的dup函数,因为可以指定重定向位置。

#include <fcntl.h>              /* Obtain O_* constant definitions */
#include <unistd.h>

       int dup3(int oldfd, int newfd, int flags);

dup3自然是dup2函数的进阶版了。他多了一个参数flags,那这个参数是用来干嘛的呢?

看一下这段解释:

dup3() 与 dup2() 相同,不同之处在于:

* 调用方可以通过在标志中指定O_CLOEXEC来强制为新文件描述符设置关闭执行标志。

* 如果 oldfd 等于 newfd,则 dup3() 失败并显示错误 EINVAL。

我们知道fork函数在被调用后,操作系统会通过fork来使用父进程的数据结构,环境变量以及代码生成一个全新的子进程,并且子进程也拥有fork函数,这就会导致子进程的fork也有返回值。而由于子进程和父进程拥有一样的进程地址空间,在读取fork函数的返回值时会访问同一虚拟地址,但对应访问了两个物理空间,这就导致fork函数返回值有两个值(发生了写时拷贝)。事实上,父进程fork函数返回的是子进程的pid,子进程的fork函数返回的是0。

当父进程使用fork函数时,操作系统会为子进程创建一个新的task_struct,新的页表,新的进程地址空间,页表和进程地址空间都是复制父进程的,实际上进程PCB也是很大程度上复制了一部分,其中就包括文件描述符表。这时候父子进程的资源基本上都是共享的。因为父子进程共享同一段物理空间同一段代码,而物理内存和虚拟地址之间需要用页表映射,当子进程对共享代码进行修改时会发生写时拷贝,所以接收fork函数返回值的变量有一样的虚拟地址但是值却不同。同理,子进程使用exec函数进行程序替换后,重新建立页表映射,重新开辟物理空间。

 

操作系统为了管理一个进程,当进程创建时会先为其创建一个task_struct结构体描述这个进程的信息,方便系统管理它。这个task_struct中有一个成员files_struct,files_struct中有一个成员struct file * fd_array(结构体指针数组),数组每一个元素都是指向一个file结构体的指针。这个结构体指针数组就是我们说的文件描述符表,文件描述符就是file结构体指针数组下标

file结构体是进程打开一个文件时,操作系统为文件创建的内核数据结构,其中包含文件标志,文件偏移位置,文件inode(在磁盘文件系统中,一个文件有一个唯一的inode),以此就可以对文件进行操作。这就是所说的文件表项

file结构体会有一个计数器,当多个文件描述符指向同一个文件时,只有所有文件描述符都被释放才这个file结构体才会被释放,否则它会一直保持在内核中。

在父子进程文件描述符表相同的前提下,当进行程序替换时,文件描述符会被释放,但是里面的数据却没有被释放,由于父进程中的文件描述符也指向了这个文件的原因,当子进程该文件描述符释放,对于file结构体来说也就是计数器减一的问题。也就是说还可以用原来的文件描述符(file指针依旧还在,只不过系统默认为这个位置空出来了)找到程序替换前被打开的文件并对其操作,这他妈不是非法操作了么。

可是我们既然已经进行程序替换了,并不需要操作原来的文件,所以我们需要关闭这些被打开的文件。但是你嘎嘎重定向了好多文件,一个一个关闭势必非常麻烦。所以使用O_CLOEXEC的flags标志,使得程序替换前自动关闭newfd,也就是关闭重定向。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IP代理安全吗?如何防止IP被限制访问?

你是否遇到过可以正常上网&#xff0c;但访问某个网站却被禁止&#xff1f;注册某个网站账号&#xff0c;却被封号&#xff1f;那都是因为IP出现问题&#xff01;您的IP地址透露很多关于您的信息&#xff0c;包括您的位置和互联网活动。 在本文中&#xff0c;我们将一起了解IP地…

第二章 进程与线程 二、进程的状态与转换

目录 一、进程的状态 1、创建态 2、就绪态 3、运行态 4、阻塞态 5、终止态 注意&#xff1a; 二、进程状态的转换 三、进程的组织 1、链接方式 2、索引方式 四、考点 一、进程的状态 1、创建态 &#xff08;1&#xff09;进程正在被创建时&#xff0c;它的状态是“…

排序算法-----希尔排序

目录 前言 希尔排序&#xff08;shell&#xff09; 排序原理 大致思路 示例 代码实现&#xff08;C语言&#xff09; 算法分析 时间复杂度 空间复杂度 稳定性 前言 前面我有一篇插入排序的详细的文章讲解&#xff08;链接&#xff1a;排序算法-----插入排序&#xff0…

⑧ 嵌套路由配置

这种就是路由嵌套 在index.js中加上三级页面 引入到二级导航里面 增加重定向配置 三级页面默认显示第一个页面信息 在这里插入图片描述

GNN动态顺序推荐Dynamic Graph Neural Networks for Sequential Recommendation

Dynamic Graph Neural Networks for Sequential Recommendation 文章目录 1. 背景2. 模型2.1 动态图构造2.2 子图采样2.3 动态图推荐网络2.3.1 消息传播机制2.3.2 Node updating 2.4 推荐和优化 1. 背景 协同过滤没有考虑用户商品交互的序列演变&#xff1b; 已经有一些RNN…

vue3项目中关于二进制导出(下载)txt ,适应于其他格式

<el-button type"info" click"exportClick" size"default">导出</el-button> 接口方法&#xff1a;getExportList import { tmUseDictApi } from //api/dict; const getExportList tmUseDictApi().getExportList //初始化数据 …

React 全栈体系(五)

第三章&#xff1a;React 应用(基于 React 脚手架) 一、使用 create-react-app 创建 react 应用 1. react 脚手架 xxx 脚手架: 用来帮助程序员快速创建一个基于 xxx 库的模板项目 包含了所有需要的配置&#xff08;语法检查、jsx 编译、devServer…&#xff09;下载好了所有…

【笔试强训选择题】Day42.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&#xff…

深入理解JVM虚拟机第四篇:一些常用的JVM虚拟机(一)

一&#xff1a;Sun Classic VM虚拟机 早在1996年Java1.0版本的时候&#xff0c;Sun公司发布了一款名为Sun classic VM的Java虚拟机&#xff0c;它同时也是世界上第一款商用Java虚拟机&#xff0c;JDK1.4时完全被淘汰。 现在hotspot内置了此虚拟机。 这款虚拟机内部只提供解释器…

深入了解接口测试:Postman 接口测试指南

在现代软件开发生命周期中&#xff0c;接口测试是一个至关重要的部分。使用 Postman 这一工具&#xff0c;可以轻松地进行 接口测试。以下是一份简单的使用教程&#xff0c;帮助你快速上手。 安装 Postman 首先&#xff0c;你需要在电脑上安装 Postman。你可以从官网上下载并…

玩转堆排序以及Topk问题——【数据结构】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 目录 堆排序 建堆 建堆的时间复杂度 Topk问题 学习了二叉树以及堆&#xff0c;今天我们来学习一下什么是堆排序以及经典二叉树问题——topk问题。 在学习开始我们先来回顾一下上篇博客中我们提到的堆&#xff0c;…

TypeScript函数详解

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 函数声明 函数表达式 可选参数和默认参数 剩余参数&#xff08;Rest Parameters&#xff09; this和箭头函数 …

chato.cn: 定制专属AI聊天助理机器人工具网站

【 产品介绍】 • 名称 chato.cn • 具体描述 chato.cn的核心功能是让用户能够输入一些知识或信息&#xff0c;让机器人学习和理解&#xff0c;然后与之进行对话&#xff0c;查看其回答的质量和逻辑性。还提供了多种语言、主题、风格和规则的选项&#xff0c;让用户能够根据自己…

天地图WMTS地图瓦片下载

最近在开发个人项目中遇到了这样一个问题&#xff0c;即&#xff1a;本地开发使用天地图在线地图服务&#xff0c;部署到线上时&#xff0c;突然想到——天地图提供的开放地图服务是需要申请秘钥key才能够使用的&#xff0c;而且需要连接外网&#xff0c;同时也是有访问次数限制…

八、MySql表的复合查询

文章目录 一、基本查询回顾二、多表查询&#xff08;一&#xff09;笛卡尔积的初步过滤&#xff08;二&#xff09;例子1.显示部门号为10的部门名&#xff0c;员工名和工资2.显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别 三、自连接&#xff08;一&#xff09;定…

基于SSM的校园快递一站式服务系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Consensus-AI论文搜索引擎 直接从论文中找答案

Consensus介绍 Consensus是一个人工智能AI论文搜索引擎&#xff0c;一个可以在科学论文中找到答案的搜索引擎&#xff0c;使用人工智能从数亿篇科学论文数据库中即时提取和聚合易于使用&#xff0c;搜索结果在几秒内即可完成&#xff0c;而且100%无广告。 截图 提示&#xf…

朋友圈大佬都去读研了,这份备考书单我码住了

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

Golang 单元测试合集整理,(我最常用 gomonkey)欢迎收藏

无论写什么样的语言&#xff0c;单元测试都是必不可少的&#xff0c;它可以极大的提高我们的代码质量&#xff0c;减少各种低级错误和 bug 无论你是一个靠谱合格的码农&#xff0c;还是一个优秀的程序员&#xff0c;单元测试都是咱们必须落实的一环 单元测试比较容易&#xf…

python:使用RESTful API(flask)调用python程序传递参数,实现Web端调用python程序

问题描述 现有一个用python写的程序&#xff08;或者是一个或几个的函数接口&#xff09;&#xff0c;需要在Web前端调用python写的函数。如果直接用前端java来调用会很不方便&#xff0c;而且会出现各种麻烦的问题&#xff0c;下面给出如何在web前端调用python的接口。 解决…