readlink()

Updated: April 19, 2023

Place the contents of a symbolic link into a buffer

Synopsis:

#include <unistd.h>

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

Arguments:

path
The name of the symbolic link.
buf
A pointer to a buffer where the function can store the contents of the symbolic link (i.e., the path linked to).
bufsiz
The size of the buffer.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The readlink() function places the contents of the symbolic link named by path into the buffer pointed to by buf, which has a size of bufsiz. The contents of the returned symbolic link don't include a NULL terminator. Their length must be determined from the stat structure returned by lstat(), or by the return value of the readlink() call.

If readlink() is successful, up to bufsiz bytes from the contents of the symbolic link are placed in buf.

Returns:

The number of bytes placed in the buffer, or -1 if an error occurs (errno is set).

Errors:

EACCES
Search permission is denied for a component of the path prefix.
EINVAL
The named file isn't a symbolic link.
ELOOP
A loop exists in the symbolic links encountered during resolution of the path argument and more than SYMLOOP_MAX symbolic links were encountered.
ENAMETOOLONG
A component of path exceeds NAME_MAX characters, or the entire pathname exceeds PATH_MAX characters.
ENOENT
The named file doesn't exist.
ENOSYS
Links aren't supported by the resource manager associated with the path.
ENOTDIR
A component of the path prefix named by path isn't a directory.

Examples:

/*
 * Read the contents of the named symbolic links
 */
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char buf[PATH_MAX];

int main( int argc, char** argv )
{
  int n;
  int len;
  int ecode = 0;

  for( n = 1; n < argc; ++n ) {
    if(( len = readlink( argv[n], buf, PATH_MAX )) == -1) {
      perror( argv[n] );
      ecode++;
    }
    else {
      buf[len] = '\0';
      printf( "%s -> %s\n", argv[n], buf );
    }
  }

  return( ecode );
}

Classification:

POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler Yes
Thread Yes