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 中,该缓冲区的大小为 bufsiz。readlink() 不会在 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)