This site uses cookies to deliver our services and to show you relevant ads and job listings.
By using our site, you acknowledge that you have read and understand our Cookie Policy, Privacy Policy, and our Terms of Service.
Your use of Stack Overflow’s Products and Services, including the Stack Overflow Network, is subject to these policies and terms.

Join us in building a kind, collaborative learning community via our updated
Code of Conduct.

What about the concepts of stdin stdout stderr etc ? I have an instance like say browser process opened and it has opened some temporary files for displayed my html . The process uses the same fd to read / write ? Also the process table ....... it has entries like fd0 pointer fd1 pointer fd2 pointer ..... does that mean all these files are in RAM ? Why else pointers ?
– NishantMar 10 '11 at 7:36

17

When you open a file, OS creates a stream to that file and connect that stream to opened file, the descriptor in fact represents that stream. Similarly there are some default streams created by OS. These streams are connected to your terminal instead of files. So when you write something in terminal it goes to stdin stream and OS. And when you write "ls" command on terminal, the OS writes the output to stdout stream. stdout stream is connected to your monitor terminal so you can see the output there.
– TayyabMar 10 '11 at 9:12

1

Regarding browser example, it is not necessary that browser keeps the files opened. It depends on implementation of browser but in most cases browser open a temporary file, write the file, and close the file, so its not necessary that the file is opened even if the web page is open. And descriptor just holds the information of the file and doesn't necessarily keep the file in RAM. When you read the data from a descriptor, the OS read the data from the hard-disk. The information in file descriptor just represents the location of the file on hard-disk etc..
– TayyabMar 10 '11 at 9:22

5

File descriptor to file is not a one to one mapping. I could open() the same file 4 times and get 4 different file descriptors. Each of which could be used (depending on the flags passed to the open()) for reading, writing or both. As far as whether the file lives in RAM or on disk - this is hidden from you by the kernel, and its various caches. Ultimately what is the cache will match what is on the disk (for writing), and the kernel will not go back to disk, for reading, if the data is already in the cache.
– BeanoMar 10 '11 at 16:17

7 Answers
7

In simple words, when you open a file, the operating system creates an entry to represent that file and store the information about that opened file. So if there are 100 files opened in your OS then there will be 100 entries in OS (somewhere in kernel). These entries are represented by integers like (...100, 101, 102....). This entry number is the file descriptor.
So it is just an integer number that uniquely represents an opened file in operating system.
If your process opens 10 files then your Process table will have 10 entries for file descriptors.

Similarly when you open a network socket, it is also represented by an integer and it is called Socket Descriptor.
I hope you understand.

Also, this is why you can run out of file descriptors, if you open lots of files at once. Which will prevent *nix systems from running, since they open descriptors to stuff in /proc all the time.
– Spencer RathbunMay 10 '12 at 12:51

3

Strictly speaking the Process Table will not have the file descriptors, the file descriptors are held in the u structure of the process, and are therefore unique to the process.
– BeanoFeb 22 '14 at 16:16

7

@ErbenMo: No it may not be same. When you open file, the operating system will assign a FD that is available and when you close it then OS release the FD and may assign that FD to another file opened after that. Its Operating system's way to track Opened Files and it has nothing to do with a specific file.
– TayyabOct 30 '14 at 6:19

13

"So it is just an integer number that uniquely represents an opened file in operating system." This is incorrect. That integer uniquely represents an opened file within a process. File descriptor 0, for example, will represent one opened file in one process and a completely different opened file in another process.
– Keith ThompsonJan 7 '16 at 22:04

8

@KeithThompson: Yes you are right. Actually its about the level of abstraction. Actually two tables are maintained, where first one is per-process and the second one is system wide. FD in per-process table (i.e fdtable) is not unique system wide. However it maps to v-node table that contains the system wide unique entries. So when you call fopen() and fileno() function to check the descriptor then you can get same FD number in 2 different processes because it returns the index of fdtable which is per-process. Thanks for bringing it up!!
– TayyabJan 19 '16 at 21:45

A file descriptor is an opaque handle that is used in the interface between user and kernel space to identify file/socket resources. Therefore, when you use open() or socket() (system calls to interface to the kernel), you are given a file descriptor, which is an integer (it is actually an index into the processes u structure - but that is not important). Therefore, if you want to interface directly with the kernel, using system calls to read(), write(), close() etc. the handle you use is a file descriptor.

There is a layer of abstraction overlaid on the system calls, which is the stdio interface. This provides more functionality/features than the basic system calls do. For this interface, the opaque handle you get is a FILE*, which is returned by the fopen() call. There are many many functions that use the stdio interface fprintf(), fscanf(), fclose(), which are there to make your life easier. In C, stdin, stdout, and stderr are FILE*, which in UNIX respectively map to file descriptors 0, 1 and 2.

Hear it from the Horse's Mouth : APUE (Richard Stevens).
To the kernel, all open files are referred to by File Descriptors. A file descriptor is a non-negative number.When we open an existing file or create a new file, the kernel returns a file descriptor to the process. The kernel maintains a table of all open file descriptors, which are in use. The allotment of file descriptors is generally sequential and they are alloted to the file as the next free file descriptor from the pool of free file descriptors. When we closes the file, the file descriptor gets freed and is available for further allotment.
See this image for more details :

When we want to read or write a file, we identify the file with the file descriptor that was returned by open() or create() function call, and use it as an argument to either read() or write().
It is by convention that, UNIX System shells associates the file descriptor 0 with Standard Input of a process, file descriptor 1 with Standard Output, and file desciptor 2 with Standard Error.
File descriptor ranges from 0 to OPEN_MAX.
For more information, go through 3rd chapter of APUE Book.

As an addition to other answers, unix considers everything as a file system. Your keyboard is a file that is read only from the perspective of the kernel. The screen is a write only file. Similarly, folders, input-output devices etc are also considered to be files. Whenever a file is opened, say when the device drivers[for device files] requests an open(), or a process opens an user file the kernel allocates a file descriptor, an integer that specifies the access to that file such it being read only, write only etc. [for reference : https://en.wikipedia.org/wiki/Everything_is_a_file ]

Any operating system has processes (p's) running, say p1, p2, p3 and so forth. Each process usually makes an ongoing usage of files.

Each process is consisted of a process tree (or a process table, in another phrasing).

Usually, Operating systems represent each file in each process by a number (that is to say, in each process tree/table).

The first file used in the process is file0, second is file1, third is file2, and so forth.

Any such number is a file descriptor.

File descriptors are usually integers (0, 1, 2 and not 0.5, 1.5, 2.5).

Given we often describe processes as "process-tables", and given that tables has rows (entries) we can say that the file descriptor cell in each entry, uses to represent the whole entry.

In a similar way, when you open a network socket, it has a socket descriptor.

In some operating systems, you can run out of file descriptors, but such case is extremely rare, and the average computer user shouldn't worry from that.

File descriptors might be global (process A starts in say 0, and ends say in 1 ; Process B starts say in 2, and ends say in 3) and so forth, but as far as I know, usually in modern operating systems, file descriptors are not global, and are actually process-specific (process A starts in say 0 and ends say in 5, while process B starts in 0 and ends say in 10).