truncate(2) - Linux 手册页
名称
truncate, ftruncate - 将文件截断为指定长度
概要
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
glibc 的功能测试宏要求(参见 feature_test_macros(7))
- truncate():
- _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* 自 glibc 2.12 起: */ _POSIX_C_SOURCE >= 200809L - ftruncate():
- _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* 自 glibc 2.3.5 起: */ _POSIX_C_SOURCE >= 200112L
描述
truncate() 和 ftruncate() 函数导致由 path 命名的或由 fd 引用的常规文件被截断为精确的 length 字节大小。
如果文件先前大于此大小,则多余的数据会丢失。如果文件先前小于此大小,则会扩展它,扩展的部分读作空字节 ('\0')。
文件偏移量不会改变。
如果大小已更改,则文件的 st_ctime 和 st_mtime 字段(分别是上次状态更改时间和上次修改时间;请参阅 stat(2))将被更新,并且设置用户 ID 和设置组 ID 的权限位可能会被清除。
对于 ftruncate(),文件必须以写入方式打开;对于 truncate(),文件必须可写。
返回值
成功时返回零。出错时返回 -1,并相应地设置 errno。
错误
对于 truncate()
- EACCES
路径前缀的某个组件拒绝了搜索权限,或者用户无法写入命名的文件。(另请参阅 path_resolution(7)。)
EFAULT
Path 指向进程分配地址空间之外的位置。
EFBIG
参数 length 大于最大文件大小。(XSI)
EINTR
在阻塞等待完成时,调用被信号处理程序中断;请参阅 fcntl(2) 和 signal(7)。
EINVAL
参数 length 为负数或大于最大文件大小。
EIO
更新 inode 时发生 I/O 错误。
EISDIR
命名的文件是一个目录。
ELOOP
在转换路径名时遇到过多的符号链接。
- ENAMETOOLONG
- 路径名的某个组件超过 255 个字符,或者整个路径名超过 1023 个字符。
- ENOENT
指定的文件不存在。
- ENOTDIR
- 路径前缀的某个组件不是目录。
- EPERM
基础文件系统不支持将文件扩展到其当前大小之外。
EROFS
指定的 文件位于只读文件系统上。
- ETXTBSY
- 该文件是一个正在执行的纯过程(共享文本)文件。
- 对于 ftruncate(),相同的错误适用,但与 path 可能出错的事情不同,现在我们有了文件描述符 fd 可能出错的事情
- EBADF
fd 不是有效的描述符。
- EBADF 或 EINVAL
- fd 未以写入方式打开。
- EINVAL
fd 不引用常规文件。
符合
4.4BSD, SVr4, POSIX.1-2001(这些调用首次出现在 4.2BSD 中)。
说明
DESCRIPTION 中的详细信息适用于符合 XSI 标准的系统。对于不符合 XSI 标准的系统,POSIX 标准允许两种行为,即当 length 超过文件长度时 ftruncate() 的行为(请注意,在这样的环境中根本没有指定 truncate()):要么返回错误,要么扩展文件。像大多数 UNIX 实现一样,Linux 在处理本机文件系统时遵循 XSI 要求。但是,某些非本机文件系统不允许使用 truncate() 和 ftruncate() 将文件扩展到其当前长度之外:Linux 上一个值得注意的例子是 VFAT。
原始 Linux truncate() 和 ftruncate() 系统调用并非设计用于处理大的文件偏移量。因此,Linux 2.4 添加了 truncate64() 和 ftruncate64() 系统调用,这些调用处理大文件。但是,使用 glibc 的应用程序可以忽略这些细节,因为 glibc 的包装函数会在可用时透明地使用更新的系统调用。
错误
glibc 2.12 中的一个头文件错误意味着暴露 ftruncate() 声明所需的 _POSIX_C_SOURCE 的最小值是 200809L 而不是 200112L。这已在后续的 glibc 版本中得到修复。
参见
open(2), stat(2), path_resolution(7)