SYMLINK(2)

okay so. you opened the System Calls Manual (that's the manual name, it lives in section 2, syscalls only, no cap) and you landed on symlink. bestie, you are about to make a link that is literally symbolic. not a hard link. a vibe. let's go. πŸ¦‹


✨ NAME ✨

symlink, symlinkat β€” make symbolic link to a file

πŸ“š LIBRARY πŸ“š

Standard C Library (libc, -lc)


🌸 SYNOPSIS 🌸

like, here's the whole thing, copy it exactly, don't freestyle:

#include <unistd.h>

int
symlink(const char *name1, const char *name2);

int
symlinkat(const char *name1, int fd, const char *name2);

πŸ’… DESCRIPTION πŸ’…

So. A symbolic link name2 is created to name1. And before you get confused (everyone does, it's fine, breathe): name2 is the name of the file being created, and name1 is the string used in creating the symbolic link. The way that the "new thing" is name2 and the "thing it points at" is name1? iconic. slightly chaotic. we love her. πŸ™ˆ

Either name can be an arbitrary path name β€” go feral, no rules β€” and the files do not have to live on the same file system. cross-filesystem? she doesn't care. main character energy. ✨

Now. symlinkat() is the same girl as symlink() except in one specific case: when name2 specifies a relative path. In that case, the symbolic link gets created relative to the directory associated with the file descriptor fd instead of the current working directory. cute, right? πŸŽ€

And if you pass symlinkat() the special value AT_FDCWD in the fd parameter? Then the current working directory is used and the behavior is identical to a call to symlink(). fr fr, same thing.


πŸ”₯ RETURN VALUES πŸ”₯

symlink() returns the value 0 if it ate and left no crumbs (successful). Otherwise the value -1 comes back and the global variable errno is set to indicate the error. 😭 the -1 is never good news.


πŸ’€ ERRORS πŸ’€

The symbolic link succeeds unless β€” and girl, there are so many unlesses:

  • [ENOTDIR] β€” a component of the name2 path prefix is not a directory. rude.
  • [ENAMETOOLONG] β€” a component of the name2 pathname exceeded 255 characters, or the entire length of either path name exceeded 1023 characters. she said too long, bestie πŸ’€
  • [ENOENT] β€” a component of the name2 path prefix does not exist. she's not there. ghosted.
  • [EACCES] β€” a component of the name2 path prefix denies search permission, or write permission is denied on the parent directory of the file to be created.
  • [ELOOP] β€” too many symbolic links were encountered in translating the name2 path name. it's giving infinite hallway πŸ˜΅πŸ’«
  • [EEXIST] β€” the path name pointed at by the name2 argument already exists. she's taken!!
  • [EPERM] β€” the parent directory of the file named by name2 has its immutable flag set. see the chflags(2) manual page for more information. that directory is not accepting applications. 🚫
  • [EIO] β€” an I/O error occurred while making the directory entry for name2, allocating the inode for name2, or writing out the link contents of name2.
  • [EROFS] β€” the file name2 would reside on a read-only file system. no writes allowed, periodt.
  • [ENOSPC] β€” the directory in which the entry for the new symbolic link is being placed cannot be extended because there is no space left on the file system containing the directory.
  • [ENOSPC] β€” the new symbolic link cannot be created because there is no space left on the file system that will contain the symbolic link.
  • [ENOSPC] β€” there are no free inodes on the file system on which the symbolic link is being created. (yes, three separate ENOSPC situations. she contains multitudes.)
  • [EDQUOT] β€” the directory in which the entry for the new symbolic link is being placed cannot be extended because the user's quota of disk blocks on the file system containing the directory has been exhausted.
  • [EDQUOT] β€” the new symbolic link cannot be created because the user's quota of disk blocks on the file system that will contain the symbolic link has been exhausted.
  • [EDQUOT] β€” the user's quota of inodes on the file system on which the symbolic link is being created has been exhausted. quota said enough 🫢
  • [EINTEGRITY] β€” corrupted data was detected while reading from the file system. she's not okay, and neither is the disk. 😭
  • [EFAULT] β€” the name1 or name2 argument points outside the process's allocated address space. out of bounds, out of pocket.

On top of all the errors symlink() returns, symlinkat() may also fail if:

  • [EBADF] β€” the name2 argument does not specify an absolute path and the fd argument is neither AT_FDCWD nor a valid file descriptor open for searching.
  • [ENOTDIR] β€” the name2 argument is not an absolute path and fd is neither AT_FDCWD nor a file descriptor associated with a directory.
pro tip from your girl: errno is the group chat. read it immediately after the -1 or the messages get marked as read and you'll never know what happened. πŸ’…

πŸ‘€ SEE ALSO πŸ‘€

ln(1), chflags(2), link(2), lstat(2), readlink(2), unlink(2), symlink(7)

iykyk, go read them, they're all besties.


⭐ STANDARDS ⭐

The symlinkat() system call follows The Open Group Extended API Set 2 specification. she's certified. she's got paperwork. πŸ“œ


🌈 HISTORY 🌈

  • The symlink() system call appeared in 4.2BSD. an elder. a legend. πŸ‘‘
  • The symlinkat() system call appeared in FreeBSD 8.0.

and that's the whole page, bestie. no cap, every flag, every errno, every vibe β€” all preserved. this gorgeous little page came to you via Debian and is dated March 30, 2020, and it's the SYMLINK(2) entry in the System Calls Manual. go make some links. slay. πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from