dup2的函数定义为:

#include <unistd.h>

int dup2(int src_fd, int new_fd);

自己实现dup2函数有几个关键点:

1,检查给定的源fd是否有效,且都大于0,

2,检查目标fd是否超出了系统设定的范围,而这个值在书上是没有着重指出的,

  比如mac限制了要小于256,ubuntu限制是1024。

3,源fd与目标fd是否相等,

4,利用系统的特性:dup总是返回最小可用的fd,不断重复dup,从而得到一个等于new_fd的fd值

  再清除掉new_fd之前的临时fd

5,如果在4)的过程中。如果中途dup失败。则需要在返回失败前,关掉这些临时的fd。

  因此close这些临时fd时,需要区别是创建new_fd成功还是失败了。

下面是代码,仅限于类Unix系统环境:

 /*
* name : dup2.c
* func : implement of dup2 without fcntl.h
* author : jungle85gopy
* date : 2015.12.20
*/ /*
* Note :
* man dup() of Mac OSX
* Dup() duplicates an existing object descriptor and returns
* its value to the calling process (fildes2 = dup(fildes)).
* The value must be less than the size of the table, which is returned by
* getdtablesize(2). the size is 256 for Mac OSX 10.11.
* man dup() in ubuntu, there is no info about getdtablesize(2).
* but Ubuntu 14.04 still has getdtablesize limit of 1024.
*/ #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h> #define INIT_FD -2 int my_dup2(int src_fd, int new_fd);
int chk_dup(int src_fd, int new_fd);
int do_dup2(int src_fd, int new_fd); /*
* usage: dup2 src_fd, new_fd
*/
int main(int argc, char *argv[])
{
if (argc != ) {
printf("usage: dup2 src_fd new_fd\n");
exit();
} int new_fd = new_fd = my_dup2(atoi(argv[]), atoi(argv[]) );
if (new_fd == -) {
printf("dup to new_fd error!\n");
exit();
}
printf("\n[main]: new fd is %d\n", new_fd);
return new_fd;
} /*
* func: check the parameter of my_dup2
* return:
* -1: if error
* 0 : if success
*/
int chk_dup(int src_fd, int new_fd)
{
int tbl_size = getdtablesize(); printf("[my_dup2]: parameter : src fd %d\n", src_fd);
printf("[my_dup2]: parameter : new fd %d\n\n", new_fd); if (src_fd < || new_fd < ) {
printf("[my_dup2]: error: src or des parameter < 0.\n");
return -;
}
else if (new_fd >= tbl_size ) {
printf("[my_dup2]: error: des_fd out of system limit: %d\n", tbl_size);
return -;
} int index;
if ( (index = dup(src_fd)) == -) {
printf("[my_dup2]: parameter src_fd is inactive!\n");
return -;
} else
close(index); return ;
} /*
* func: dup a file descriptor from src_fd to new_fd
* return:
* new_fd if success
* -1 if error
*/
int my_dup2(int src_fd, int new_fd)
{
int ret; if ( (ret = chk_dup(src_fd, new_fd)) == -)
return -;
if (src_fd == new_fd)
return src_fd; // close new_fd, whether it is valid or not. ignore the return
close(new_fd); if ( (ret = do_dup2(src_fd, new_fd)) == -) {
printf("[my_dup2]: do dup failed!\n");
return -;
} else
return ret;
} /*
* func: dup from 0 to new_fd
*/
int do_dup2(int src_fd, int new_fd)
{
int index, index_hit = -, fd_array[new_fd]; for (index = ; index <= new_fd; index++)
fd_array[index] = INIT_FD; // initial to INIT_FD printf("[my_dup2]: before dup temp fds\n");
for (index = ; index <= new_fd; index++) {
fd_array[index] = dup(src_fd);
printf("[my_dup2]: index: %d, create temp fd: %d\n", index, fd_array[index]); if (fd_array[index] == -) {
printf("[my_dup2]: dup process error!\n");
break;
} else if (fd_array[index] == new_fd) {
index_hit = index;
break;
}
} // close temp fd
printf("\n[my_dup2]: to close temp fds\n"); if (index_hit == -) { // break for loops with error
for (index = ; index < new_fd; index++) {
if ((fd_array[index] == INIT_FD) || (fd_array[index] == -))
break; // no new temp dup in array
else {
close(fd_array[index]);
printf("[my_dup2]: index: %d, del temp fd: %d\n", index, fd_array[index]);
}
}
return -;
} else { // break for loops with hit
for (index = ; index < index_hit; index++) {
close(fd_array[index]);
printf("[my_dup2]: index: %d, temp fd: %d\n", index, fd_array[index]);
}
}
return new_fd;
}

[APUE]不用fcntl实现dup2函数功能的更多相关文章

  1. UNIX环境高级编程APUE练习3.2-不用fcntl实现dup2的功能

    1 题面 编写与dup2功能相同的函数,要求不调用fcntl函数,并且要有正确的出错处理. 2 基本思路 不能用fcntl,能够返回一个文件描述符的只有open和dup.而open会创建一个新的文件表 ...

  2. 第3章 文件I/O(4)_dup、dup2、fcntl和ioctl函数

    5. 其它I/O系统调用 (1)dup和dup2函数 头文件 #include<unistd.h> 函数 int dup(int oldfd); int dup2(int oldfd, i ...

  3. APUE中fcntl.h的使用及O_SYNC在Mac与Ubuntu下的测试

    此部分测试涉及到APUE V3中,第三章的图3-12到图3-14. 通过fcntl.h提供的功能,修改fd的文件属性,本处增加O_SYNC功能,并测试其效果. 本文涉及代码: tree ch3 ch3 ...

  4. linux之dup和dup2函数解析

    1. 文件描述符在内核中数据结构在具体说dup/dup2之前,我认为有必要先了解一下文件描述符在内核中的形态.一个进程在此存在期间,会有一些文件被打开,从而会返回一些文件描述符,从shell中运行一个 ...

  5. dup和dup2函数

    下面两个函数都可用来复制一个现存的文件描述符: #include<unistd.h> int dup(int filedes); int dup2(int filedes,int file ...

  6. dup和dup2函数以及管道的实现

    疑问:管道应该不是这样实现的,因为这要求修改程序的代码 dup和dup2也是两个非常有用的调用,它们的作用都是用来复制一个文件的描述符.它们经常用来重定向进程的stdin.stdout和stderr. ...

  7. dup,dup2函数【转】

    转自:http://eriol.iteye.com/blog/1180624 转自:http://www.cnblogs.com/jht/archive/2006/04/04/366086.html ...

  8. 2-3 Sass的函数功能-列表函数

    列表函数主要包括一些对列表参数的函数使用,主要包括以下几种: length($list):返回一个列表的长度值: nth($list, $n):返回一个列表中指定的某个标签值 join($list1, ...

  9. Unix 网络编程 dup和dup2函数

    dup和dup2也是两个很实用的调用,它们的作用都是用来复制一个文件的描写叙述符. 它们经经常使用来重定向进程的stdin.stdout和stderr.这两个函数的原形例如以下: #include & ...

随机推荐

  1. 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文

    阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...

  2. 为C# as 类型转换及Assembly.LoadFrom埋坑!

    背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...

  3. URL安全的Base64编码

    Base64编码可用于在HTTP环境下传递较长的标识信息.在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式.此时,采用Base64编码不仅比较简短,同时也具有不可 ...

  4. iOS热更新-8种实现方式

    一.JSPatch 热更新时,从服务器拉去js脚本.理论上可以修改和新建所有的模块,但是不建议这样做. 建议 用来做紧急的小需求和 修复严重的线上bug. 二.lua脚本 比如: wax.热更新时,从 ...

  5. [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform

    eclipse maven clean install 报错 1. 修改properties-->resource-->utf-8仍然报错 2.修改项目pom.xml文件,增加: < ...

  6. EC笔记:第4部分:22、所有成员都应该是private的

    EC笔记:第4部分:22.所有成员都应该是private的 更简单的访问 用户不用记得什么时候该带上括号,什么时候不用带上括号(因为很确定的就要带上括号) 访问限制 对于public的成员变量,我们可 ...

  7. Javascript高性能编程-提高Dom访问速度

    在浏览器中对于Dom的操作和普通的脚本的操作处于两个不同的dll中,两个dll的交互是比较耗时的,优化对Dom的操作可以提高脚本的执行速度.下面是对如何优化的一些总结: 将需要多次操作的节点存储在一个 ...

  8. 2016/12/30_Python

    今天主要学习内容: Python: 1.字典的使用 1)怎么创建字典 dicts = {"name":"juncx","age":17} d ...

  9. [计算机网络]简易http server程序

    好久没输出了,知识还是要写下总结才能让思路更加清晰.最近在学习计算机网络相关的知识,来聊聊如何编写一个建议的HTTP服务器. 这个http server的实现源代码我放在了我的github上,有兴趣的 ...

  10. Lesson 24 It could be worse

    Text I entered the hotel manager's office and sat down. I had just lost £50 and I felt very upset. ' ...