---
name: "linkat"
section: "2"
platform: "macos"
package: "xnu"
version: "12377.121.6"
release: "macOS 26.5"
platforms: ["linux", "freebsd", "macos"]
url: "https://new.carta.tech/link/2"
---

# linkat(2)

make a hard file link

Part of [link(2)](/link/2.md).

## NAME

**link**, **linkat** – make a hard file link

## SYNOPSIS

**#include \<unistd.h\>**

*int*\

**link**(*const char \*path1*, *const char \*path2*);

*int*\

**linkat**(*int fd1*, *const char \*name1*, *int fd2*, *const char \*name2*, *int flag*);

## DESCRIPTION

The **link**() function call atomically creates the specified directory entry (hard link) *path2* with the attributes of the underlying object pointed at by *path1*. If the link is successful, the link count of the underlying object is incremented; *path1* and *path2* share equal access and rights to the underlying object.

If *path1* is removed, the file *path2* is not deleted and the link count of the underlying object is decremented.

In order for the system call to succeed, *path1* must exist and both *path1* and *path2* must be in the same file system. As mandated by POSIX.1, *path1* may not be a directory.

**link**() will resolve and follow symbolic links contained within both *path1* and *path2*. If the last component of *path1* is a symbolic link, **link**() will point the hard link,  *path2*, to the underlying object pointed to by *path1*, not to the symbolic link itself.

The **linkat**() system call is equivalent to *link* except in the case where either *name1* or *name2* or both are relative paths. In this case a relative path *name1* is interpreted relative to the directory associated with the file descriptor *fd1* instead of the current working directory and similarly for *name2* and the file descriptor *fd2*.

Values for *flag* are constructed by a bitwise-inclusive OR of flags from the following list, defined in ⟨fcntl.h⟩:

- AT\_SYMLINK\_FOLLOW

  If *name1* names a symbolic link, a new link for the target of the symbolic link is created.

- AT\_SYMLINK\_NOFOLLOW\_ANY

  If *name1* names a symbolic link, a new link for the symbolic link is created. If a symbolic link is encountered during pathname resolution, an error is returned.

- AT\_RESOLVE\_BENEATH

  If *name1* does not reside in the hierarchy beneath the starting directory, an error is returned.

- AT\_UNIQUE

  If *name1* resolves to a vnode with multiple hard links, an error is returned.

If **linkat**() is passed the special value AT\_FDCWD in the *fd1* or *fd2* parameter, the current working directory is used for the respective *name* argument. If both *fd1* and *fd2* have value AT\_FDCWD, the behavior is identical to a call to **link**(). Unless *flag* contains the AT\_SYMLINK\_FOLLOW, AT\_SYMLINK\_NOFOLLOW\_ANY, AT\_RESOLVE\_BENEATH or the AT\_UNIQUE flags. On OS X, not assigning AT\_SYMLINK\_FOLLOW, AT\_SYMLINK\_NOFOLLOW\_ANY, AT\_RESOLVE\_BENEATH or AT\_UNIQUE to *flag* may result in some file systems returning an error.

## RETURN VALUES

Upon successful completion, a value of 0 is returned.  Otherwise, a value of -1 is returned and *errno* is set to indicate the error.

## ERRORS

**link**() will fail and no link will be created if:

- \[EACCES\]

  A component of either path prefix denies search permission.

- \[EACCES\]

  The requested link requires writing in a directory with a mode that denies write permission.

- \[EACCES\]

  The current process cannot access the existing file.

- \[EDQUOT\]

  The directory in which the entry for the new 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.

- \[EEXIST\]

  The link named by *path2* already exists.

- \[EFAULT\]

  One of the pathnames specified is outside the process's allocated address space.

- \[EIO\]

  An I/O error occurs while reading from or writing to  the file system to make the directory entry.

- \[ELOOP\]

  Too many symbolic links are encountered in translating one of the pathnames. This is taken to be indicative of a looping symbolic link.

- \[EMLINK\]

  The file already has {LINK\_MAX} links.

- \[ENAMETOOLONG\]

  A component of a pathname exceeds  {NAME\_MAX} characters, or an entire path name exceeded  {PATH\_MAX} characters.

- \[ENOENT\]

  A component of either path prefix does not exist, or is a dangling symbolic link.

- \[ENOENT\]

  The file named by *path1* does not exist, or is a dangling symbolic link.

- \[ENOSPC\]

  The directory in which the entry for the new link is being placed cannot be extended because there is no space left on the file system containing the directory.

- \[ENOTDIR\]

  A component of either path prefix is not a directory.

- \[EPERM\]

  The file named by *path1* is a directory.

- \[EROFS\]

  The requested link requires writing in a directory on a read-only file system.

- \[EXDEV\]

  The link named by *path2* and the file named by *path1* are on different file systems.

- \[EDEADLK\]

  The file named by *path1* is a “dataless” file that must be materialized before being linked and the I/O policy of the current thread or process disallows file materialization (see [getiopolicy\_np(3)](/getiopolicy_np/3.md)).

In addition to the errors returned by the **link**(), the **linkat**() system call may fail if:

- \[EBADF\]

  The *name1* or *name2* argument does not specify an absolute path and the *fd1* or *fd2* argument, respectively, is neither AT\_FDCWD nor a valid file descriptor open for searching.

- \[EINVAL\]

  The value of the *flag* argument is not valid.

- \[ENOTSUP\]

  *flag* was not set to AT\_SYMLINK\_FOLLOW (some file systems only).

- \[ENOTSUP\]

  The underlying file system does not support this call.

- \[ENOTDIR\]

  The *name1* or *name2* argument is not an absolute path and *fd1* or *fd2*, respectively, is neither AT\_FDCWD nor a file descriptor associated with a directory.

- \[ELOOP\]

  If AT\_SYMLINK\_NOFOLLOW\_ANY was passed and a symbolic link was encountered in translating either the *name1* or *name2* arguments.

- \[ENOTCAPABLE\]

  AT\_RESOLVE\_BENEATH was passed and *path* does not reside in the directory hierarchy beneath the starting directory encountered in translating either the *name1* or *name2* arguments.

- \[ENOTCAPABLE\]

  The flag parameter has the AT\_UNIQUE bit set and *name1* resolves to a vnode with multiple links.

## SEE ALSO

[symlink(2)](/symlink/2.md), [unlink(2)](/unlink/2.md)

## STANDARDS

The **link**() function is expected to conform to  IEEE Std 1003.1-1988 (“POSIX.1”). The **linkat**() system call is expected to conform to POSIX.1-2008 .
