Возвращаемое значение lseek()

Я запутался lseek()возвращаемое значение (новое смещение файла)

У меня есть текстовый файл (его имя prwtest). Его содержимое записано от a до z.

И код, который я написал, следующий,

  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 }

На номер строки 17Я использую флаг O_APPEND, поэтому текущее смещение файла prwtest берется из текущего размера файла i-узла. (Это 26).

На номер строки 18, Я использую lseek() который используется SEEK_CUR, а смещение равно 0.

Но результат значение cur_offset равно 0. (Я предполагаю, что это должно быть 26, потому что SEEK_CUR указывает текущее смещение файла.) Однако, SEEK_END дает мне то, что я думал, cur_offset 26

Почему lseek(fd, 0, SEEK_CUR); возвращает мне значение 0, а не 26?

3 ответа

Решение

Кроме того, в Linux ваш закомментированный код не будет работать так, как вы ожидаете. Этот код:

 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);

не сможет написать содержимое buf1 в начале файла (если файл не пуст).

pwrite на линуксе глючит:

ОШИБКИ

POSIX требует, чтобы открытие файла с O_APPEND Флаг не должен влиять на местоположение, в котором pwrite() пишет данные. Тем не менее, в Linux, если файл открывается с O_APPEND, pwrite() добавляет данные в конец файла, независимо от значения смещения.

Ваша проблема с open() / openat()не lseek(),

От open() manpage, акцент мой:

O_APPEND

Файл открывается в режиме добавления. Перед каждой записью (2) смещение файла помещается в конец файла, как будто с lseek(2).

Поскольку вы не записываете в файл, смещение никогда не перемещается в конец файла.


Пока мы на этом, вы должны закрыть файл перед завершением программы...


На самом деле, пока мы действительно на это, если вы делаете #include <stdio.h> почему бы не использовать стандартный ввод / вывод файлов (fopen() / fseek() / fwrite()) вместо POSIX-специфичных вещей?;-)

O_APPEND вступает в силу перед каждой записью в файл, а не при открытии файла.

Поэтому сразу после открытия позиция остается 0 но если вы вызываете написать, lseek на SEEK_CUR вернет правильное значение.

Другие вопросы по тегам