另外参见

ln(1),open(2),重命名(2),stat(2),symlink(2),unlink(2),path_resolution(7),symlink(7)

说明

link()创建到现有文件的新链接(也称为硬链接)。

如果newpath存在,它将不会被覆盖。

对于任何操作,此新名称都可以与旧名称完全相同。这两个名称都引用相同的文件(因此具有相同的权限和所有权),并且无法确定哪个名称是"原始"文件。

linkat()

除了此处描述的差异外,linkat()系统调用的操作方式与link()完全相同。

如果oldpath中给定的路径名​​是相对的,则它相对于文件描述符olddirfd所引用的目录进行解释(而不是相对于调用进程的当前工作目录,如相对路径名的link()所做的那样) 。

如果oldpath是相对的,而olddirfd是特殊值AT_FDCWD,则将oldpath相对于调用进程的当前工作目录进行解释(如link())。

如果oldpath是绝对路径,则将忽略olddirfd。

newpath的解释与oldpath的解释相同,只是相对路径名是相对于文件描述符newdirfd引用的目录解释的。

下列值可以在标志中按位或:

AT_EMPTY_PATH(since Linux 2.6.39)
如果oldpath是一个空字符串,请创建一个指向olddirfd引用的文件的链接(该链接可能已使用open(2)O_PATH标志获得了)。在这种情况下,olddirfd可以引用目录以外的任何类型的文件。如果文件的链接计数为零,则通常将不起作用(使用O_TMPFILE创建且没有O_EXCL的文件是例外)。调用者必须具有CAP_DAC_READ_SEARCH功能才能使用此标志。该标志是特定于Linux的。定义_GNU_SOURCE以获得其定义。
AT_SYMLINK_FOLLOW(since Linux 2.6.18)
默认情况下,如果linkat()是符号链接(例如link()),则不会取消引用oldpath。如果标志AT_SYMLINK_FOLLOW是符号链接,则可以在标志中指定该标志,以使旧路径被取消引用。如果安装了procfs,则可以将其用作AT_EMPTY_PATH的替代方法,如下所示:
linkat(AT_FDCWD, "/proc/self/fd/<fd>", newdirfd,
       newname, AT_SYMLINK_FOLLOW);

在内核2.6.18之前,flags参数尚未使用,必须指定为0。

有关openat()需求的说明,请参见openat(2)。

遵循规范

link():SVr4、4.3BSD,POSIX.1-2001(但请参阅注释),POSIX.1-2008。

linkat():POSIX.1-2008。

返回值

成功时,返回零。如果出错,则返回-1,并正确设置errno。

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

BUGS

在NFS文件系统上,如果NFS服务器执行链接创建并在其声明之前死亡,则返回码可能是错误的。使用stat(2)来查找是否已创建链接。

名称

link,linkat-为文件命名

语法

#include <unistd.h>

int link(const char *oldpath, const char *newpath);

#include <fcntl.h>           /* Definition of AT_* constants */
#include <unistd.h>

int linkat(int olddirfd, const char *oldpath,
           int newdirfd, const char *newpath, int flags);

glibc的功能测试宏要求(请参阅feature_test_macros(7)):

linkat():

Since glibc 2.10:
_POSIX_C_SOURCE>= 200809L
Before glibc 2.10:
_ATFILE_SOURCE

版本

linkat()在内核2.6.16中添加到Linux;库支持已添加到版本2.4中的glibc。

错误说明

EACCES
对包含newpath的目录的写访问被拒绝,或者对oldpath或newpath的路径前缀中的目录之一的搜索权限被拒绝。 (另请参见path_resolution(7)。)
EDQUOT
用户在文件系统上的磁盘块配额已用尽。
EEXIST
newpath已经存在。
EFAULT
oldpath或newpath指向您可访问的地址空间之外的位置。
EIO
发生I / O错误。
ELOOP
解决oldpath或newpath时遇到太多符号链接。
EMLINK
oldpath引用的文件已具有最大数量的链接。例如,在不使用dir_index功能的ext4(5)文件系统上,对文件的硬链接数的限制为65,000;对于文件,则为65,000。在btrfs(5)上,限制为65,535个链接。
ENAMETOOLONG
oldpath或newpath太长。
ENOENT
oldpath或newpath中的目录组件不存在,或者是悬挂的符号链接。
ENOMEM
内核内存不足。
ENOSPC
包含文件的设备没有空间容纳新目录条目。
ENOTDIR
实际上,在oldpath或newpath中用作目录的组件不是目录。
EPERM
oldpath是一个目录。
EPERM
包含oldpath和newpath的文件系统不支持硬链接的创建。
EPERM(since Linux 3.6)
调用者无权创建与此文件的硬链接(请参见proc(5)中对/ proc / sys / fs / protected_hardlinks的描述)。
EPERM
oldpath被标记​​为不可变或仅附加。 (请参阅ioctl_iflags(2)。)
EROFS
该文件位于只读文件系统上。
EXDEV
oldpath和newpath不在同一挂载的文件系统上。 (Linux允许在多个点上挂载文件系统,但是即使两个文件上都挂载了相同的文件系统,link()也无法跨不同的挂载点工作。)

linkat()可能会发生以下其他错误:

EBADF
olddirfd或newdirfd不是有效的文件描述符。
EINVAL
在标志中指定了无效的标志值。
ENOENT
在标志中指定了AT_EMPTY_PATH,但是调用者没有CAP_DAC_READ_SEARCH功能。
ENOENT
试图链接到/ proc / self / fd / NN文件,该文件对应于使用以下命令创建的文件描述符
打开(路径,O_TMPFILE || O_EXCL,模式);
参见open(2)。
ENOENT
oldpath是相对路径名,而olddirfd是已删除的目录,或者newpath是相对路径名,而newdirfd是已删除的目录。
ENOTDIR
oldpath是相对的,而olddirfd是引用目录以外的文件的文件描述符;或类似的newpath和newdirfd
EPERM
在标志中指定了AT_EMPTY_PATH,oldpath是一个空字符串,而olddirfd引用了一个目录。
LINK - Linux手册页

Linux程序员手册 第2部分
更新日期: 2017-09-15

备注

link()创建的硬链接不能跨越文件系统。如果需要,请使用symlink(2)。

POSIX.1-2001说,如果link()是符号链接,则应该取消引用oldpath。但是,从内核2.0开始,Linux不会这样做:如果oldpath是符号链接,则newpath会创建为指向同一符号链接文件的(硬)链接(即newpath成为指向oldpath引用的同一文件的符号链接)至)。其他一些实现的行为与Linux相同。 POSIX.1-2008更改了link()的规范,如果它是符号链接,则是否取消对oldpath的引用使其取决于实现。为了在创建链接时精确控制符号链接的处理,请使用linkat()。

Glibc notes

在无法使用linkat()的较旧内核上,除非指定了AT_SYMLINK_FOLLOW,否则glibc包装器函数将转而使用link()。当oldpath和newpath是相对路径名时,glibc基于/ proc / self / fd中与olddirfd和newdirfd参数相对应的符号链接构造路径名。

日期:2019-08-20 17:58:56 来源:oir作者:oir