备注

在包括glibc 2.4在内的glibc版本中,将readlink()的返回类型声明为int。如今,返回类型已声明为ssize_t,这是POSIX.1-2001中(新要求)的。

使用静态大小的缓冲区可能无法为符号链接内容提供足够的空间。缓冲区所需的大小可以从链接上对lstat(2)的调用返回的stat.st_size值中获得。但是,应该检查readlink()和readlinkat()写入的字节数,以确保符号链接的大小在两次调用之间没有增加。当使用PATH_MAX作为缓冲区大小时,为readlink()和readlinkat()动态分配缓冲区还解决了一个常见的可移植性问题,因为如果系统没有这样的限制,则不能保证每个POSIX都定义此常数。

Glibc notes

在无法使用readlinkat()的较旧内核上,glibc包装器功能将转而使用readlink()。如果路径名是相对路径名,则glibc将基于/ proc / self / fd中与dirfd参数相对应的符号链接构造路径名。

示例

以下程序从lstat(2)提供的信息中动态分配readlink()所需的缓冲区,在lstat(2)报告大小为零的情况下,回退到大小为PATH_MAX的缓冲区。

#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
    struct stat sb;
    char *buf;
    ssize_t nbytes, bufsiz;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    if (lstat(argv[1], &sb) == -1) {
        perror("lstat");
        exit(EXIT_FAILURE);
    }

    /* Add one to the link size, so that we can determine whether
       the buffer returned by readlink() was truncated. */

    bufsiz = sb.st_size + 1;

    /* Some magic symlinks under (for example) /proc and /sys
       report aqst_sizeaq as zero. In that case, take PATH_MAX as
       a "good enough" estimate. */

    if (sb.st_size == 0)
        bufsiz = PATH_MAX;

    buf = malloc(bufsiz);
    if (buf == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }

    nbytes = readlink(argv[1], buf, bufsiz);
    if (nbytes == -1) {
        perror("readlink");
        exit(EXIT_FAILURE);
    }

    printf("aq%saq points to aq%.*saq\n", argv[1], (int) nbytes, buf);

    /* If the return value was equal to the buffer size, then the
       the link target was larger than expected (perhaps because the
       target was changed between the call to lstat() and the call to
       readlink()). Warn the user that the returned target may have
       been truncated. */

    if (nbytes == bufsiz)
        printf("(Returned buffer may have been truncated)\n");

    free(buf);
    exit(EXIT_SUCCESS);
}
READLINK - Linux手册页

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

遵循规范

readlink():4.4BSD(readlink()首次出现在4.2BSD中),POSIX.1-2001,POSIX.1-2008。

readlinkat():POSIX.1-2008。

名称

readlink,readlinkat-读取符号链接的值

另外参见

readlink(1),lstat(2),stat(2),symlink(2),realpath(3),path_resolution(7),symlink(7)

出版信息

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

语法

#include <unistd.h>

ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

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

ssize_t readlinkat(int dirfd, const char *pathname,
                   char *buf, size_t bufsiz);

Feature Test Macro Requirements for glibc (see
feature_test_macros(7)):

readlink():

_XOPEN_SOURCE>= 500 || _POSIX_C_SOURCE>= 200112L || / * Glibc版本

readlinkat():

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

错误说明

EACCES
路径前缀的一部分的搜索权限被拒绝。 (另请参见path_resolution(7)。)
EFAULT
buf扩展到进程分配的地址空间之外。
EINVAL
bufsiz并不乐观。
EINVAL
命名文件(即路径名的最后文件名部分)不是符号链接。
EIO
从文件系统读取时发生I / O错误。
ELOOP
翻译路径名时遇到太多符号链接。
ENAMETOOLONG
路径名或路径名的组成部分太长。
ENOENT
命名文件不存在。
ENOMEM
内核内存不足。
ENOTDIR
路径前缀的组成部分不是目录。

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

EBADF
dirfd不是有效的文件描述符。
ENOTDIR
pathname是相对的,dirfd是引用目录以外的文件的文件描述符。

返回值

成功后,这些调用将返回放置在buf中的字节数。 (如果返回的值等于bufsiz,则可能发生了截断。)发生错误时,将返回-1并将errno设置为指示错误。

说明

readlink()将符号链接路径名的内容放入大小为bufsiz的缓冲区buf中。 readlink()不会将空字节附加到buf。如果缓冲区太小而无法容纳所有内容,它将(无提示)截断内容(长度为bufsiz字符)。

readlinkat()

readlinkat()系统调用的操作与readlink()完全相同,除了此处所述的区别。

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

如果路径名是相对的并且dirfd是特殊值AT_FDCWD,则路径名将相对于调用进程的当前工作目录进行解释(如readlink())。

如果路径名是绝对的,则dirfd被忽略。

从Linux 2.6.39开始,路径名可以为空字符串,在这种情况下,调用将在dirfd引用的符号链接上进行操作(该链接应该已使用带有O_PATH和O_NOFOLLOW标志的open(2)获得)。

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

版本

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

日期:2019-08-20 17:59:13 来源:oir作者:oir