I have a binary file from which I need to read timestamps. In particular, I'm trying to read the last record. Every record is 24 bytes long, the timestamp is in the first 8 bytes. Here's the code I wrote:
#define IDX_RS_LEN (unsigned int)(sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
int offset;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -IDX_RS_LEN, SEEK_END);
read(fd, &rGmte, sizeof(unsigned long));
printf("offset:%d\trGmte: %lu\n", offset, rGmte);
} else {
printf("Error opening file\n");
}
close(fd);
return 0;
}
But this gives me the following output:
offset:117384 rGmte: 0
Which is wrong. If I replace the expression in the define with the fixed value 24 I get the right output:
offset:117384 rGmte: 1606314900
Please also note that offset is the same in both cases, but the value read is different. Any idea?
You are using a wrong type to set the position / offset in lseek
, you should use an off_t
(signed long
) not an unsigned int
.
Take a look to What happens when I assign a negative value to an unsigned int?
The offset set to lseek
should be -24
:
printf("Output: %ld\n", -(signed long)(sizeof(unsigned long) * 3));
Output: -24
but you are setting
printf("Output: %ld\n", -(unsigned int)(sizeof(unsigned long) * 3));
Output: 4294967272
Switch from
#define IDX_RS_LEN (unsigned int)(sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
int offset;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -IDX_RS_LEN, SEEK_END);
to
#define IDX_RS_LEN (sizeof(unsigned long) * 3)
int main(int argc, char** argv)
{
int fd;
unsigned long rGmte;
char filename[256];
off_t offset = IDX_RS_LEN;
fd = open(filename, O_RDONLY);
if (fd != -1) {
offset = lseek(fd, -offset, SEEK_END);
and it should work: https://godbolt.org/z/hEG4xx