--- name: link signature: 'link OLDFILE,NEWFILE' status: documented categories: ["Filehandles, files, directories"] --- ```{index} single: link; Perl built-in ``` *[Filehandles, files, directories](../perlfunc-by-category)* # link Create a hard link from `NEWFILE` to the existing `OLDFILE`. `link` adds a second directory entry that refers to the same underlying file as `OLDFILE`. After a successful call, the file has two names: `OLDFILE` and `NEWFILE`. Both names are equal citizens — the file itself is not deleted until every name is removed and no process holds the file open. The call is a thin wrapper around the [`link(2)`] system call and inherits its constraints: both paths must resolve on the **same filesystem**, and on POSIX systems only the superuser may hard- link a directory (most Linux kernels refuse even for `root`). ## Synopsis ```perl link OLDFILE, NEWFILE ``` ## What you get back `1` on success, `0` on failure. On failure, [`$!`](../perlvar) is set to the system error — typical values are `EXDEV` (cross-device link), `EPERM` (target is a directory, or filesystem forbids hard links), `EEXIST` (`NEWFILE` already exists), `EACCES` (insufficient permission), and `ENOENT` (`OLDFILE` missing). ```perl link $src, $dst or die "link $src -> $dst failed: $!"; ``` ## Global state it touches - [`$!`](../perlvar) — set on failure to the system error code. ## Examples Create a second name for an existing file: ```perl link "report.txt", "report.bak" or die "link failed: $!"; ``` Use [`stat`](stat) to observe the link count going up. The third element of the [`stat`](stat) list is the number of hard links pointing at the inode: ```perl link "data", "data.alt" or die $!; my $nlink = (stat "data")[3]; print "data has $nlink names\n"; # "data has 2 names" ``` Atomically replace a file by building the new version under a temporary name, then swapping with `link` + [`rename`](rename): ```perl open my $fh, ">", "config.new" or die $!; print $fh $new_contents; close $fh; rename "config.new", "config" or die "rename: $!"; ``` (For the genuinely atomic-under-crash variant you want `link` + [`unlink`](unlink) + `rename`; see the commentary in `perlport`.) Detect a cross-device failure and fall back to copying: ```perl use Errno qw(EXDEV); unless (link $src, $dst) { if ($! == EXDEV) { # /tmp and $HOME are typically different filesystems copy_file($src, $dst); } else { die "link $src -> $dst: $!"; } } ``` ## Edge cases - **Directories**: `link` on a directory fails with `EPERM` on effectively every modern system. POSIX forbids it for non-root, and Linux forbids it even for root. Use [`symlink`](symlink) when you want a second name for a directory. - **Cross-filesystem**: the kernel returns `EXDEV` if `OLDFILE` and `NEWFILE` resolve to different filesystems. Hard links cannot span mount points because they share an inode number, which is only meaningful within one filesystem. - **Existing target**: if `NEWFILE` already exists, the call fails with `EEXIST`. `link` never overwrites. Remove the target first with [`unlink`](unlink) if replacement is intended. - **Symbolic link as `OLDFILE`**: the link is made to the symlink's **target**, not to the symlink itself, on most systems. If you need to link the symlink, dereference it explicitly or use a platform that exposes `linkat` with `AT_SYMLINK_FOLLOW` cleared (not available through Perl core). - **Relative paths** are resolved against the current working directory at the moment of the call, for both operands. - **Permissions**: `link` does not require write permission on `OLDFILE` — only search permission on its directory and write permission on the directory containing `NEWFILE`. - **Same path both sides**: `link $f, $f` fails with `EEXIST`. - **Unlinking**: removing `OLDFILE` with [`unlink`](unlink) after a successful `link` leaves the file fully reachable through `NEWFILE`. The data is freed only when the last name is unlinked and no open file descriptor refers to it. - **Portability**: not every filesystem supports hard links. FAT, exFAT, and many network filesystems either refuse or silently behave as copies. See `perlport` for the platform matrix. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`symlink`](symlink) — create a symbolic link instead of a hard link; works across filesystems and on directories - [`unlink`](unlink) — remove a directory entry; the file itself survives as long as another link or open descriptor remains - [`rename`](rename) — move or rename a file within one filesystem; atomic where `link` + `unlink` is not - [`stat`](stat) — inspect the link count (field 3) to see how many names refer to the same inode - [`$!`](../perlvar) — the system error set when `link` returns `0` [`link(2)`]: https://man7.org/linux/man-pages/man2/link.2.html