Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jul 2009 21:30:01 -0800
From:      Mel Flynn <mel.flynn+fbsd.questions@mailing.thruhere.net>
To:        freebsd-questions@freebsd.org
Subject:   Re: How to find what symlink points to?
Message-ID:  <200907272130.02195.mel.flynn%2Bfbsd.questions@mailing.thruhere.net>
In-Reply-To: <631612.70113.qm@web57002.mail.re3.yahoo.com>
References:  <631612.70113.qm@web57002.mail.re3.yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 27 July 2009 20:54:51 Unga wrote:

> Thanks everybody for valuable replies. In fact, I also used readlink(2) but
> fed the symlink path directly from dirent, which was partial, readlink(2)
> requires full path.

Nope it doesn't. It's the classical "opendir does not chdir" problem. 
readlink(2) requires a path that resolves from the current working directory 
of the program. If you opendir(3) /dev and are in /, then dirent->d_name is 
not valid for your cwd. Either you have to chdir or prepend the path given to 
opendir to dirent->d_name.

% ./rl /dev/stdout
stdout => fd/1

See the diff on previous rl.c below.

-- 
Mel

--- rl.c.orig   2009-07-27 09:19:58.000000000 -0800
+++ rl.c        2009-07-27 21:25:48.000000000 -0800
@@ -9,13 +9,31 @@

 int main(int argc, char **argv)
 {
-       char path[MAXPATHLEN], buf[MAXPATHLEN+1];
+       char path[MAXPATHLEN], buf[MAXPATHLEN+1], *ptr;
        ssize_t res;

        if( argc != 2 )
                exit(67);

        (void)strlcpy(path, argv[1], sizeof(path));
+       ptr = strrchr(path, '/');
+       if( ptr != NULL )
+       {
+               char *tmp = ptr + 1;
+
+               if( ptr == path )
+               {
+                       if( strlen(path) == 1 )
+                               errx(67, "/ can never be a symlink");
+                       chdir("/");
+               }
+               else
+               {
+                       *ptr = '\0';
+                       (void)chdir(path);
+               }
+               (void)strlcpy(path, tmp, sizeof(path));
+       }
        res = readlink(path, buf, sizeof(buf));
        if( res < 0 )
                err(EXIT_FAILURE, "readlink()");




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907272130.02195.mel.flynn%2Bfbsd.questions>