From owner-freebsd-questions@FreeBSD.ORG Tue Jul 28 05:30:04 2009 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 38DE2106564A for ; Tue, 28 Jul 2009 05:30:04 +0000 (UTC) (envelope-from mel.flynn+fbsd.questions@mailing.thruhere.net) Received: from mailhub.rachie.is-a-geek.net (rachie.is-a-geek.net [66.230.99.27]) by mx1.freebsd.org (Postfix) with ESMTP id 05EDE8FC0C for ; Tue, 28 Jul 2009 05:30:03 +0000 (UTC) (envelope-from mel.flynn+fbsd.questions@mailing.thruhere.net) Received: from smoochies.rachie.is-a-geek.net (mailhub.lan.rachie.is-a-geek.net [192.168.2.11]) by mailhub.rachie.is-a-geek.net (Postfix) with ESMTP id 195237E818 for ; Mon, 27 Jul 2009 21:30:03 -0800 (AKDT) From: Mel Flynn To: freebsd-questions@freebsd.org Date: Mon, 27 Jul 2009 21:30:01 -0800 User-Agent: KMail/1.11.4 (FreeBSD/8.0-BETA2; KDE/4.2.4; i386; ; ) References: <631612.70113.qm@web57002.mail.re3.yahoo.com> In-Reply-To: <631612.70113.qm@web57002.mail.re3.yahoo.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200907272130.02195.mel.flynn+fbsd.questions@mailing.thruhere.net> Subject: Re: How to find what symlink points to? X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Jul 2009 05:30:04 -0000 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()");