- Using strace
- access: Testing File Permissions
- fcntl: Locks and Other File Operations
- fsync and fdatasync: Flushing Disk Buffers
- getrlimit and setrlimit: Resource Limits
- getrusage: Process Statistics
- gettimeofday: Wall-Clock Time
- The mlock Family: Locking Physical Memory
- mprotect: Setting Memory Permissions
- nanosleep: High-Precision Sleeping
- readlink: Reading Symbolic Links
- sendfile: Fast Data Transfers
- setitimer: Setting Interval Timers
- sysinfo: Obtaining System Statistics
- uname
8.11 readlink: Reading Symbolic Links
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.
Listing 8.9 (print-symlink.c) Print the Target of a Symbolic Link
#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