I'm having some trouble comprehending exactly how read() works. For example, given the following program, with the file infile containing the string "abcdefghijklmnop":
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int fd;
char buf[5] = "WXYZ";
fd = open("infile", O_RDONLY);
read(fd, buf, 2);
read(fd, buf 2, 2);
close(fd);
printf("%c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]);
return 0;
}
Looking at the read system call function:
ssize_t read(int fildes, void *buf, size_t nbyte);
I get that *buf is the buffer that holds the bytes read, and nbyte is the number of bytes that's being read. So after the first read(), only the first 2 characters of infile are read ("a" and "b"). Why isn't the output just "abcd"? Why are there other possibilities such as "aXbZ" or "abcZ"?
CodePudding user response:
The manual page for the version of read
I have says:
read()
attempts to readnbyte
bytes of data from the object referenced by the descriptorfildes
into the buffer pointed to bybuf
.
and:
Upon successful completion,
read()
,readv()
, andpread()
return the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left before the end-of-file, but in no other case.
Thus, in the case you describe, with “the file infile containing the string "abcdefghijklmnop"”, the two read
calls are guarantee to put “ab” and “cd” into buf
, so the program will print “abcd” and a new-line character. (I would not take that guarantee literally. Certainly the system can guarantee that it will not allow unrelated interrupts to prevent the read
from completely reading the requested data, but it could not guarantee there is no hardware failure, such as a disk drive failing before the read is completed.)
In other situations, when read
is reading from a source other than a normal file, each of the two read
calls may read 0, 1, or 2 bytes. Thus, the possible buffer contents are:
Bytes read in first read | Bytes read in second read | Buffer contents |
---|---|---|
0 | 0 | WXYZ |
0 | 1 | WXcZ |
0 | 2 | WXcd |
1 | 0 | aXYZ |
1 | 1 | aXcZ |
1 | 2 | aXcd |
2 | 0 | abYZ |
2 | 1 | abcZ |
2 | 2 | abcd |