Недавно я столкнулся с проблемой, что 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?