免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3807 | 回复: 17
打印 上一主题 下一主题

<<APUE>>--Exercises 3.2 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-05-18 20:40 |只看该作者 |倒序浏览
3.2
Write your own function called dup2 that performs the same service as
the dup2 function we described in section 3.12,without calling the
fcntl function. Be sure to handle errors correctly.


  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <unistd.h>
  4. int
  5. my_dup2(int oldd,int newd)
  6. {
  7.     int fd;
  8.     if(oldd==newd){
  9.         return (-1==(fd=dup(oldd)))?-1:close(fd),oldd;
  10.     }else{
  11.         if( (-1==lseek(newd,0,SEEK_CUR)) && (errno==EBADF) ){
  12.             close(newd);
  13.         }
  14.         if(newd != (fd=dup(oldd))){
  15.             if(fd ==  -1){
  16.                 return -1;
  17.             }else{
  18.                 int fd1;
  19.                 if(newd != (fd1=my_dup2(oldd,newd))){
  20.                     close(fd1);
  21.                 }
  22.             }
  23.         }
  24.     }
  25.     return fd;
  26. }


  27. int
  28. main(void)
  29. {
  30.     int fd;
  31.     if(-1==(fd=my_dup2(1,5))){
  32.         perror("5555555");
  33.         exit(-1);
  34.     }
  35.     write(5,"hahahahahahahaha",17);

  36.     exit(0);
  37. }
复制代码




请问这样写的my_dup2有问题吗?

[ 本帖最后由 雨丝风片 于 2006-5-21 09:03 编辑 ]

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
2 [报告]
发表于 2006-05-18 21:33 |只看该作者
我没有看这个练习,不过,题目允许可以用dup吗?
另外,好像逻辑有错吧?如果my_dup2(10,5)可以运行吗?

论坛徽章:
0
3 [报告]
发表于 2006-05-18 22:03 |只看该作者
原帖由 gvim 于 2006-5-18 21:33 发表
我没有看这个练习,不过,题目允许可以用dup吗?
另外,好像逻辑有错吧?如果my_dup2(10,5)可以运行吗?



题目只不允许fcntl,没不让dup


my_dup2(10,5)将会在这 if( (-1==lseek(newd,0,SEEK_CUR)) && (errno==EBADF) ){
里退出返回-1
perror输出Bad file descriptor


我也觉得逻辑很差,思路还没理顺过来,我再想几天看看

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
4 [报告]
发表于 2006-05-18 22:06 |只看该作者
呵。 你是怎么试验的?
你首先要有fd=10啊。

论坛徽章:
0
5 [报告]
发表于 2006-05-18 22:12 |只看该作者
我写了段这个,输出了字串  @.@


  1. 28
  2.      29 int
  3.      30 main(void)
  4.      31 {
  5.      32     int fd;
  6.      33     if(-1 == (fd=dup2(2,10))){
  7.      34         perror("error");
  8.      35         exit(-1);
  9.      36     }
  10.      37     if(-1==(fd=my_dup2(fd,5))){
  11.      38         perror("5555555");
  12.      39         exit(-1);
  13.      40     }
  14.      41     write(5,"hahahahahahahaha",17);
  15.      42
  16.      43     exit(0);
  17.      44 }
复制代码

论坛徽章:
0
6 [报告]
发表于 2006-05-19 08:51 |只看该作者
还要用递归?你再看看dup2的要求和dup的特性,在纸上画画图,理一理思路。

另外,如果你能够确定你的程序的合法值范围,那就应该适时地给出错误信息并终止程序,而不应该让它(至少从代码本身来看有可能)继续运行下去。

论坛徽章:
0
7 [报告]
发表于 2006-05-19 11:03 |只看该作者
这是网上的一种写法,检验old fd,没有用lseek,直接dup,然后检查返回值
  1. int dup2(int oldd, int newd) {
  2.         int fd;

  3.         /*
  4.          * First of all, check the parameters.
  5.          */
  6.         if(oldd < 0 || newd < 0) {
  7.                 errno = EBADF;
  8.                 return -1;
  9.         }

  10.         /*
  11.          * Duplicate the file descriptor.
  12.          */
  13.         fd = dup(oldd);
  14.         if(fd == -1)
  15.                 return -1;

  16.         if(fd == newd)
  17.                 return 0; /* Plain luck */

  18.         /*
  19.          * If the new fd is larger then the newd,
  20.          * it means that by closing the newd we
  21.          * guarantee that the new dup() will open
  22.          * it with the newd index.
  23.          */
  24.         if(fd > newd) {
  25.                 close(fd);
  26.                 close(newfd);
  27.                 fd = dup(oldd);
  28.                 assert(fd == newfd); /* reasonable */
  29.                 return fd;
  30.         }

  31.         /*
  32.          * Do it recursively.
  33.          */
  34.         newd = dup2(oldd, newd);
  35.         close(fd);
  36.         return newd;
  37. }
复制代码

论坛徽章:
0
8 [报告]
发表于 2006-05-19 14:01 |只看该作者
果然清晰:)

那不要递归是不是还要找个空间存放dup出来的fd,最后再close就行了?

论坛徽章:
0
9 [报告]
发表于 2006-05-20 08:17 |只看该作者
原帖由 balabalacha 于 2006-5-19 14:01 发表
果然清晰:)

那不要递归是不是还要找个空间存放dup出来的fd,最后再close就行了?


俺很少使用递归算法,不过这道题确实用递归比较简练一些。

论坛徽章:
0
10 [报告]
发表于 2006-05-20 09:36 |只看该作者


我看了一下dup2.c是调用fcntl的,而fcntl是_fcntl的,
里面好似.........看木懂  --.--

  1. case F_DUPFD:
  2.                         /*
  3.                          * Get the file descriptor that the caller wants to
  4.                          * use:
  5.                          */
  6.                         oldfd = va_arg(ap, int);

  7.                         /* Initialise the file descriptor table entry: */
  8.                         if ((ret = __sys_fcntl(fd, cmd, oldfd)) < 0) {
  9.                         }
  10.                         /* Initialise the file descriptor table entry: */
  11.                         else if (_thread_fd_table_init(ret) != 0) {
  12.                                 /* Quietly close the file: */
  13.                                 __sys_close(ret);

  14.                                 /* Reset the file descriptor: */
  15.                                 ret = -1;
  16.                         } else {
  17.                                 /*
  18.                                  * Save the file open flags so that they can
  19.                                  * be checked later:
  20.                                  */
  21.                                 _thread_fd_setflags(ret,
  22.                                     _thread_fd_getflags(fd));
  23.                         }
  24.                         break;

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP