Reputation: 168
The man entry says lseek
should return -1
if the resulting file offset would be negative for a regular file.
Why does code like this work?
int fd;
off_t offset;
fd = open("test.txt", O_RDWR);
offset = lseek(fd, -10, SEEK_SET);
printf("%d\n", offset); // prints -10
if (offset == (off_t) -1)
perror("seek"); // error not triggered
I feel like I should get offset=-1
and errno
set to EINVAL
.
This also causes the file size to appear extremely large (close to the size of an unsigned int) - seems like an overflow issue. Why is that?
Upvotes: 5
Views: 6884
Reputation: 74018
I managed to reproduce your "erroneous" behaviour. You must include unistd.h
to get the proper prototype. With this include, lseek
behaves as described.
When you miss this include, the compiler passes an int -10
instead of an off_t -10
. This results in your observed behaviour.
Update:
The complete list of needed includes is
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
Upvotes: 15
Reputation: 10516
A negative file offset may be valid for some devices in some implementations.
The POSIX.1-1990 standard did not specifically prohibit lseek() from returning a negative offset
. Therefore, an application was required to clear errno prior to the call and check errno upon return to determine whether a return value of ( off_t)-1
is a negative offset or an indication of an error condition.
The standard developers did not wish to require this action on the part of a conforming application, and chose to require that errno be set to [EINVAL]
when the resulting file offset would be negative for a regular file, block special file, or directory.
See lseek
Upvotes: 5