1READLINK(2) Linux Programmer's Manual READLINK(2)
2
3
4
6 readlink, readlinkat - read value of a symbolic link
7
9 #include <unistd.h>
10
11 ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
12
13 #include <fcntl.h> /* Definition of AT_* constants */
14 #include <unistd.h>
15
16 ssize_t readlinkat(int dirfd, const char *pathname,
17 char *buf, size_t bufsiz);
18
19 Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
20
21 readlink():
22 _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
23 || /* Glibc versions <= 2.19: */ _BSD_SOURCE
24
25 readlinkat():
26 Since glibc 2.10:
27 _POSIX_C_SOURCE >= 200809L
28 Before glibc 2.10:
29 _ATFILE_SOURCE
30
32 readlink() places the contents of the symbolic link pathname in the
33 buffer buf, which has size bufsiz. readlink() does not append a null
34 byte to buf. It will (silently) truncate the contents (to a length of
35 bufsiz characters), in case the buffer is too small to hold all of the
36 contents.
37
38 readlinkat()
39 The readlinkat() system call operates in exactly the same way as read‐
40 link(), except for the differences described here.
41
42 If the pathname given in pathname is relative, then it is interpreted
43 relative to the directory referred to by the file descriptor dirfd
44 (rather than relative to the current working directory of the calling
45 process, as is done by readlink() for a relative pathname).
46
47 If pathname is relative and dirfd is the special value AT_FDCWD, then
48 pathname is interpreted relative to the current working directory of
49 the calling process (like readlink()).
50
51 If pathname is absolute, then dirfd is ignored.
52
53 Since Linux 2.6.39, pathname can be an empty string, in which case the
54 call operates on the symbolic link referred to by dirfd (which should
55 have been obtained using open(2) with the O_PATH and O_NOFOLLOW flags).
56
57 See openat(2) for an explanation of the need for readlinkat().
58
60 On success, these calls return the number of bytes placed in buf. (If
61 the returned value equals bufsiz, then truncation may have occurred.)
62 On error, -1 is returned and errno is set to indicate the error.
63
65 EACCES Search permission is denied for a component of the path prefix.
66 (See also path_resolution(7).)
67
68 EFAULT buf extends outside the process's allocated address space.
69
70 EINVAL bufsiz is not positive.
71
72 EINVAL The named file (i.e., the final filename component of pathname)
73 is not a symbolic link.
74
75 EIO An I/O error occurred while reading from the filesystem.
76
77 ELOOP Too many symbolic links were encountered in translating the
78 pathname.
79
80 ENAMETOOLONG
81 A pathname, or a component of a pathname, was too long.
82
83 ENOENT The named file does not exist.
84
85 ENOMEM Insufficient kernel memory was available.
86
87 ENOTDIR
88 A component of the path prefix is not a directory.
89
90 The following additional errors can occur for readlinkat():
91
92 EBADF dirfd is not a valid file descriptor.
93
94 ENOTDIR
95 pathname is relative and dirfd is a file descriptor referring to
96 a file other than a directory.
97
99 readlinkat() was added to Linux in kernel 2.6.16; library support was
100 added to glibc in version 2.4.
101
103 readlink(): 4.4BSD (readlink() first appeared in 4.2BSD), POSIX.1-2001,
104 POSIX.1-2008.
105
106 readlinkat(): POSIX.1-2008.
107
109 In versions of glibc up to and including glibc 2.4, the return type of
110 readlink() was declared as int. Nowadays, the return type is declared
111 as ssize_t, as (newly) required in POSIX.1-2001.
112
113 Using a statically sized buffer might not provide enough room for the
114 symbolic link contents. The required size for the buffer can be
115 obtained from the stat.st_size value returned by a call to lstat(2) on
116 the link. However, the number of bytes written by readlink() and read‐
117 linkat() should be checked to make sure that the size of the symbolic
118 link did not increase between the calls. Dynamically allocating the
119 buffer for readlink() and readlinkat() also addresses a common porta‐
120 bility problem when using PATH_MAX for the buffer size, as this con‐
121 stant is not guaranteed to be defined per POSIX if the system does not
122 have such limit.
123
124 Glibc notes
125 On older kernels where readlinkat() is unavailable, the glibc wrapper
126 function falls back to the use of readlink(). When pathname is a rela‐
127 tive pathname, glibc constructs a pathname based on the symbolic link
128 in /proc/self/fd that corresponds to the dirfd argument.
129
131 The following program allocates the buffer needed by readlink() dynami‐
132 cally from the information provided by lstat(2), falling back to a buf‐
133 fer of size PATH_MAX in cases where lstat(2) reports a size of zero.
134
135 #include <sys/types.h>
136 #include <sys/stat.h>
137 #include <limits.h>
138 #include <stdio.h>
139 #include <stdlib.h>
140 #include <unistd.h>
141
142 int
143 main(int argc, char *argv[])
144 {
145 struct stat sb;
146 char *buf;
147 ssize_t nbytes, bufsiz;
148
149 if (argc != 2) {
150 fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
151 exit(EXIT_FAILURE);
152 }
153
154 if (lstat(argv[1], &sb) == -1) {
155 perror("lstat");
156 exit(EXIT_FAILURE);
157 }
158
159 /* Add one to the link size, so that we can determine whether
160 the buffer returned by readlink() was truncated. */
161
162 bufsiz = sb.st_size + 1;
163
164 /* Some magic symlinks under (for example) /proc and /sys
165 report 'st_size' as zero. In that case, take PATH_MAX as
166 a "good enough" estimate. */
167
168 if (sb.st_size == 0)
169 bufsiz = PATH_MAX;
170
171 buf = malloc(bufsiz);
172 if (buf == NULL) {
173 perror("malloc");
174 exit(EXIT_FAILURE);
175 }
176
177 nbytes = readlink(argv[1], buf, bufsiz);
178 if (nbytes == -1) {
179 perror("readlink");
180 exit(EXIT_FAILURE);
181 }
182
183 printf("'%s' points to '%.*s'\n", argv[1], (int) nbytes, buf);
184
185 /* If the return value was equal to the buffer size, then the
186 the link target was larger than expected (perhaps because the
187 target was changed between the call to lstat() and the call to
188 readlink()). Warn the user that the returned target may have
189 been truncated. */
190
191 if (nbytes == bufsiz)
192 printf("(Returned buffer may have been truncated)\n");
193
194 free(buf);
195 exit(EXIT_SUCCESS);
196 }
197
199 readlink(1), lstat(2), stat(2), symlink(2), realpath(3), path_resolu‐
200 tion(7), symlink(7)
201
203 This page is part of release 5.07 of the Linux man-pages project. A
204 description of the project, information about reporting bugs, and the
205 latest version of this page, can be found at
206 https://www.kernel.org/doc/man-pages/.
207
208
209
210Linux 2020-06-09 READLINK(2)