Blame man2/readlink.2

Packit 7cfc04
.\" Copyright (c) 1983, 1991 The Regents of the University of California.
Packit 7cfc04
.\" And Copyright (C) 2011 Guillem Jover <guillem@hadrons.org>
Packit 7cfc04
.\" And Copyright (C) 2006, 2014 Michael Kerrisk
Packit 7cfc04
.\" All rights reserved.
Packit 7cfc04
.\"
Packit 7cfc04
.\" %%%LICENSE_START(BSD_4_CLAUSE_UCB)
Packit 7cfc04
.\" Redistribution and use in source and binary forms, with or without
Packit 7cfc04
.\" modification, are permitted provided that the following conditions
Packit 7cfc04
.\" are met:
Packit 7cfc04
.\" 1. Redistributions of source code must retain the above copyright
Packit 7cfc04
.\"    notice, this list of conditions and the following disclaimer.
Packit 7cfc04
.\" 2. Redistributions in binary form must reproduce the above copyright
Packit 7cfc04
.\"    notice, this list of conditions and the following disclaimer in the
Packit 7cfc04
.\"    documentation and/or other materials provided with the distribution.
Packit 7cfc04
.\" 3. All advertising materials mentioning features or use of this software
Packit 7cfc04
.\"    must display the following acknowledgement:
Packit 7cfc04
.\"	This product includes software developed by the University of
Packit 7cfc04
.\"	California, Berkeley and its contributors.
Packit 7cfc04
.\" 4. Neither the name of the University nor the names of its contributors
Packit 7cfc04
.\"    may be used to endorse or promote products derived from this software
Packit 7cfc04
.\"    without specific prior written permission.
Packit 7cfc04
.\"
Packit 7cfc04
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit 7cfc04
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 7cfc04
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 7cfc04
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit 7cfc04
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 7cfc04
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit 7cfc04
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit 7cfc04
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit 7cfc04
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit 7cfc04
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit 7cfc04
.\" SUCH DAMAGE.
Packit 7cfc04
.\" %%%LICENSE_END
Packit 7cfc04
.\"
Packit 7cfc04
.\"     @(#)readlink.2	6.8 (Berkeley) 3/10/91
Packit 7cfc04
.\"
Packit 7cfc04
.\" Modified Sat Jul 24 00:10:21 1993 by Rik Faith (faith@cs.unc.edu)
Packit 7cfc04
.\" Modified Tue Jul  9 23:55:17 1996 by aeb
Packit 7cfc04
.\" Modified Fri Jan 24 00:26:00 1997 by aeb
Packit 7cfc04
.\" 2011-09-20, Guillem Jover <guillem@hadrons.org>:
Packit 7cfc04
.\"     Added text on dynamically allocating buffer + example program
Packit 7cfc04
.\"
Packit 7cfc04
.TH READLINK 2 2017-09-15 "Linux" "Linux Programmer's Manual"
Packit 7cfc04
.SH NAME
Packit 7cfc04
readlink, readlinkat \- read value of a symbolic link
Packit 7cfc04
.SH SYNOPSIS
Packit 7cfc04
.nf
Packit 7cfc04
.B #include <unistd.h>
Packit 7cfc04
.PP
Packit 7cfc04
.BI "ssize_t readlink(const char *" pathname ", char *" buf \
Packit 7cfc04
", size_t " bufsiz );
Packit 7cfc04
Packit 7cfc04
.BR "#include <fcntl.h>           " "/* Definition of AT_* constants */"
Packit 7cfc04
.B #include <unistd.h>
Packit 7cfc04
.PP
Packit 7cfc04
.BI "ssize_t readlinkat(int " dirfd ", const char *" pathname ,
Packit 7cfc04
.BI "                   char *" buf ", size_t " bufsiz );
Packit 7cfc04
.PP
Packit 7cfc04
.fi
Packit 7cfc04
.in -4n
Packit 7cfc04
Feature Test Macro Requirements for glibc (see
Packit 7cfc04
.BR feature_test_macros (7)):
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
.ad l
Packit 7cfc04
.BR readlink ():
Packit 7cfc04
.RS 4
Packit 7cfc04
_XOPEN_SOURCE\ >=\ 500 || _POSIX_C_SOURCE\ >=\ 200112L
Packit 7cfc04
.\"    || _XOPEN_SOURCE\ &&\ _XOPEN_SOURCE_EXTENDED
Packit 7cfc04
    || /* Glibc versions <= 2.19: */ _BSD_SOURCE
Packit 7cfc04
.RE
Packit 7cfc04
.PP
Packit 7cfc04
.BR readlinkat ():
Packit 7cfc04
.PD 0
Packit 7cfc04
.ad l
Packit 7cfc04
.RS 4
Packit 7cfc04
.TP 4
Packit 7cfc04
Since glibc 2.10:
Packit 7cfc04
_POSIX_C_SOURCE\ >=\ 200809L
Packit 7cfc04
.TP
Packit 7cfc04
Before glibc 2.10:
Packit 7cfc04
_ATFILE_SOURCE
Packit 7cfc04
.RE
Packit 7cfc04
.ad b
Packit 7cfc04
.PD
Packit 7cfc04
.SH DESCRIPTION
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
places the contents of the symbolic link
Packit 7cfc04
.I pathname
Packit 7cfc04
in the buffer
Packit 7cfc04
.IR buf ,
Packit 7cfc04
which has size
Packit 7cfc04
.IR bufsiz .
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
does not append a null byte to
Packit 7cfc04
.IR buf .
Packit 7cfc04
It will (silently) truncate the contents (to a length of
Packit 7cfc04
.I bufsiz
Packit 7cfc04
characters), in case the buffer is too small to hold all of the contents.
Packit 7cfc04
.SS readlinkat()
Packit 7cfc04
The
Packit 7cfc04
.BR readlinkat ()
Packit 7cfc04
system call operates in exactly the same way as
Packit 7cfc04
.BR readlink (),
Packit 7cfc04
except for the differences described here.
Packit 7cfc04
.PP
Packit 7cfc04
If the pathname given in
Packit 7cfc04
.I pathname
Packit 7cfc04
is relative, then it is interpreted relative to the directory
Packit 7cfc04
referred to by the file descriptor
Packit 7cfc04
.I dirfd
Packit 7cfc04
(rather than relative to the current working directory of
Packit 7cfc04
the calling process, as is done by
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
for a relative pathname).
Packit 7cfc04
.PP
Packit 7cfc04
If
Packit 7cfc04
.I pathname
Packit 7cfc04
is relative and
Packit 7cfc04
.I dirfd
Packit 7cfc04
is the special value
Packit 7cfc04
.BR AT_FDCWD ,
Packit 7cfc04
then
Packit 7cfc04
.I pathname
Packit 7cfc04
is interpreted relative to the current working
Packit 7cfc04
directory of the calling process (like
Packit 7cfc04
.BR readlink ()).
Packit 7cfc04
.PP
Packit 7cfc04
If
Packit 7cfc04
.I pathname
Packit 7cfc04
is absolute, then
Packit 7cfc04
.I dirfd
Packit 7cfc04
is ignored.
Packit 7cfc04
.PP
Packit 7cfc04
Since Linux 2.6.39,
Packit 7cfc04
.\" commit 65cfc6722361570bfe255698d9cd4dccaf47570d
Packit 7cfc04
.I pathname
Packit 7cfc04
can be an empty string,
Packit 7cfc04
in which case the call operates on the symbolic link referred to by
Packit 7cfc04
.IR dirfd
Packit 7cfc04
(which should have been obtained using
Packit 7cfc04
.BR open (2)
Packit 7cfc04
with the
Packit 7cfc04
.B O_PATH
Packit 7cfc04
and
Packit 7cfc04
.B O_NOFOLLOW
Packit 7cfc04
flags).
Packit 7cfc04
.PP
Packit 7cfc04
See
Packit 7cfc04
.BR openat (2)
Packit 7cfc04
for an explanation of the need for
Packit 7cfc04
.BR readlinkat ().
Packit 7cfc04
.SH RETURN VALUE
Packit 7cfc04
On success, these calls return the number of bytes placed in
Packit 7cfc04
.IR buf .
Packit 7cfc04
(If the returned value equals
Packit 7cfc04
.IR bufsiz ,
Packit 7cfc04
then truncation may have occurred.)
Packit 7cfc04
On error, \-1 is returned and
Packit 7cfc04
.I errno
Packit 7cfc04
is set to indicate the error.
Packit 7cfc04
.SH ERRORS
Packit 7cfc04
.TP
Packit 7cfc04
.B EACCES
Packit 7cfc04
Search permission is denied for a component of the path prefix.
Packit 7cfc04
(See also
Packit 7cfc04
.BR path_resolution (7).)
Packit 7cfc04
.TP
Packit 7cfc04
.B EFAULT
Packit 7cfc04
.I buf
Packit 7cfc04
extends outside the process's allocated address space.
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
.I bufsiz
Packit 7cfc04
is not positive.
Packit 7cfc04
.\" At the glibc level, bufsiz is unsigned, so this error can only occur
Packit 7cfc04
.\" if bufsiz==0.  However, the in the kernel syscall, bufsiz is signed,
Packit 7cfc04
.\" and this error can also occur if bufsiz < 0.
Packit 7cfc04
.\" See: http://thread.gmane.org/gmane.linux.man/380
Packit 7cfc04
.\" Subject: [patch 0/3] [RFC] kernel/glibc mismatch of "readlink" syscall?
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
The named file (i.e., the final filename component of
Packit 7cfc04
.IR pathname )
Packit 7cfc04
is not a symbolic link.
Packit 7cfc04
.TP
Packit 7cfc04
.B EIO
Packit 7cfc04
An I/O error occurred while reading from the filesystem.
Packit 7cfc04
.TP
Packit 7cfc04
.B ELOOP
Packit 7cfc04
Too many symbolic links were encountered in translating the pathname.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENAMETOOLONG
Packit 7cfc04
A pathname, or a component of a pathname, was too long.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOENT
Packit 7cfc04
The named file does not exist.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOMEM
Packit 7cfc04
Insufficient kernel memory was available.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOTDIR
Packit 7cfc04
A component of the path prefix is not a directory.
Packit 7cfc04
.PP
Packit 7cfc04
The following additional errors can occur for
Packit 7cfc04
.BR readlinkat ():
Packit 7cfc04
.TP
Packit 7cfc04
.B EBADF
Packit 7cfc04
.I dirfd
Packit 7cfc04
is not a valid file descriptor.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOTDIR
Packit 7cfc04
.I pathname
Packit 7cfc04
is relative and
Packit 7cfc04
.I dirfd
Packit 7cfc04
is a file descriptor referring to a file other than a directory.
Packit 7cfc04
.SH VERSIONS
Packit 7cfc04
.BR readlinkat ()
Packit 7cfc04
was added to Linux in kernel 2.6.16;
Packit 7cfc04
library support was added to glibc in version 2.4.
Packit 7cfc04
.SH CONFORMING TO
Packit 7cfc04
.BR readlink ():
Packit 7cfc04
4.4BSD
Packit 7cfc04
.RB ( readlink ()
Packit 7cfc04
first appeared in 4.2BSD),
Packit 7cfc04
POSIX.1-2001, POSIX.1-2008.
Packit 7cfc04
.PP
Packit 7cfc04
.BR readlinkat ():
Packit 7cfc04
POSIX.1-2008.
Packit 7cfc04
.SH NOTES
Packit 7cfc04
In versions of glibc up to and including glibc 2.4, the return type of
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
was declared as
Packit 7cfc04
.IR int .
Packit 7cfc04
Nowadays, the return type is declared as
Packit 7cfc04
.IR ssize_t ,
Packit 7cfc04
as (newly) required in POSIX.1-2001.
Packit 7cfc04
.PP
Packit 7cfc04
Using a statically sized buffer might not provide enough room for the
Packit 7cfc04
symbolic link contents.
Packit 7cfc04
The required size for the buffer can be obtained from the
Packit 7cfc04
.I stat.st_size
Packit 7cfc04
value returned by a call to
Packit 7cfc04
.BR lstat (2)
Packit 7cfc04
on the link.
Packit 7cfc04
However, the number of bytes written by
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
and
Packit 7cfc04
.BR readlinkat ()
Packit 7cfc04
should be checked to make sure that the size of the
Packit 7cfc04
symbolic link did not increase between the calls.
Packit 7cfc04
Dynamically allocating the buffer for
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
and
Packit 7cfc04
.BR readlinkat ()
Packit 7cfc04
also addresses a common portability problem when using
Packit 7cfc04
.I PATH_MAX
Packit 7cfc04
for the buffer size,
Packit 7cfc04
as this constant is not guaranteed to be defined per POSIX
Packit 7cfc04
if the system does not have such limit.
Packit 7cfc04
.SS Glibc notes
Packit 7cfc04
On older kernels where
Packit 7cfc04
.BR readlinkat ()
Packit 7cfc04
is unavailable, the glibc wrapper function falls back to the use of
Packit 7cfc04
.BR readlink ().
Packit 7cfc04
When
Packit 7cfc04
.I pathname
Packit 7cfc04
is a relative pathname,
Packit 7cfc04
glibc constructs a pathname based on the symbolic link in
Packit 7cfc04
.IR /proc/self/fd
Packit 7cfc04
that corresponds to the
Packit 7cfc04
.IR dirfd
Packit 7cfc04
argument.
Packit 7cfc04
.SH EXAMPLE
Packit 7cfc04
The following program allocates the buffer needed by
Packit 7cfc04
.BR readlink ()
Packit 7cfc04
dynamically from the information provided by
Packit 7cfc04
.BR lstat (2),
Packit 7cfc04
falling back to a buffer of size
Packit 7cfc04
.BR PATH_MAX
Packit 7cfc04
in cases where
Packit 7cfc04
.BR lstat (2)
Packit 7cfc04
reports a size of zero.
Packit 7cfc04
.PP
Packit 7cfc04
.EX
Packit 7cfc04
#include <sys/types.h>
Packit 7cfc04
#include <sys/stat.h>
Packit 7cfc04
#include <limits.h>
Packit 7cfc04
#include <stdio.h>
Packit 7cfc04
#include <stdlib.h>
Packit 7cfc04
#include <unistd.h>
Packit 7cfc04
Packit 7cfc04
int
Packit 7cfc04
main(int argc, char *argv[])
Packit 7cfc04
{
Packit 7cfc04
    struct stat sb;
Packit 7cfc04
    char *buf;
Packit 7cfc04
    ssize_t nbytes, bufsiz;
Packit 7cfc04
Packit 7cfc04
    if (argc != 2) {
Packit 7cfc04
        fprintf(stderr, "Usage: %s <pathname>\\n", argv[0]);
Packit 7cfc04
        exit(EXIT_FAILURE);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    if (lstat(argv[1], &sb) == \-1) {
Packit 7cfc04
        perror("lstat");
Packit 7cfc04
        exit(EXIT_FAILURE);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    /* Add one to the link size, so that we can determine whether
Packit 7cfc04
       the buffer returned by readlink() was truncated. */
Packit 7cfc04
Packit 7cfc04
    bufsiz = sb.st_size + 1;
Packit 7cfc04
Packit 7cfc04
    /* Some magic symlinks under (for example) /proc and /sys
Packit 7cfc04
       report \(aqst_size\(aq as zero. In that case, take PATH_MAX as
Packit 7cfc04
       a "good enough" estimate. */
Packit 7cfc04
Packit 7cfc04
    if (sb.st_size == 0)
Packit 7cfc04
        bufsiz = PATH_MAX;
Packit 7cfc04
Packit 7cfc04
    buf = malloc(bufsiz);
Packit 7cfc04
    if (buf == NULL) {
Packit 7cfc04
        perror("malloc");
Packit 7cfc04
        exit(EXIT_FAILURE);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    nbytes = readlink(argv[1], buf, bufsiz);
Packit 7cfc04
    if (nbytes == \-1) {
Packit 7cfc04
        perror("readlink");
Packit 7cfc04
        exit(EXIT_FAILURE);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    printf("\(aq%s\(aq points to \(aq%.*s\(aq\\n", argv[1], (int) nbytes, buf);
Packit 7cfc04
Packit 7cfc04
    /* If the return value was equal to the buffer size, then the
Packit 7cfc04
       the link target was larger than expected (perhaps because the
Packit 7cfc04
       target was changed between the call to lstat() and the call to
Packit 7cfc04
       readlink()). Warn the user that the returned target may have
Packit 7cfc04
       been truncated. */
Packit 7cfc04
Packit 7cfc04
    if (nbytes == bufsiz)
Packit 7cfc04
        printf("(Returned buffer may have been truncated)\\n");
Packit 7cfc04
Packit 7cfc04
    free(buf);
Packit 7cfc04
    exit(EXIT_SUCCESS);
Packit 7cfc04
}
Packit 7cfc04
.EE
Packit 7cfc04
.SH SEE ALSO
Packit 7cfc04
.BR readlink (1),
Packit 7cfc04
.BR lstat (2),
Packit 7cfc04
.BR stat (2),
Packit 7cfc04
.BR symlink (2),
Packit 7cfc04
.BR realpath (3),
Packit 7cfc04
.BR path_resolution (7),
Packit 7cfc04
.BR symlink (7)
Packit 7cfc04
.SH COLOPHON
Packit 7cfc04
This page is part of release 4.15 of the Linux
Packit 7cfc04
.I man-pages
Packit 7cfc04
project.
Packit 7cfc04
A description of the project,
Packit 7cfc04
information about reporting bugs,
Packit 7cfc04
and the latest version of this page,
Packit 7cfc04
can be found at
Packit 7cfc04
\%https://www.kernel.org/doc/man\-pages/.