Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rename(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)rename: x64 82 / i386 38 / arm64-generic none / arm32 38; renameat: x64 264 / i386 302 / arm64-generic none / arm32 329; renameat2: x64 316 / i386 353 / arm64-generic 276 / arm32 382
Since (kernel)rename 1.0 (POSIX API, 4.3BSD lineage); renameat 2.6.16; renameat2 3.15 (man VERSIONS)
Man pageman2/rename.2 covers all three (local cache, dated 2021-08-27); renameat.2 / renameat2.2 are roff .so aliases
glibc wrapperYes; rename() / renameat() in <stdio.h> (renameat glibc 2.4, _POSIX_C_SOURCE >= 200809L since 2.10); renameat2() glibc 2.28 under _GNU_SOURCE
Aliases coveredrenameat (SC-renameat), renameat2 (SC-renameat2) – RENAME_* flags documented here per task spec
Ledger IDSC-rename

Purpose

rename() changes the name or location of a file, atomically replacing newpath if it exists: another process never observes newpath missing, though a window can exist where both names refer to the file. Hard links and open file descriptors to oldpath are unaffected. renameat() adds two dirfd-relative path resolutions; renameat2() adds a flags word, and a zero-flags renameat2() equals renameat(). The asm-generic table has only renameat2 (276); the plain and renameat numbers are absent on arm64-generic (hub / worklog 1-d).

Synopsis

#include <stdio.h>
int rename(const char *oldpath, const char *newpath);

#include <fcntl.h>      /* AT_* constants */
#include <stdio.h>
int renameat(int olddirfd, const char *oldpath,
             int newdirfd, const char *newpath);
int renameat2(int olddirfd, const char *oldpath,
              int newdirfd, const char *newpath, unsigned int flags);

Arguments and behavior

renameat() applies the *at() convention to both paths (absolute paths ignore the dirfd; AT_FDCWD; relative paths resolve against the dirfd). Renaming a directory requires newpath to be nonexistent or an empty directory; renaming onto an existing directory of the wrong type fails with EISDIR. If oldpath and newpath are hard links to the same file, the call succeeds without doing anything. If the operation fails after newpath existed, an instance of newpath is guaranteed to remain. Renaming across filesystems fails with EXDEV; glibc’s renameat() wrapper falls back to rename() via /proc/self/fd symlinks on kernels without renameat (Glibc notes).

Flags and constants (renameat2)

FlagValueSinceMeaning
RENAME_NOREPLACE1<<03.15Fail with EEXIST instead of overwriting newpath; atomic create-if-absent. Incompatible with RENAME_EXCHANGE. Needs filesystem support: ext4 3.15; btrfs, tmpfs, cifs 3.17; xfs 4.0; many more (ext2, reiserfs, jfs, vfat, …) 4.9
RENAME_EXCHANGE1<<13.15Atomically exchange oldpath and newpath; both must exist and may be of different types (e.g. non-empty directory vs symlink)
RENAME_WHITEOUT1<<23.18Rename and leave a “whiteout” at the source atomically; meaningful for overlay/union layers; outside overlays it appears as a character device {0,0}; needs CAP_MKNOD like mknod; fs support: tmpfs 3.18, ext4 3.18, xfs 4.1, f2fs 4.2, btrfs 4.7, ubifs 4.9. Incompatible with RENAME_EXCHANGE

Return value and errors

Returns 0 on success, -1 on error with errno set. Errors per the man page: EACCES (write permission on source/target directory or search permission in a prefix), EBUSY (directory in use as cwd/root/mount point and the system chooses to report it), EDQUOT, EFAULT, EINVAL (newpath is a path prefix of oldpath), EISDIR, ELOOP, EMLINK, ENAMETOOLONG, ENOENT, ENOMEM, ENOSPC, ENOTDIR, ENOTEMPTY / EEXIST (target a non-empty directory), EPERM / EACCES (sticky-bit S_ISVTX rules failing CAP_FOWNER; unsupported rename type), EROFS, EXDEV, and EINVAL / ENOSYS / EOPNOTSUPP for unsupported or conflicting renameat2 flags on filesystems lacking support.

Security and notes

Ordinary filesystem permissions govern the call; RENAME_WHITEOUT requires CAP_MKNOD. The sticky-bit rules make /tmp-style directories safe for renaming entries owned by other users. BUGS section: on NFS, a rename may have taken effect server-side even when the call reports failure (retransmitted RPC after a server crash). Watch-related filesystem events surface through inotify – see inotify_init.md; mount-point interactions with the mount API live in mount.md.

References

  • Cached man page: source-cache/man-pages-sparse/man2/rename.2, .so aliases renameat.2, renameat2.2
  • Online: https://man7.org/linux/man-pages/man2/rename.2.html
  • Kernel tables: source-cache/kernel/syscall_64.tbl (82, 264, 316), syscall_generic.tbl (276)
  • Constants: RENAME_* in installed <linux/fs.h> / glibc <stdio.h> gates