The readlink system call retrieves the target of a symbolic link. It takes three arguments: the path to the symbolic link, a buffer to receive the target of the link, and the length of that buffer. Unusually, readlink does not NUL-terminate the target path that it fills into the buffer. It does, however, return the number of characters in the target path, so NUL-terminating the string is simple.
If the first argument to readlink points to a file that isn't a symbolic link, readlink sets errno to EINVAL and returns -1.
The small program in Listing 8.9 prints the target of the symbolic link specified on its command line.
#include <errno.h> #include <stdio.h> #include <unistd.h> int main (int argc, char* argv[]) { char target_path[256]; char* link_path = argv[1]; /* Attempt to read the target of the symbolic link. */ int len = readlink (link_path, target_path, sizeof (target_path)); if (len == -1) { /* The call failed. */ if (errno == EINVAL)
/* It's not a symbolic link; report that. */ fprintf (stderr, "%s is not a symbolic link\n", link_path); else /* Some other problem occurred; print the generic message. */ perror ("readlink"); return 1; } else { /* NUL-terminate the target path. */ target_path[len] = '\0'; /* Print it. */ printf ("%s\n", target_path); return 0; } }
For example, here's how you could make a symbolic link and use print-symlink to read it back:
% ln -s /usr/bin/wc my_link % ./print-symlink my_link /usr/bin/wc