在OSX 10.6上,pwrite()函数不能正确处理64位偏移量。

3
我在尝试使用pwrite()写入超过2GB偏移量的内容时,在OSX 10.6.8上遇到了一个奇怪的问题。我一直捕获到一个SIGXFSZ信号,意味着文件大小限制已经超过了。忽略该信号是无效的,因为pwrite()将简单地返回EFBIG
看起来OSX不支持显式的open64()pwrite64()函数。同时,sizeof(off_t)的大小为8个字节,这意味着pwrite()应该接受64位的偏移量。在调用open()时是否有我漏掉的标志,或者我应该向fcntl()传递哪些OSX特定的设置来启用大文件支持?
最后,当我使用RLIMIT_FSIZE选项检查getrlimit()时,它显示当前和最大文件大小限制均为9223372036854775807字节。因此,这似乎并没有阻止我通过pwrite()写入大文件。
在64位的OSX下,还有其他人遇到过pwrite()的问题吗?
编辑:根据要求,我添加了调用pwrite()的代码...请注意,此代码位于写线程内部:
for (int i=0; i < data->iterations; i++)
{
    unsigned char* ptr = data->buffer;
    int temp_buff_size = data->buff_size;
    int offset = i * data->buff_size;

    while(temp_buff_size > 0)
    {
        int temp_bytes_written = pwrite(data->fd, ptr, temp_buff_size, offset);

        if (temp_bytes_written >= 0)
        {
            temp_buff_size -= temp_bytes_written;
            ptr += temp_bytes_written;
            offset += temp_bytes_written;
        }
        else if (errno == EINTR)
        {
            continue;
        }
        else
        {
            perror("Write thread exiting");
            write_thread_finished = 1;
                return (void*)-1;
        }
    }
}

我在循环中调用它,因为我理解 pwrite() 不能保证写入所有请求的数据,所以我需要确保我请求写入的数据实际上已经写入到磁盘上。如果写入的字节数较少,那么我就会适当地偏移要写入的缓冲区,以将其余部分写入磁盘。 data->iterations 的作用只是向线程传递有关要将缓冲区写入磁盘多少次的信息...这是带宽测试的一部分,因此我正在尝试写入一个大文件,以了解它能够被写入磁盘的速度有多快。唯一的问题是,我无法向 pwrite() 传递大于2GB的偏移量。


为什么不给我们展示调用 pwrite 的代码呢? - Gabe
2
我不了解OSX,但是即使在64位系统上,int仍然保持在32位吗?所以当有符号整数溢出为负数时,你尝试在负偏移处写入? - Some programmer dude
2
正如@JoachimPileborg所指出的,并且正如pwrite的签名所示,您应该使用size_t来表示大小,使用off_t来表示偏移量。 - user7116
@JoachimPileborg:就是这样... 把它作为答案写下来,我会接受它作为官方答案。 - Jason
1个回答

8
在OSX上,即使是64位系统,int仍然保持在32位。因此,当有符号整数溢出为负数时,您将尝试以负偏移量进行写入。 编辑:根据手册,正确的类型是off_t,无论底层操作系统是32位还是64位,它都应具有正确的大小和符号性。

1
@R.. 当我看到代码时,它很容易。特别是因为我今天早些时候在64位系统上混合使用了int/long类型。 :) - Some programmer dude
3
顺便提一句,如果您提及变量 offset 应该具有类型 off_t,那么答案会更好。 - R.. GitHub STOP HELPING ICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接