3

If I type ls -l /dev in a virtual terminal I get

lrwxrwxrwx  1 root root          15 apr 10 10:59 stderr -> /proc/self/fd/2
lrwxrwxrwx  1 root root          15 apr 10 10:59 stdin -> /proc/self/fd/0
lrwxrwxrwx  1 root root          15 apr 10 10:59 stdout -> /proc/self/fd/1

If i then type ls -l /proc/self/fd I get

lrwx------ 1 user user 64 apr 10 19:59 0 -> /dev/pts/1
lrwx------ 1 user user 64 apr 10 19:59 1 -> /dev/pts/1
lrwx------ 1 user user 64 apr 10 19:59 2 -> /dev/pts/1

All entries point to the same device file, which also happen to be the controlling terminal for the virtual shell (as confirmed by the "tty" command). Am I then right to assume that the stdin, sdout and stderr file descriptors all operate on the same file (/dev/pts/1), e.g. three separate open() calls have been made (when the virtual shell process was forked from its parent process) on the same file?

If so, while running the following program:

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

int main() {
    int rfd = open("./a_file",O_RDONLY);
    int wfd = open("./a_file",O_WRONLY);

    char rc='a',wc='b';

    if (write(rfd,&wc,1)<0) {
        perror("Error");
    }

    if (read(wfd,&rc,1)<0) {
        perror("Error");
    }
}

Gives:

Error: Bad file descriptor
Error: Bad file descriptor

As expected, but when changing rfd to 1 (sdtout) and wfd to 0 (stdin) in the read() arguments, I don't get an error. Does this mean that /dev/tty was opened with the O_RDWR flag?

When trying:

if (write(1,&wc,1)<0) {
    perror("Error");
}

if (read(0,&rc,1)<0) {
    perror("Error");
}

I see the 'b' on the console, but the read() call doesn't return, as if there wasn't any data to be read from the file. Why is that?

1 Answers1

2

Agreeing that they all reference the same device, the actual question appears at the very end. The reason why the read fails to return anything is that /dev/tty is not just a connection from its input to its output, but is a connection between your (shell) process and a real device, i.e., the Linux console. You could have a program running on the console which reads data from the host (such as your example above) and replies (providing data for the read call), but without that additional connection, the read will have no data.

Further reading:

Thomas Dickey
  • 76,765
  • But isn't /dev/tty a file in some sense? Using another file than /dev/tty i can open two different fd's, one for writing and one for reading, then write a byte to the file, which i can then read from the read fd. Why is that not possible using /dev/tty? Keep in mind that my two fd do not share the same offset in the kernel. One reason that it would not work on /dev/tty, i can imagine, is that stdin and stdout have the same offset, e.g. have been created with dup() – Bwawhwmopoloin Apr 11 '16 at 09:48
  • A device is different from a file, because a device does something (or can react), while a file is passive. Files hold data, while devices manipulate data. – Thomas Dickey Apr 11 '16 at 23:06