In operating system design, file descriptors are resources that users may either read bytes from or write bytes to. These may include actual files.
By convention:
0: standard input (read)1: standard output (write)2: standard error (write)
In UNIX systems
On UNIX and Linux systems, there are several syscalls and utilities we can use to interact with file descriptors.
ssize_t write(int fd, const void buf[.count], size_t count): writescountbytes to a file descriptor.ssize_t read(int fd, void buf[.count], size_t count): readscountbytes from a file descriptor. Blocking syscall. If the file descriptor cannot be read from, it’ll exit the program. Otherwise, it won’t properly exit.int dup(int oldfd): allocates a new file descriptor that refers to the same file descriptor asoldfd. The new FD number is the lowest available number.int dup2(int oldfd, int newfd): atomically changes the FDnewfdto point tooldfd. This closesnewfd, and allocates its same FD number to point tonewfd. This is done atomically to prevent any race conditions associated with doing this process manually, i.e., callingclose(), thendup().