вызов lseek () без включения "unistd.h" всегда возвращает -1 - PullRequest
0 голосов
/ 08 мая 2020

Недавно я столкнулся с проблемой, что lseek не работает. Ниже приведен упрощенный код:

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void main(int argc, char**argv){

  int fd;
  if ((fd = creat("file.hole", S_IRUSR|S_IWUSR)) < 0)
  {
       printf("creat error\n");
       return ;
  }
  off_t pos;
  pos = lseek(fd, 0, SEEK_CUR);
  printf("0 pos = %lld\n", pos);
  close(fd);
}

Во время компиляции проблем нет.

# gcc mem-test4.c -o mem-test4
# 

Также он работает, как ожидалось:

[develop] ~/gcc-test # ./mem-test4
0 pos = 0
[develop] ~/gcc-test # strace ./mem-test4
execve("./mem-test4", ["./mem-test4"], 0x7e8eeda0 /* 16 vars */) = 0
set_tls(0x76f48580, 0x7eca4be8, 0x37, 0x7eca4ea8, 0x76f484d8) = 0
set_tid_address(0x76f484f4)             = 772
mprotect(0x54baf000, 4096, PROT_READ)   = 0
open("file.hole", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0600) = 3
_llseek(3, 0, [0], SEEK_CUR)            = 0
ioctl(1, TIOCGWINSZ, {ws_row=59, ws_col=192, ws_xpixel=0, ws_ypixel=0}) = 0
writev(1, [{iov_base="0 pos = 0", iov_len=9}, {iov_base="\n", iov_len=1}], 20 pos = 0
) = 10
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
[develop] ~/gcc-test #

Но в моем коде , Я не включил "unistd.h".

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
//#include <unistd.h>

void main(int argc, char**argv){

  int fd;
  if ((fd = creat("file.hole", S_IRUSR|S_IWUSR)) < 0)
  {
       printf("creat error\n");
       return ;
  }
  off_t pos;
  pos = lseek(fd, 0, SEEK_CUR);
  printf("0 pos = %lld\n", pos);
  close(fd);
}

Он выдает предупреждение во время компиляции

[develop] ~/gcc-test # gcc mem-test4.c -o mem-test4
mem-test4.c: In function 'main':
mem-test4.c:15:13: warning: implicit declaration of function 'lseek' [-Wimplicit-function-declaration]
   pos = lseek(fd, 0, SEEK_CUR);
         ^~~~~
mem-test4.c:17:7: warning: implicit declaration of function 'close' [-Wimplicit-function-declaration]
   close(fd);
   ^~~~~
[develop] ~/gcc-test #

Он не сообщает об ошибках ссылки, поэтому я игнорирую предупреждения. Но результат теста неверен, lseek () всегда возвращает -1.

[develop] ~/gcc-test # ./mem-test4
0 pos = -1
[develop] ~/gcc-test # strace ./mem-test4
execve("./mem-test4", ["./mem-test4"], 0x7efcfda0 /* 16 vars */) = 0
set_tls(0x76f1e580, 0x7e8c7be8, 0x37, 0x7e8c7ea8, 0x76f1e4d8) = 0
set_tid_address(0x76f1e4f4)             = 789
mprotect(0x54ac0000, 4096, PROT_READ)   = 0
open("file.hole", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0600) = 3
_llseek(3, 12884901889, 0x7e8c7d38, 0x7e8c7da4 /* SEEK_??? */) = -1 EINVAL (Invalid argument)
ioctl(1, TIOCGWINSZ, {ws_row=59, ws_col=192, ws_xpixel=0, ws_ypixel=0}) = 0
writev(1, [{iov_base="0 pos = -1", iov_len=10}, {iov_base="\n", iov_len=1}], 20 pos = -1
) = 11
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
[develop] ~/gcc-test #

Из strace он вызывает системный api _llseek, но параметр кажется странным. Итак, для более позднего кода он должен был вызвать некоторую библиотечную функцию, а затем косвенно вызвать _llseek (). Но почему параметр неверен?

Это нормально, что компилятор выдает предупреждение о «неявном объявлении функции», и нам не всегда нужно это исправлять. В таком случае, как избежать этой проблемы с lseek?

...