标题: 32-bits程序访问文件0x80000000及以上偏移
创建: 2016-12-10 14:09 更新: 2018-11-27 09:37 链接: https://scz.617.cn/unix/201612101409.txt
参看:
open(2) mmap(2) lseek(2) lseek64(3) feature_test_macros(7)
lseek()第2形参offset的数据类型是off_t。对于32-bits架构,off_t缺省对应32位 有符号整数,其最大值是0x7fffffff。如果我们需要在32-bits程序中访问0x80000000 及以上偏移,会遇上很多坑,而64-bits程序不存在这个问题。
我给个小结,为满足原始需求,有3种办法:
a)
define _FILE_OFFSET_BITS 64
open lseek read
这是推荐用法,此时不需要_GNU_SOURCE、_LARGEFILE64_SOURCE、O_LARGEFILE、 lseek64
b)
define _LARGEFILE64_SOURCE
open O_LARGEFILE lseek64 read
此时必须_LARGEFILE64_SOURCE、O_LARGEFILE、lseek64。假设已经O_LARGEFILE,但 不用lseek64,此时lseek不会报错,后面的read会报"Invalid argument"
O_LARGEFILE必须辅以lseek64。分两次lseek,不能解决问题。所谓分两次lseek,指
lseek( fd, ( off_t )0x7fffffff, SEEK_SET ) lseek( fd, ( off_t )(off-0x7fffffff), SEEK_CUR )
这种情况下,第二次lseek会报"Value too large for defined data type"
如果想直接使用lseek,应该定义_FILE_OFFSET_BITS宏
定义_GNU_SOURCE之后会隐式定义_LARGEFILE64_SOURCE
c)
open mmap memcpy
mmap的形参offset不需要_FILE_OFFSET_BITS宏,尽管其数据类型是off_t,open时也 不需要O_LARGEFILE,因此不需要_LARGEFILE64_SOURCE宏