Hello,
I just have a simple question, when implenting a stdout, stdin, and stderrr, should I just allocate memmory space and write to it or create a file in the vfs and write to it? As far as I know, unix has those std files as vfs files in /dev, but I just wanted to clarify with the rest of the OS dev community. If I am completly wrong about something, please do tell.
Thank you.
Implementing stdout, stdin, and stderr
Implementing stdout, stdin, and stderr
JS-OS - a learning tool and the result of a bit of caffeine
https://github.com/JSmith-BitFlipper/JS-OS
https://github.com/JSmith-BitFlipper/JS-OS
Re: Implementing stdout, stdin, and stderr
Unix uses file descriptors. Basically, each process has a table of open file descriptions (a pointer to a file, the current location in the open file, whether read/write is allowed, ...). Whenever a process opens a particular file, the open(2) system call returns an integer that is the location of the newly opened file description in the table. The integer itself is just an array index, but it's commonly called a file description. So process_open_files_table[file descriptor] = file description.
File descriptors are allocated such that the smallest slot is always used. This means that the first file opened gets the file descriptor 0, the second gets the file descriptor 1, and so on.
By convention, the first file opened is the standard input and it has file descriptor 0. The second file opened is the standard output and it has file descriptor 1. The third file opened is the standard error and it has file descriptor 2. This means that the libc stdin/stdout/stderr FILE contain this file descriptor and a call like fputc would call the system call write(2) on the file descriptor.
Note how a process never really itself opens the stdin/stdout/stderr file descriptors, but rather inherits it from the parent process. Whenever a process is created (through fork(2)), the new process gets a copy of all the file descriptors from the parent process. The shell process uses this to implement IO redirection, pipelines, etc. - simply by making sure the new child processes have the correct initial file descriptors for stdin, stdout, and stderr.
So yeah, you will want to read up on file descriptors are how they work. They are basically named (by an integer) kernel objects that can be manipulated through system calls. Note how Windows uses a similar (but quite different) scheme called 'Handles' (but note how file descriptors are also handles, as handle means a named kernel object in our context).
File descriptors are allocated such that the smallest slot is always used. This means that the first file opened gets the file descriptor 0, the second gets the file descriptor 1, and so on.
By convention, the first file opened is the standard input and it has file descriptor 0. The second file opened is the standard output and it has file descriptor 1. The third file opened is the standard error and it has file descriptor 2. This means that the libc stdin/stdout/stderr FILE contain this file descriptor and a call like fputc would call the system call write(2) on the file descriptor.
Note how a process never really itself opens the stdin/stdout/stderr file descriptors, but rather inherits it from the parent process. Whenever a process is created (through fork(2)), the new process gets a copy of all the file descriptors from the parent process. The shell process uses this to implement IO redirection, pipelines, etc. - simply by making sure the new child processes have the correct initial file descriptors for stdin, stdout, and stderr.
So yeah, you will want to read up on file descriptors are how they work. They are basically named (by an integer) kernel objects that can be manipulated through system calls. Note how Windows uses a similar (but quite different) scheme called 'Handles' (but note how file descriptors are also handles, as handle means a named kernel object in our context).