简体   繁体   中英

return value of lseek()

I got confused about lseek() 's return value(which is new file offset)

I have the text file (Its name is prwtest). Its contents are written to a to z.

And, the code what I wrote is following,

  1 #include <unistd.h>
  2 #include <fcntl.h>
  3 #include <stdlib.h>
  4 #include <stdio.h>
  5 #include <string.h>
  6 
  7 #define BUF 50
  8 
  9 int main(void)
 10 {
 11         char buf1[]="abcdefghijklmnopqrstuvwxyz";
 12         char buf2[BUF];
 13         int fd;
 14         int read_cnt;
 15         off_t cur_offset;
 16 
 17         fd=openat(AT_FDCWD, "prwtest", O_CREAT | O_RDWR | O_APPEND);
 18         cur_offset=lseek(fd, 0, SEEK_CUR);
 19         //pwrite(fd, buf1, strlen(buf1), 0);
 20         //write(fd, buf1, strlen(buf1));
 21         //cur_offset=lseek(fd, 0, SEEK_END);
 22 
 23         printf("current offset of file prwtest: %d \n", cur_offset);
 24 
 25         exit(0);
 26 }

On the line number 17 , I use flag O_APPEND , so the prwtest's current file offset is taken from i-node's current file size. (It's 26).

On the line number 18 , I use lseek() which is used by SEEK_CUR, and the offset is 0.

But the result value cur_offset is 0. (I assume that it must be 26, because SEEK_CUR indicates current file offset.) However, SEEK_END gives me what I thought, cur_offset is 26.

Why the lseek(fd, 0, SEEK_CUR); gives me return value 0, not 26?

Your issue is with open() / openat() , not lseek() .

From the open() manpage, emphasis mine:

O_APPEND

The file is opened in append mode. Before each write(2), the file offset is positioned at the end of the file, as if with lseek(2).

Since you don't write to the file, the offset is never repositioned to the end of the file.


While we're at it, you should be closing the file before ending the program...


Actually, while we're really at it, if you do #include <stdio.h> already, why not use the standard's file I/O ( fopen() / fseek() / fwrite() ) instead of the POSIX-specific stuff? ;-)

O_APPEND takes effect before each write to the file, not when opening file.

Therefore right after the open the position remains 0 but if you invoke write, the lseek on SEEK_CUR will return correct value.

Also, on Linux, your commented-out code won't work as you expect. This code:

 17         fd=openat(AT_FDCWD, "prwtest", O_CREAT | O_RDWR | O_APPEND);
 18         cur_offset=lseek(fd, 0, SEEK_CUR);
 19         pwrite(fd, buf1, strlen(buf1), 0);

will fail to write the contents of buf1 at the beginning of the file (unless the file is empty).

pwrite on Linux is buggy:

POSIX requires that opening a file with the O_APPEND flag should have no effect on the location at which pwrite() writes data. However, on Linux, if a file is opened with O_APPEND , pwrite() appends data to the end of the file, regardless of the value of offset .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM