Understanding File Descriptors in Linux: A Simplified Explanation

We have often heard that “Everything In Linux Is A File” and in this context another term which we come across is “File Descriptors”. In this module, we will have a look at what File Descriptors are in Linux and how to work with them.

What are File Descriptors?

File Descriptors are non-negative integers that act as an abstract handle to “Files” or I/O resources (like pipes, sockets, or data streams). These descriptors help us interact with these I/O resources and make working with them very easy.

Every process has it’s own set of file descriptors. Most processes (except for some daemons) have these three File Descriptors :

  • stdin: Standard Input denoted by the File Descriptor 0
  • stdout: Standard Output denoted by the File Descriptor 1
  • stderr: Standard Error denoted by File Descriptor 2

List All File Descriptors Of A Process

Every process has its own set of File Descriptors. To list them all, we need to find its PID. For example, if I want to check all the File Descriptors under the process ‘i3

First, we need to find the PID of the process by using the ps command:

$ ps aux | grep i3
576

Now, to list all the file descriptors under a particular PID the syntax would be:

$ ls -la /proc/<PID>/fd

For our example, this would translate to:

$ ls -la /proc/576/fd
total 0
lr-x------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 0 -> /dev/null
l-wx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 1 -> /dev/null
l-wx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 2 -> /home/whokilleddb/.xsession-errors
l-wx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 3 -> /run/user/1000/i3/errorlog.576
lrwx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 4 -> 'socket:[20002]'
lrwx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 5 -> 'anon_inode:[eventpoll]'
lrwx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 6 -> 'anon_inode:[eventfd]'
lrwx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 7 -> 'socket:[20004]'
lrwx------ 1 whokilleddb whokilleddb 64 Mar 10 14:45 8 -> 'socket:[20005]'

Working with File Descriptors in C

Here, we have written a little C program to describe how we can use File Descriptors.

#include <unistd.h>
#include <string.h>
void main()
{
	char buff[20];
	char hello[20]="I Am ";
	read(0,buff,20);
	strcat(hello,buff);
	write(1,hello,strlen(hello));
}

Here we are reading characters from stdin by using File Descriptor 0 [ read() at line 7 ] and then after concatenating it with a message [ strcat() at line 8 ] and then writes the resultant string to the I/On stream pointed to by File Descriptor 1, i.e, stdout [ write() at line 9 ].

Compiling and running our program :

$ gcc fd.c -o out
$ ./out
Groot
I Am Groot

Conclusion

Hence, we lightly touched upon file descriptors in this module. These make several operations easy as everything can be treated as a file. They are a crucial when it comes to dealing with pipes, sockets and data streams and are an integral part of the OS’s architecture.

What are file descriptors in the context of Unix?

In Unix, every input or output operation that happens in a Unix environment is represented by a file descriptor. Essentially, file descriptors are integer numbers that uniquely identify an open file within a process.

How does one open a file in Unix?

To open a file in Unix, a process makes a system call to the kernel requesting to open a specific file. The kernel then returns a file descriptor, which is used by the process to access the file for reading or writing.

Why is everything considered to be a file in Unix?

In Unix, the philosophy that “everything is a file” means that all types of input/output operations are treated as if they were manipulating files. This simplifies the design and implementation of the operating system.

How does the operating system handle file descriptors when a file is closed?

When a file is closed in Unix, the operating system releases the file descriptor associated with that file. This ensures that the file descriptor can be reused by the system.

Can you explain the concept of free file descriptors?

In Unix, when a file descriptor is no longer in use or needed, it is considered free. This means that the file descriptor is available for reuse by other processes.

What role do system calls play in file descriptor management?

System calls in Unix are how processes interact with the operating system. When a process needs to work with file descriptors, it makes system calls to request actions such as opening, reading, writing, or closing files.

How do file descriptors relate to pipelines in Unix?

File descriptors play a crucial role in Unix pipelines, which are a way to connect the output of one command to the input of another. In pipelines, file descriptors are used to pass data between processes efficiently.