How are the standard file descriptors implemented?
Hello, after my current research on that topic, I fear that my question is probably way too broad and unspecific, as there seem to be multiple viable ways, so I try to narrow it down. First of what is my motivation? I try to implement these standard file descriptors within a practice operating system, in order to get file-system specific system calls like open, read, write and close to work. What I currently (believe to) know: - The standard file descriptors are an abstraction layer in between an output device like a monitor and an input device like a keyboard. In the old days, these were configured directly to the terminals. - In glibc (https://github.com/bminor/glibc/blob/master/libio/stdfiles.c), they are defined there as FILE struct instances that associate to the specific file descriptors. - I can locate the file descriptors of a specific process within Linux under: /proc/{process_id}/fd/{0,1,2} root@basti:/proc/self# ls -l fd total 0 lrwx------ 1 root root 64 Oct 7 07:54 0 -> /dev/pts/4 lrwx------ 1 root root 64 Oct 7 07:54 1 -> /dev/pts/4 lrwx------ 1 root root 64 Oct 7 07:54 2 -> /dev/pts/4 lrwx------ 1 root root 64 Oct 7 07:54 255 -> /dev/pts/4 they all point to /dev/pts/4, if I look in the /dev/pts directory: root@basti:/dev/pts# ls -l total 0 crw--w---- 1 basti tty 136, 0 Oct 7 07:53 0 crw--w---- 1 basti tty 136, 1 Oct 6 20:59 1 crw--w---- 1 libvirt-qemu tty 136, 2 Oct 4 16:27 2 crw--w---- 1 basti tty 136, 3 Oct 7 07:56 3 crw------- 1 basti tty 136, 4 Oct 7 07:56 4 c--------- 1 root root 5, 2 Oct 4 12:10 ptmx Here I can see that they all point to a character device, with the group tty. And I know that /dev/pts/4 is a pseudeo teletype, which is a slave of the ptmx multiplexor. The gaps I currently have: - Who creates that device /dev/pts/4 ? I was currently not able to locate this information. - How is that device connected to my keyboard/monitor? - Could I maybe create a simplified version, which just utilizes a file for STDIN, STDOUT, STDERR. That are created by the init process and inherited to all child processes? Maybe I could then redirect the keyboard output to the STDIN file, the STDOUT file to the monitor device etc. Thanks in advance for any help! Greetings Sebastian
Thanks a million for... ! Sent from my iPhone
On Oct 7, 2020, at 2:11 PM, Sebastian Fricke <sebastian.fricke.linux@gmail.com> wrote:
Hello,
after my current research on that topic, I fear that my question is probably way too broad and unspecific, as there seem to be multiple viable ways, so I try to narrow it down. First of what is my motivation? I try to implement these standard file descriptors within a practice operating system, in order to get file-system specific system calls like open, read, write and close to work.
What I currently (believe to) know: - The standard file descriptors are an abstraction layer in between an output device like a monitor and an input device like a keyboard. In the old days, these were configured directly to the terminals. - In glibc (https://github.com/bminor/glibc/blob/master/libio/stdfiles.c), they are defined there as FILE struct instances that associate to the specific file descriptors. - I can locate the file descriptors of a specific process within Linux under: /proc/{process_id}/fd/{0,1,2} root@basti:/proc/self# ls -l fd total 0 lrwx------ 1 root root 64 Oct 7 07:54 0 -> /dev/pts/4 lrwx------ 1 root root 64 Oct 7 07:54 1 -> /dev/pts/4 lrwx------ 1 root root 64 Oct 7 07:54 2 -> /dev/pts/4 lrwx------ 1 root root 64 Oct 7 07:54 255 -> /dev/pts/4
they all point to /dev/pts/4, if I look in the /dev/pts directory:
root@basti:/dev/pts# ls -l total 0 crw--w---- 1 basti tty 136, 0 Oct 7 07:53 0 crw--w---- 1 basti tty 136, 1 Oct 6 20:59 1 crw--w---- 1 libvirt-qemu tty 136, 2 Oct 4 16:27 2 crw--w---- 1 basti tty 136, 3 Oct 7 07:56 3 crw------- 1 basti tty 136, 4 Oct 7 07:56 4 c--------- 1 root root 5, 2 Oct 4 12:10 ptmx
Here I can see that they all point to a character device, with the group tty. And I know that /dev/pts/4 is a pseudeo teletype, which is a slave of the ptmx multiplexor.
The gaps I currently have: - Who creates that device /dev/pts/4 ? I was currently not able to locate this information. - How is that device connected to my keyboard/monitor? - Could I maybe create a simplified version, which just utilizes a file for STDIN, STDOUT, STDERR. That are created by the init process and inherited to all child processes? Maybe I could then redirect the keyboard output to the STDIN file, the STDOUT file to the monitor device etc.
Thanks in advance for any help!
Greetings Sebastian
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Wed, 07 Oct 2020 08:11:17 +0200, Sebastian Fricke said:
- The standard file descriptors are an abstraction layer in between an output device like a monitor and an input device like a keyboard. In the old days, these were configured directly to the terminals.
There's "in the old days", and then there's the age of myths and legend, which some of us were already around for. :) Yes, files were configured to terminals. Unless they were connected to a pipe to another program, or to a file, or to a network socket, or... In other words, only configured to terminals by default, if you were running from an interactive source like a terminal or console. Redirection to a file was there from pretty much the beginning of Unix. https://en.wikipedia.org/wiki/Everything_is_a_file Pipes date back to 1973 or so.. https://en.wikipedia.org/wiki/Pipeline_(Unix) BSD 4.2 brought us sockets, although I admit not being sure when bash sprouted the /dev/tcp and /dev/udp pseudo-devices. (And also brought loads of fun when 4.3 showed up with a different concept of broadcast addresses, meaning that a 4.2->4.3 upgrade was a flag-day for the entire subnet... or else. :) And I remember more than one security exploit against programs that assumed that stdout was connected to someplace rational, which led to hilarity and hjinks if you invoked the program with file descriptor zero closed, it would open some security-relevant file like /etc/passwd (possibly inplicitly via a call to getpwent() or similar, and then invoke some other program, which now had fd 0 stdout connected to /etc/passwd. (vipw got bit by this, among other programs...)
- Who creates that device /dev/pts/4 ? I was currently not able to locate this information.
The Nth program to open a generic pts device. It can then be fed to dup() to create copies, passed across a fork/exec, or pretty much anything else legal to do with an open file descriptor. In a GUI environment, it's probably xterm/Gnome-terminal/etc...
- How is that device connected to my keyboard/monitor?
Depends. if you're on a virtual console, it's probably using /dev/ttyN instead. If you're running an X-based GUI, it gets complicated. :) Normally, xterm or gnome-terminal or whatever, creates a pty, sets up fd 0 1 and 2 to point to it, opens up its own file descriptors for the other end of the 3 pipes, and then fork/execs bash or whatever program. So if bash or a child scribble on stdout, xterm then reads from the other end of the pipe and then goes through a *very* long and ugly process to map that to pixels on the screen. input goes through an equally convoluted process from a keyboard event being read by the X server (usually via the evdev driver in most modern distros), then passed as an X event to xterm or gnome-terminal, which then reads it and synthesizes a character input and pushes it down the pipe to the bash or vi or whatever is currently the process reading from the terminal. Meanwhile, bash does its own games when setting up to run a program, in order to get any redirections set up.
- Could I maybe create a simplified version, which just utilizes a file for STDIN, STDOUT, STDERR. That are created by the init process and inherited to all child processes?
% your_command_here < your_stdin_file > your_stdout_file 2> your_stderr_file Done. Don't make it harder than you have to.
Maybe I could then redirect the keyboard output to the STDIN file, the STDOUT file to the monitor device etc.
That's actually more complicated than just directing the file to wherever in the first place. (How complicated? The xterm source famously contained the comment "Here there be dragons. You are not expected to understand this" in the section of code that set up the ptys for the child process's initial fd 0/1/2.
participants (3)
-
linux lover -
Sebastian Fricke -
Valdis Klētnieks