关于文件描述符复制函数dup2的疑问

时间:2022-01-30 10:00:14
  我在APUE里学到了dup2这个函数。
  然后试着编写了一个复制描述符的函数。目的是想知道四个描述符指向同一个文件表项的情况。
 

源代码如下:

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#define BUF 4096
#define  RWXRWXRWX (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH)

int main()
{
        int n;
        int fd0;
        int fd1;
        int fd2;
        int fd3;
        char buf[BUF];
        fd0=open("demo111",O_RDWR|O_CREAT,RWXRWXRWX);
        printf("before fd0=%d\n",fd0);
        dup2(fd0,fd1);
        dup2(fd0,fd2);
        dup2(fd0,fd3);
        printf("fd0=%d\n",fd0);
        printf("fd1=%d\n",fd1);
        printf("fd2=%d\n",fd2);
   }

然而运行的结果是

before fd0=3
fd0=3
fd1=134513552
fd2=134514027
fd3=2625524
 
使用dup2(int oldfields,int newoldfields)函数后,不是应该fd0 fd1 fd2 fd3都一样指向头一个文件描述符么?

另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???

15 个解决方案

#1


不是指向同一个文件描述符,是指向同一个文件表项。
没关闭啊。

#2


?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数

#3


把oldfields文件描述符指向的文件表项复制给newoldfields文件描述符,但newoldfields文件描述符自身的值就没变过。就像
char *p1 = "abc";
char *p2 = p1;

p1,p2都指向abc,但p1,p2自身地址(&p1,&p2)是不一样的。

#4


dup2(int oldfields,int newoldfields)
从函数原型上也能看出,传的是int,不是int *。


另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???
没看懂这个问题想问什么

#5


引用 2 楼 luciferisnotsatan 的回复:
?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2(fd0,fd1);这块改成了int return_status;return_status=dup2(fd0,fd1);
为什么return_status的值是-1;我的newlodfields的文件描述符值是随即的,但也应该调用成功。
而我加上了errno,然后perror("fd0->fd1"),提示的错误是:UNKNOW ERROR 32424092084;

#6


引用 4 楼 luciferisnotsatan 的回复:
dup2(int oldfields,int newoldfields)
从函数原型上也能看出,传的是int,不是int *。


另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???
没看懂这个问题想问什么

打错 是关闭一个文件描述符

#7


另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???

    dup2(int oldfd,int newfd)是在当newfd已经指向一个文件时,关闭newfd(跟重定向效果一样),所谓的关闭只是将文件的引用计数减去1,当引用计数是0时,就将文件关闭,非0时都只是将引用计数减去1,文件并不关闭

#8


fd1,fd2,fd3是随机数, 很正常啊, 你操作fd1,fd2,fd3就是在操作fd0. 

比如dup(1,123) 意思就是123和1都指向同一个打开的文件, 共享同一个文件偏移量, 操作123就等于操作1.

#9


引用 5 楼 onewaithome 的回复:
引用 2 楼 luciferisnotsatan 的回复:

?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2(fd0,fd1);这块改成了int return_s……




 dup2(int oldfd,int newfd),这两个参数都要是fd才行,要指向一个打开的文件(或者是一个没有关闭的管道的读端或写端)才行。可以用一个数字表示,fd1,fd2这些都是随机的数字,不一定是一个有效的fd,可以做个测试

//close(fd0)//fd0是一个有效的fd,在关闭之前下句没错,关闭以后会出错
dup2(fd0,STDOUT_FILENO);

#10


引用 5 楼 onewaithome 的回复:
引用 2 楼 luciferisnotsatan 的回复:

?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2(fd0,fd1);这块改成了int return_s……

可能随机数太大了,超出范围了。

#11


引用 10 楼 luciferisnotsatan 的回复:
引用 5 楼 onewaithome 的回复:

引用 2 楼 luciferisnotsatan 的回复:

?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2……

也可以不是一个有效的表述符。

#12


dup复制的是文件表项吧,不是文件描述符。

#13


你把fd想成指针,dup2使得new指向的文件关闭,同时让new指向old指向的文件。

#14


参考linux的dup2函数源代码。

或者

http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express
点开Visual C++ 2010 Express下面的语言选‘简体中文’,再点立即安装

再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\dup2.c

#15


我前几天刚学,下面是我个人体会
dup(fd)  fd为已存在的文件描述符,如0、1、2,如dup(1)返回3,此时的3为1的复制
此时你write( 3,buf,size),则输出在标准输出
若dup(5)则出错,因为5未启用,返回-1
dup2(1,7)就是dup(1)成功默认返回可启用的最小文件描述符3,而dup2()则可以指定如让7成为1的复制

#1


不是指向同一个文件描述符,是指向同一个文件表项。
没关闭啊。

#2


?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数

#3


把oldfields文件描述符指向的文件表项复制给newoldfields文件描述符,但newoldfields文件描述符自身的值就没变过。就像
char *p1 = "abc";
char *p2 = p1;

p1,p2都指向abc,但p1,p2自身地址(&p1,&p2)是不一样的。

#4


dup2(int oldfields,int newoldfields)
从函数原型上也能看出,传的是int,不是int *。


另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???
没看懂这个问题想问什么

#5


引用 2 楼 luciferisnotsatan 的回复:
?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2(fd0,fd1);这块改成了int return_status;return_status=dup2(fd0,fd1);
为什么return_status的值是-1;我的newlodfields的文件描述符值是随即的,但也应该调用成功。
而我加上了errno,然后perror("fd0->fd1"),提示的错误是:UNKNOW ERROR 32424092084;

#6


引用 4 楼 luciferisnotsatan 的回复:
dup2(int oldfields,int newoldfields)
从函数原型上也能看出,传的是int,不是int *。


另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???
没看懂这个问题想问什么

打错 是关闭一个文件描述符

#7


另外:为什么有四个文件描述符指向同一个文件表项,就得关闭一个文件表项呢???

    dup2(int oldfd,int newfd)是在当newfd已经指向一个文件时,关闭newfd(跟重定向效果一样),所谓的关闭只是将文件的引用计数减去1,当引用计数是0时,就将文件关闭,非0时都只是将引用计数减去1,文件并不关闭

#8


fd1,fd2,fd3是随机数, 很正常啊, 你操作fd1,fd2,fd3就是在操作fd0. 

比如dup(1,123) 意思就是123和1都指向同一个打开的文件, 共享同一个文件偏移量, 操作123就等于操作1.

#9


引用 5 楼 onewaithome 的回复:
引用 2 楼 luciferisnotsatan 的回复:

?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2(fd0,fd1);这块改成了int return_s……




 dup2(int oldfd,int newfd),这两个参数都要是fd才行,要指向一个打开的文件(或者是一个没有关闭的管道的读端或写端)才行。可以用一个数字表示,fd1,fd2这些都是随机的数字,不一定是一个有效的fd,可以做个测试

//close(fd0)//fd0是一个有效的fd,在关闭之前下句没错,关闭以后会出错
dup2(fd0,STDOUT_FILENO);

#10


引用 5 楼 onewaithome 的回复:
引用 2 楼 luciferisnotsatan 的回复:

?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2(fd0,fd1);这块改成了int return_s……

可能随机数太大了,超出范围了。

#11


引用 10 楼 luciferisnotsatan 的回复:
引用 5 楼 onewaithome 的回复:

引用 2 楼 luciferisnotsatan 的回复:

?????
dup2(int oldfields,int newoldfields)
把old的复制给new。又不会改变new的值。fd1,fd2,fd3都没初始化,随机数


这点我弄混了,我把dup2当成文件描述符的复制函数。

我还有个疑问:
我在dup2……

也可以不是一个有效的表述符。

#12


dup复制的是文件表项吧,不是文件描述符。

#13


你把fd想成指针,dup2使得new指向的文件关闭,同时让new指向old指向的文件。

#14


参考linux的dup2函数源代码。

或者

http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express
点开Visual C++ 2010 Express下面的语言选‘简体中文’,再点立即安装

再参考C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\dup2.c

#15


我前几天刚学,下面是我个人体会
dup(fd)  fd为已存在的文件描述符,如0、1、2,如dup(1)返回3,此时的3为1的复制
此时你write( 3,buf,size),则输出在标准输出
若dup(5)则出错,因为5未启用,返回-1
dup2(1,7)就是dup(1)成功默认返回可启用的最小文件描述符3,而dup2()则可以指定如让7成为1的复制