truncate(2)
โจ truncate(2) โจ โ the System Calls Manual girlies know ๐
okay so bestie, welcome to truncate(2), straight out of the System Calls Manual ๐ this one is so useful and honestly kind of iconic, no cap.
๐ NAME
truncate, ftruncate โ truncate a file to a specified length. that's it, that's the whole gig ๐
๐ LIBRARY
Standard C library โ that's libc, link it with -lc ๐ซถ
๐งพ SYNOPSIS
#include <unistd.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
๐ง Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
lowkey don't forget these bestie, or your compiler will ghost you ๐ญ
truncate():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
|| /* glibc <= 2.19: */ _BSD_SOURCE
ftruncate():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.3.5: */ _POSIX_C_SOURCE >= 200112L
|| /* glibc <= 2.19: */ _BSD_SOURCE
๐ DESCRIPTION
so what do these two do?? literally exactly what it says on the tin, bestie. truncate() and ftruncate() cause the regular file named by path, or referenced by fd, to be truncated to a size of precisely length bytes. periodt โจ
if the file was previously larger than that size โ the extra data is gone, bestie, lost to the void ๐
if the file was previously shorter โ it gets extended, and the extended part reads as null bytes ('\0'). it's giving "stretch but hollow" ๐ฆ
the file offset is not changed. say it with me. not. changed. ๐
if the size actually changed, then the st_ctime and st_mtime fields get updated โ that's time of last status change and time of last modification respectively, and yes you should go read inode(7) if you wanna know more โ and heads up, the set-user-ID and set-group-ID mode bits may be cleared ๐
with ftruncate(), the file must be open for writing. with truncate(), the file must be writable. non-negotiable ๐ธ
๐ฏ RETURN VALUE
on success, zero is returned ๐ on error, -1 is returned, and errno is set to tell you what went wrong. vibe check failed, basically ๐ซ
๐ฅ ERRORS
๐ For truncate():
EACCESโ search permission is denied for a component of the path prefix, or the named file isn't writable by the user. (also seepath_resolution(7)) ๐ซEFAULTโ the argumentpathpoints outside the process's allocated address space. it's pointing at nothing, bestie ๐ญEFBIGโ the argumentlengthis larger than the maximum file size. (XSI)ENOSPCโ there is not enough space left on the device for extending the file size to the givenlength. the disk said no ๐EINTRโ while blocked waiting to complete, the call was interrupted by a signal handler; seefcntl(2)andsignal(7). rude interruption frEINVALโ the argumentlengthis negative or larger than the maximum file size.EIOโ an I/O error occurred updating the inode. yikes ๐ซEISDIRโ the named file is a directory. no ma'am, directories are not for truncating ๐ELOOPโ too many symbolic links were encountered in translating the pathname. symlink rabbit hole ๐ENAMETOOLONGโ a component of a pathname exceeded 255 characters, or an entire pathname exceeded 1023 characters. brevity is a virtue bestie โ๏ธENOENTโ the named file does not exist. ghosted ๐ปENOTDIRโ a component of the path prefix is not a directory.EPERMโ the underlying filesystem does not support extending a file beyond its current size.EPERMโ the operation was prevented by a file seal; seefcntl(2). sealed, like a limited-edition drop ๐EROFSโ the named file resides on a read-only filesystem.ETXTBSYโ the file is an executable file that is being executed. it's busy being the main character, do not touch ๐
๐ For ftruncate():
the same errors apply, except now instead of things that can be wrong with path, we have things that can be wrong with the file descriptor, fd ๐
EBADFโfdis not a valid file descriptor.EBADForEINVALโfdis not open for writing.EINVALโfddoes not reference a regular file or a POSIX shared memory object.EINVALorEBADFโ the file descriptorfdis not open for writing. POSIX permits, and portable applications should handle, either error for this case. (Linux producesEINVAL.) so write your code for both, bestie, that's the assignment ๐
๐ฐ๏ธ VERSIONS
the deets in DESCRIPTION are for XSI-compliant systems โจ for non-XSI-compliant systems, the POSIX standard allows two behaviors for ftruncate() when length exceeds the file length โ and btw, truncate() isn't specified at all in such an environment, so jot that down ๐ those two behaviors are: either returning an error, or extending the file. like most UNIX implementations, Linux follows the XSI requirement when dealing with native filesystems ๐ however โ some nonnative filesystems do not permit truncate() and ftruncate() to be used to extend a file beyond its current length: a notable example on Linux is VFAT. so if VFAT is being weird to you, now you know why ๐
also, on some 32-bit architectures, the calling signature for these system calls differs, for the reasons described in syscall(2). iykyk ๐ง
๐ STANDARDS
POSIX.1-2024. certified slay โ
๐ HISTORY
POSIX.1-2001, SVr4, 4.2BSD. ancient lore, we love an origin story ๐๏ธ
the original Linux truncate() and ftruncate() system calls were not designed to handle large file offsets, which is genuinely so embarrassing for them ๐ญ consequently, Linux 2.4 added truncate64() and ftruncate64() system calls that do handle large files. however โ applications using glibc can literally ignore all of this, because glibc's wrapper functions transparently employ the more recent system calls where they're available. transparent glow-up, we love to see it ๐
๐๏ธ NOTES
ftruncate() can also be used to set the size of a POSIX shared memory object; see shm_open(3) ๐ซถ multi-purpose icon behavior
๐ BUGS
a header file bug in glibc 2.12 meant that the minimum value of _POSIX_C_SOURCE required to expose the declaration of ftruncate() was 200809L instead of 200112L. ๐ญ this has been fixed in later glibc versions, so if you're on 2.12 specifically... girl. upgrade ๐ซ
๐ SEE ALSO
and that's the whole page, bestie!! ๐ธ this one came from Linux man-pages 6.20, dated 2026-04-12 โ go forth and truncate responsibly, mwah ๐ ๐โจ
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: BSD-4-Clause-UC
- Copyright 1983-1991, The Regents of the University of California
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms