readlink(2) - Linux 手册页

名称

readlink - 读取符号链接的值

概要

#include <unistd.h>

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

glibc 的功能测试宏要求(参见 feature_test_macros(7))

readlink():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_C_SOURCE >= 200112L

描述

readlink() 将符号链接 path 的内容放入缓冲区 buf 中,该缓冲区的大小为 bufsizreadlink() 不会在 buf 的末尾添加空字节。如果缓冲区太小而无法容纳所有内容,它将截断内容(截断为 bufsiz 个字符)。

返回值

成功时,readlink() 返回放置在 buf 中的字节数。发生错误时,返回 -1,并且 errno 会被设置为指示错误。

错误

EACCES

路径前缀的某个组件的搜索权限被拒绝。(请参阅 path_resolution(7)。)

EFAULT

buf 超出了进程分配的地址空间。

EINVAL

bufsiz 不是正数。

EINVAL

指定的文件不是符号链接。

EIO

在从文件系统读取时发生 I/O 错误。

ELOOP

在转换路径名时遇到过多的符号链接。

ENAMETOOLONG
路径名或路径名的一个组件太长。
ENOENT

指定的文件不存在。

ENOMEM

内核内存不足。

ENOTDIR
路径前缀的某个组件不是目录。

符合

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

说明

在 glibc 2.4 及更早版本中,readlink() 的返回类型声明为 int。现在,返回类型声明为 ssize_t,如 POSIX.1-2001 中(新)要求的。

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

示例

以下程序根据 lstat() 提供的信息动态分配 readlink() 所需的缓冲区,确保在两次调用之间没有竞争条件。

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

int
main(int argc, char *argv[])
{
    struct stat sb;
    char *linkname;
    ssize_t r;

   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);
    }

   linkname = malloc(sb.st_size + 1);
    if (linkname == NULL) {
        fprintf(stderr, "insufficient memory\n");
        exit(EXIT_FAILURE);
    }

   r = readlink(argv[1], linkname, sb.st_size + 1);

   if (r < 0) {
        perror("lstat");
        exit(EXIT_FAILURE);
    }

   if (r > sb.st_size) {
        fprintf(stderr, "symlink increased in size "
                        "between lstat() and readlink()\n");
        exit(EXIT_FAILURE);
    }

   linkname[sb.st_size] = '\0';

   printf("'%s' points to '%s'\n", argv[1], linkname);

   exit(EXIT_SUCCESS);
}

参见

readlink(1), lstat(2), readlinkat(2), stat(2), symlink(2), path_resolution(7), symlink(7)

引用自

canonicalize_file_name(3), explain(3), explain_readlink(3), explain_readlink_or_die(3), guestfish(1), guestfs(3), kpsereadlink(1), lslk(8), lsof(8), open_by_handle(3), pidof(8), proc(5), read(2), realpath(3), rpm(8), star(1)