[转]unix/linux中的dup()系统调用
[转]unix/linux中的dup()系统调用 在linux纷繁复杂的内核代码中,sys_dup()的代码也许称得上是最简单的之一了,但是就是这么一个简单的系统调用,却成就了unix/linux系统最著名的一个特性:输入/输出重定向。
sys_dup()的主要工作就是用来“复制”一个打开的文件号,使两个文件号都指向同一个文件。既然说简单,我们就首先来看一下它的代码(定义在fs/fcntl.c中):
而sys_dup()的主体是dupfd()(定义在同一个文件中):
注:dup和dup2的原型如下:
#include <unistd.h>
int dup(int file_descriptor);
int dup2(int file_descriptor1, int file_descriptor2)
dup返回的文件描述符总是取最小的可用值
dup2返回的文件描述符或者与file_descriptor2相同,或者是第一个大于该参数的可用值。
而这么一个简单的系统调用是如何完成重定向这个艰巨的任务的呢?我们不妨先看个例子。
当我们在shell下输入如下命令:“echo
hello!”,这条命令要求shell进程执行一个可执行文件echo,参数为“hello!”。当shell接收到命令之后,先找到
bin/echo,然后fork()出一个子进程让他执行bin/echo,并将参数传递给它,而这个进程从shell继承了三个标准文件,即标准输入
(stdin),标准输出(stdout)和标准出错信息(stderr),他们三个的文件号分别为0、1、2。而至于echo进程的工作很简单,就是将参数“hello!”写到标准输出文件中去,通常都是我们的显示器上。但是如果我们将命令改成“echo hello! >
foo”,则在执行时输出将会被重定向到磁盘文件foo中(注:重定向于文件描述符有关)。我们假定在此之前该shell进程只有三个标准文件打开,文件号分别为0、1、2,以上命令行将按如下序列执行:
(1) 打开或创建磁盘文件foo,如果foo中原来有内容,则清除原来内容,其文件号为3。
(2) 通过dup()复制文件stdout,即将文件号1出的file结构指针复制到文件号4处,目的是将stdout的file指针暂时保存一下
(3) 关闭stdout,即1号文件,但是由于4号文件对stdout也同时有个引用,所以stdout文件并未真正关闭,只是腾出1号文件号位置。
(4) 通过dup(),复制3号文件(即磁盘文件foo),由于1号文件关闭,其位置空缺,故3号文件被复制到1号,即进程中原来指向stdout的指针指向了foo。
(5)
通过系统调用fork()和exec()创建子进程并执行echo,子进程在执行echo前夕关闭3号和4号文件,只留下0、1、2三个文件,请注意,这
时的1号文件已经不是stdout而是磁盘文件foo了。当echo想向stdout文件写入“hello!”时自然就写入到了foo中。
(6) 回到shell后,关闭指向foo的1号与3号文件文件,再用dup()和close()将2号恢复至stdout,这样shell就恢复了0、1、2三个标准输入/输出文件。
由此可见,当echo程序(或其他)在运行的时候并不知道stdout(对于stdin和stderr同样)指向什么,进程与实际输出文件或设备的结合是在运行时由其父进程“包办”的。这样就简化了子进程的程序设计,因为在设计时只要跟三个逻辑上存在的文件打交道就可以了。可能有人会觉得这很像面向对象中
的多态和重载,没有什么新奇之处,但是如果你活在30甚至40年前,可能你会改变你的看法。
[转]unix/linux中的dup()系统调用的更多相关文章
- linux中的dup()系统调用
参考1:http://www.blogjava.net/lihao336/archive/2011/12/13/366231.html 在linux纷繁复杂的内核代码中,sys_dup()的代码也许称 ...
- 如何设置UNIX/Linux中新创建目录或文件的默认权限
在unix或者linux中,每创建一个文件或者目录时,这个文件或者目录都具有一个默认的权限,比如目录755,文件644,那么这些默认权限是怎么控制的呢? 答案是"umask"权限掩 ...
- unix/linux中图形界面那些事
我们知道unix/linux刚开始的时候是没有图形界面的,随着时代的发展,排版.制图.多媒体应用越来越普遍了,这些需求都需要用到图形界面(Graphical User Interface).为此,MI ...
- Unix/Linux中的grep命令(转)
本文转载自:如何使用Unix/Linux grep命令——磨刀不误砍柴工系列.该博文条理很清晰. grep简介 grep在一个或多个文件中查找与模式字符串(pattern)匹配的行,并将搜索的结果打印 ...
- Unix/Linux中/usr目录的由来
在Linux系统中,有一个很重要的目录——/usr目录.关于这个目录名称的由来,网上主要有下面几种说法: user的缩写 User Shareable Read-only的缩写 Unix/User S ...
- Unix/Linux中shell调用sqlplus的方式
Unix/Linux下,shell脚本调用sqlplus的几种方式介绍: 一.最简单的shell调用sqlplus #!/bin/bash sqlplus -S /nolog > sqlplus ...
- Unix/Linux中的read和write函数
文件描述符 对于内核而言,所有打开的文件都通过文件描述符引用.文件描述符是一个非负整数.当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符.当读或写一个文件时,使用open或creat ...
- Unix/Linux中的fork函数
fork函数介绍 一个现有进程可以调用fork函数创建一个新进程.该函数定义如下: #include <unistd.h> pid_t fork(void); // 返回:若成功则在子进程 ...
- Unix/Linux中Cron的用法
cron是unix或者linux下用来定时任务的命令,大致的用法如下: 1.服务的启动和关闭 /sbin/service crond start //启动服务 /sbin/service cr ...
随机推荐
- 决策树遇到sklearn.exceptions.NotFittedError: XXX instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.的解决方案
1.异常信息: C:\Python36\python36.exe "E:/python_project/ImoocDataAnalysisMiningModeling/第6章 挖掘建模/6- ...
- (最全)Xpath、Beautiful Soup、Pyquery三种解析库解析html 功能概括
一.Xpath 解析 xpath:是一种在XMl.html文档中查找信息的语言,利用了lxml库对HTML解析获取数据. Xpath常用规则: nodename :选取此节点的所有子节点 // : ...
- vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据
在vue项目中组件间相互传值或者后台获取的数据需要供多个组件使用的情况很多的话,有必要考虑引入vuex来管理这些凌乱的状态,今天这边博文用来记录这一整个的过程,后台api接口是使用webpack-se ...
- Postgresql 连接更新
update dbo.m_role_fun a set role_code = b.rsc from (select rsc, fun_code from dbo.m_fun) b where a.f ...
- MyEclipse部署web项目的关键
我自己的经验: 主要有3点: 自己的代码要正确 数据库服务确保已经启动 确保你的访问路径是正确的 1.自己的代码要正确 比如jdbc驱动,正确的写法:private static final Stri ...
- 使用StackPanel进行简单地布局
尽管StackPanel非常简单,但是其实用性也非常强 ,Stackpanel将子元素以堆叠的形式 排列在一行或一列.通常建议使用该控件对于一些小范围内的控件进行布局. 如果要架设用户控件的框架结构, ...
- 【SSH网上商城项目实战04】EasyUI菜单的实现
转自:https://blog.csdn.net/eson_15/article/details/51297705 上一节我们使用EasyUI搭建了后台页面的框架,这一节我们主要使用EasyUI技术简 ...
- hdu2044 一只小蜜蜂
和之前的楼梯题一样,递推求解 但是要注意这里可以到50,结果已经超出了Int的范围,所以要用64位保存 #include<iostream> #include<cmath> # ...
- Web安全相关(四):过多发布(Over Posting)
简介 过多发布的内容相对比较简单,因此,我只打算把原文中的一些关键信息翻译一下.原文链接如下: http://www.asp.net/mvc/overview/getting-started/gett ...
- thinkphp点击导航变色
1.从该处进入导航页面,点击分贝进入点击的页面. 2.点击1处进入对应的导航栏,导航栏变色. 3.在1图图片点击跳转是给地址添加参数status. 4.在后台IndexController.class ...