write()/read() system call

read() and write() system calls are used to read and write data respectively to a file descriptor. To understand the concept of write()/read() system calls let us first start with write() system call.

write() system call is used to write to a file descriptor. In other words write() can be used to write to any file (all hardware are also referred as file in Linux) in the system but rather than specifying the file name, you need to specify its file descriptor.

Syntax:

#include<unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

The first parameter (fd) is the file descriptor where you want to write. The data that is to be written is specified in the second parameter. Finally, the third parameter is the total bytes that are to be written.

To understand better lets look at the first program below:

Program1: To write some data on the standard output device (by default – monitor)

//Name the program file as “write.c”

#include<unistd.h>
int main()
{
write(1,"hello\n",6); //1 is the file descriptor, "hello\n" is the data, 6 is the count of characters in data
}

How it works?

The write() system call takes three parameters: “1” which is the file descriptor of the file where we want to write. Since we want to write on standard output device which is the screen, hence the file descriptor, in this case, is ‘1’, which is fixed (0 is the file descriptor for standard input device (e.g. keyboard) and 2 is for standard error device)).
Next thing is what we want to write on the screen. In this case its “hello\n” i.e. hello and newline(\n), so a total of 6 characters, which becomes the third parameter. The third parameter is how much you want to write, which may be less than the data specified in the second parameter. You can play around and see the change in output.

Output:

Once you compile and run this, the output on the screen will be the word “hello”, as shown below

write() system call

On success, the write() system call returns the ‘number of bytes written’ i.e. the count of how many bytes it could write. This you can save in an integer variable and checked. The write() system call on failure returns -1.
Note: students get confused by thinking that write() return the data that is written. Remember, it returns the count of characters written. Refer to the program below.

Program 2

#include<stdio.h
#include<unistd.h>
int main()
{
int count;
count=write(1,"hello\n",6);
printf("Total bytes written: %d\n",count);
}

How it Works?

The program is similar to the previous one except that this time it also explicitly prints the count of bytes that write() system call was able to write on file descriptor 1.

Output:

write() system call

Variations

Try making the changes as shown in the codes below and observe the output to understand the working of the write() system call in detail.

Program 3:

#include<unistd.h>
int main()
{
write(1,"hello\n",60); //the bytes to be printed (third parameter) are more than the data specified in 2nd parameter
}

Program4:

#include<unistd.h>
int main()
{
write(1,"hello\n",3);//the bytes to be printed (third parameter) are less than the data specified in 2nd parameter
}

Program5:

#include<unistd.h>
#include<stdio.h>
int main()
{
int count;
count=write(3,"hello\n",6); //the file descriptor is not one of the pre-specified ones i.e., 0, 1 or 2
printf("Total bytes written: %d\n",count);
}

Will this call to write() be successful? If not then what will it return?

read()

The use of read() system call is to read from a file descriptor. The working is same as write(), the only difference is read() will read the data from file pointed to by file descriptor.

Syntax:

#include<unistd.h>
ssize_t read(int fd, const void *buf, size_t count);

The first parameter is the file descriptor. The second parameter is the buffer where the read data will be saved. Lastly, the third parameter is the number of bytes that you want to read.
Think of the buffer as a temporary storing area. As you are reading from this page and before typing the program on your system you temporarily store it in your brain. So your brain is the buffer. Although this page contains a lot of data, you might want to read only 20 characters. Hence, the third parameter (count) tells, how much you want to read?

Program 6: To read data from the standard input device and write it on the screen

//read.c
#include<unistd.h>
int main()
{
char buff[20];
read(0,buff,10);//read 10 bytes from standard input device(keyboard), store in buffer (buff)
write(1,buff,10);//print 10 bytes from the buffer on the screen
}

How it works?

The read() system call reads the input typed by the user via the keyboard (file descriptor 0) and stores it in the buffer (buff) which is nothing but a character array. It will read a maximum of 10 bytes (because of the third parameter). This can be less than or equal to the buffer size. No matter how much the user types only first 10 characters will be read.
Finally, the data is printed on the screen using the write() system call. It prints the same 10 bytes from the buffer (buff) on the screen (file descriptor 1).

Output:

read() system call

Variations: you can try different values of the third parameter in read and write to understand the working better.

The read() system call returns -1 on failure and “the count of bytes read” on success.


Important:

A common question that comes to our mind is that as a programmer you can not guarantee how much the user will type as an input. Hence, you can not specify the correct bytes in write() systemc all’s 3rd parameter. Hence, the output may vary from what you expect.
Now, remember what read() returns on success! the number of bytes read, and that’s the key as demonstrated below.

Program 7: To read data from the standard input device and write it on the screen
//read.c

#include<unistd.h>
int main()
{
int nread;
char buff[20];
nread=read(0,buff,10);//read 10 bytes from standard input device(keyboard), store in buffer (buff)
write(1,buff,nread);//print 10 bytes from the buffer on the screen
}

How it works?

This time we store the count of bytes read by read() in nread variable and then use variable in the write() to print exactly the same number of bytes on the screen.

Practice Programs on write()/read() system call

Q1. Write a program to read a maximum of 15 characters from the user and print them on the screen.
Q2. Write a program to print the count of characters read by the read() system call.

Viva Questions on write()/read() system call

Q1. What does the write() system call return on success?
Q2. What does the write() system call return on failure?
Q3. Can you use write() system to send data to a printer?
Q4. Can write system be used to write into a file “xyz.txt” without knowing the file descriptor of xyz.txt?
Q5. How to access the manual page of write()?
Q6. What does the read() system call return on success?

Share your answers to the viva questions in the comments section.

Video

Relevant Programs:

Leave a Reply

Your email address will not be published. Required fields are marked *