linuxgccdup

linux does opening /dev/fd/n is the same as duplicating it?


In APUE and in The Linux programming interface I read the following paragraph

Opening one of the files in the /dev/fd directory is equivalent to duplicating the corresponding file descriptor. Thus, the following statements are equivalent:

fd = open("/dev/fd/1", O_WRONLY);

fd = dup(1); /* Duplicate standard output */

When I test this scenario on a descriptor 3 (on regular file) I saw different result. The code is as follows:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main (int argc, char *argv[]) {
        int fd1, fd2, fd3;
        char filename[32];

        fd1 = open ("./data.in", O_RDWR);
        sprintf (filename, "/dev/fd/%d", fd1);
        fd2 = open (filename, O_RDONLY);
        fd3=dup(fd1);

        lseek(fd1, 10, SEEK_SET);
        printf ("pos1=%ld, pos2=%ld, pos3=%ld\n", lseek(fd1, 0, SEEK_CUR), lseek(fd2, 0, SEEK_CUR), lseek(fd3, 0, SEEK_CUR));
 
         return (0);
 }

If Opening the file in the /dev/fd directory is equivalent to duplicating it by dup, I except that all 3 descriptors have the same value in lseek(fdn, 0, SEEK_CUR), but I saw the following result:

pos1=10, pos2=0, pos3=10

I don't know why !


Solution

  • As Barmar told, It looks like a documentation bug. open() always creates a new entry in the file table. dup() just creates a new FD that refers to the same file table entry. The current position in a seekable stream is in the file table