File Descriptors In Linux

File Descriptors In Linux

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.