How to find what symlink points to?
Mel Flynn
mel.flynn+fbsd.questions at mailing.thruhere.net
Tue Jul 28 05:30:04 UTC 2009
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()");
More information about the freebsd-questions
mailing list