Linux File Descriptor
A file descriptor in Linux is a non-negative integer that uniquely identifies an open file within a process. It serves as an abstract handle to perform various input/output (I/O) operations, such as reading from or writing to files, sockets, or other resources.
Key Characteristics
- Non-negative Integer: File descriptors are represented as integers starting from 0.
- Process-specific: Each process has its own set of file descriptors.
- Standard File Descriptors:
0
: Standard Input (stdin)1
: Standard Output (stdout)2
: Standard Error (stderr)
Common Operations
- Opening a File: The
open()
system call is used to open a file and returns a file descriptor.int fd = open("example.txt", O_RDONLY);
- Reading from a File: The
read()
system call reads data from a file descriptor.char buffer[100]; ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
- Writing to a File: The
write()
system call writes data to a file descriptor.ssize_t bytes_written = write(fd, "Hello, World!", 13);
- Closing a File: The
close()
system call closes a file descriptor.close(fd);
File Descriptor Limits
- Maximum Number: The maximum number of file descriptors a process can open is determined by the system's
ulimit
settings. - Checking Limits: The
ulimit -n
command can be used to check the current limit.ulimit -n
File Descriptor Table
Each process maintains a file descriptor table that maps file descriptors to open files or resources. The kernel manages this table and ensures that each file descriptor is unique within the process.
Example Usage
Here is a simple example of using file descriptors in a C program:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return 1;
}
char buffer[100];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read == -1) {
perror("read");
close(fd);
return 1;
}
printf("Read %zd bytes: %s\n", bytes_read, buffer);
close(fd);
return 0;
}
Summary
File descriptors are a fundamental concept in Linux for managing I/O operations. They provide a simple and efficient way to interact with files, sockets, and other resources. Understanding how to use and manage file descriptors is essential for system programming in Linux.