-1

I am studying in System Programming.

If we call open("/dev/fd/n", mode), we duplicate the n-th file descriptor and assign to a new file descriptor.

However, the mode we specify needs to be the subset of the referenced file (/dev/fd/n), and, I was wondering how is this working.


Does this create a new entry in the open file table?

  1. If it does, why should the mode be a subset of /dev/fd/n's file status flag?
  2. If not, how could I have two different file descriptor pointing to the same entry in file entry table with different file status flag?
JMP
  • 4,417
  • 17
  • 30
  • 41
  • 1
    Opening a new file creates a new entry in the file table. Period. Closing the file frees the fd# to be re-used for a subsequent file (at least on some OS's), but it's always a new, different file entry. "mode" doesn't really have much of anything to do with it. – paulsm4 Nov 07 '20 at 04:18

1 Answers1

3

When we open /dev/fd/n, we are not "duplicating" a file descriptor. We are opening a brand new file.

You may be confusing this with using dup. Since we know the binary value of n, we could do: int fdn = dup(n);. That would share things.

But, that is not what we're doing.

/dev/fd is a symlink to /proc/self/fd. If we do ls -l /proc/self/fd > /tmp/out, we'll get something like:

total 0
lrwx------. 1 cae cae 64 Nov  7 00:16 0 -> /dev/pts/2
l-wx------. 1 cae cae 64 Nov  7 00:16 1 -> /tmp/out
lrwx------. 1 cae cae 64 Nov  7 00:16 2 -> /dev/pts/2
lr-x------. 1 cae cae 64 Nov  7 00:16 3 -> /proc/35153/fd

If we do:

fd = open("/proc/self/0",O_WRONLY);

this is identical to doing:

fd2 = open("/dev/pts/2",O_WRONLY);

fd and fd2 do not share any flags/modes, etc. They are completely separate. Nor do they have any common flags/modes with fd 0.

Note that I deliberately specified /proc/self/0 [which is open for reading] and, yet, we opened it for writing.

It does not care about [nor use] the original descriptors flags, etc. Once again, it is just a "double level" symlink to the full path of the final target file: /dev/pts/2

It is the file permissions of the target file that dictate whether a given open is allowed (e.g. if the permissions were 0444, and we tried to open with O_WRONLY, that would return EPERM).

This would be no different than if we had a directory that looked like:

total 0
-rw-r--r--. 1 cae cae 0 Nov  7 00:29 a
lrwxrwxrwx. 1 cae cae 1 Nov  7 00:29 b -> a
lrwxrwxrwx. 1 cae cae 1 Nov  7 00:29 c -> a
lrwxrwxrwx. 1 cae cae 1 Nov  7 00:29 d -> c

We could do:

int fd1 = open("a",O_RDONLY);
int fd2 = open("b",O_WRONLY);
int fd3 = open("c",O_WRONLY);
int fd4 = open("d",O_WRONLY);

Those four file descriptors don't share anything. But, they are four separate streams to the same file. So, if we write to any of fd2, fd3, or fd4. Then, read from fd1 and we'll see the effect.

Craig Estey
  • 30,627
  • 4
  • 24
  • 48