为什么lseek允许我设置负文件位置?

时间:2013-10-12 20:53:50

标签: c linux

如果结果文件偏移量对于常规文件为负,那么man条目lseek应该返回-1

为什么这样的代码有效?

int fd;
off_t offset;

fd = open("test.txt", O_RDWR);
offset = lseek(fd, -10, SEEK_SET);

printf("%d\n", offset);                // prints -10

if (offset == (off_t) -1)
    perror("seek");                    // error not triggered

我觉得我应该将offset=-1errno设置为EINVAL

这也会导致文件大小显得非常大(接近无符号整数的大小) - 似乎是一个溢出问题。那是为什么?

2 个答案:

答案 0 :(得分:11)

我设法重现了你的“错误”行为。您必须包含unistd.h才能获得正确的原型。使用此包含,lseek的行为与描述相同。

当您错过此包含时,编译器会传递 int -10而不是off_t -10。这会导致您观察到的行为。

更新

所需包含的完整列表是

  • open(2)

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
  • lseek(2)

    #include <sys/types.h>
    #include <unistd.h>
    
  • printf(3)perror(3)

    #include <stdio.h>
    

答案 1 :(得分:3)

  

在某些实现中,负文件偏移对某些设备可能有效。

POSIX.1-1990标准没有specifically prohibit lseek() from returning a negative offset。因此,需要应用程序在调用之前清除errno并在返回时检查errno以确定返回值( off_t)-1是负偏移还是错误条件的指示。

标准开发人员不希望在符合要求的应用程序中要求此操作,并且当所得文件偏移对于常规文件为负时,选择要求将errno设置为[EINVAL],阻止特殊文件或目录。

请参阅lseek