/* From readlink(2) gcc -g -Wall -o test_readlink test_readlink.c GNU/Linux: ./test_readlink /proc/self/exe bufsize = 4096 '/proc/self/exe' points to '/home/srs/Hurd/DEBs/test_cases/test_readlink' GNU/Hurd: ./test_readlink /proc/self/exe bufsize = 16 '/proc/self/exe' points to './test_readlink' */ #include #include #include #include #include #include #include #ifndef PATH_MAX #define PATH_MAX 4096 #endif int main(int argc, char *argv[]) { struct stat sb; char *linkname; ssize_t r, bufsiz; if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(EXIT_FAILURE); } if (lstat(argv[1], &sb) == -1) { perror("lstat"); exit(EXIT_FAILURE); } bufsiz = sb.st_size + 1; /* Some magic symlinks under (for example) /proc and /sys report 'st_size' as zero. In that case, take PATH_MAX as a "good enough" estimate */ if (sb.st_size == 0) bufsiz = PATH_MAX; printf("bufsize = %zd\n", bufsiz); linkname = malloc(bufsiz); if (linkname == NULL) { perror("malloc"); exit(EXIT_FAILURE); } r = readlink(argv[1], linkname, bufsiz); if (r == -1) { perror("readlink"); exit(EXIT_FAILURE); } linkname[r] = '\0'; printf("'%s' points to '%s'\n", argv[1], linkname); if (r == bufsiz) printf("(Returned buffer may have been truncated)\n"); free(linkname); exit(EXIT_SUCCESS); }