A Beginner's Guide to Understanding Read System Call in Linux

In Linux, system calls are the primary interface between the user space applications and the kernel.

These system calls provide a means for applications to access the kernel services like file I/O, process management, and inter-process communication.

One such system call is the "read" system call, which is used to read data from a file or device. In this article, we will explore the "read" system call in detail, its syntax, parameters, return value, and some examples of its usage.

Overview of the "read" System Call

The "read" system call is used to read data from a file descriptor. The syntax of the "read" system call is as follows:

ssize_t read(int fd, void *buf, size_t count);

where "fd" is the file descriptor of the file to be read, "buf" is a pointer to the buffer where the data is to be stored, and "count" is the maximum number of bytes to be read.

The "read" system call returns the number of bytes read, or -1 if an error occurred. Some of the common error codes returned by the "read" system call are:

  • EINTR: Interrupted system call
  • EAGAIN: Resource temporarily unavailable
  • EBADF: Invalid file descriptor
  • EINVAL: Invalid argument
  • EIO: Input/output error

Let's now look at some examples of using the "read" system call.

Example : Reading from a File

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

int main(int argc, char *argv[])
{
int fd;
ssize_t nread;
char buffer[BUFFER_SIZE];

if (argc != 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
exit(EXIT_FAILURE);
}

fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}

while ((nread = read(fd, buffer, BUFFER_SIZE)) > 0) {
if (write(STDOUT_FILENO, buffer, nread) != nread) {
perror("write");
exit(EXIT_FAILURE);
}
}

if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}

if (close(fd) == -1) {
perror("close");
exit(EXIT_FAILURE);
}

exit(EXIT_SUCCESS);
}

In this example, we open a file using the "open" system call and read from it using the "read" system call. The file descriptor returned by the "open" system call is passed as the first argument to the "read" system call.

The data read is stored in the buffer passed as the second argument to the "read" system call. The maximum number of bytes to be read is passed as the third argument to the "read" system call.

The "read" system call is used inside a loop to read data from the file until the end of the file is reached. The number of bytes read is returned by the "read" system call and is stored in the "nread" variable. The data read is then written to the standard output using the "write" system call.