I wrote this small code to ascertain read behavior.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <errno.h>
int main ()
{
ssize_t ret;
int fd;
char str[30] = {0};
off_t lret
fd = open("./sample", O_RDWR);
printf("File descriptor = %d\n",fd);
lret = lseek(fd,LONG_MAX,SEEK_SET);
printf("%ld\n",lseek(fd, 0, SEEK_CUR));
ret = read(fd, str, 20);
if (ret == -1) {
perror("read error");
}
else {
printf("%ld\n",ret);
printf("%s\n",str);
}
ret = write(fd, "bye", 3);
if (ret == -1) {
perror("write error");
}
else
printf("%ld\n",ret);
printf("%ld\n",lseek(fd, 0, SEEK_CUR));
close (fd);
return 0;
}
Here is the output:
$ cat sample
HELLO$ ./a.out
File descriptor = 3
4294967295
read error: Invalid argument
write error: Invalid argument
4294967295
$ ll sample
-rw-r--r--. 1 bruce stud 5 Jan 14 17:25 sample
But if I change lseek statement to
ret = lseek(fd,5,SEEK_SET);
read returns 0
$ ./a.out
File descriptor = 3
5
0
3
8
$ cat sample
HELLObye$ ll sample
-rw-r--r--. 1 bruce stud 8 Jan 14 17:26 sample
Why does read behave like this?
Note that the value returned by
lseekis aoff_t, not asize_t. The difference is that off_t is signed. When you take a signed value and make it unsigned, it appears like a large positive number.I would expect that “LONG_MAX” is not actually
4294967295, but either2147483647(2^31-1) or a much larger number. So the4294967295comes from a -1 [it is 2^32-1, which is indeed the same as -1 in 32-bit math].In other words, you are getting an error from
lseek.