NetBSD Problem Report #34662

From root@atlas.ipv6.stack.nl  Fri Sep 29 11:53:35 2006
Return-Path: <root@atlas.ipv6.stack.nl>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id 574A563B8CA
	for <gnats-bugs@gnats.NetBSD.org>; Fri, 29 Sep 2006 11:53:35 +0000 (UTC)
Message-Id: <20060929115633.1858369@atlas.ipv6.stack.nl>
Date: Fri, 29 Sep 2006 13:56:33 +0200 (CEST)
From: martijnb@atlas.ipv6.stack.nl
Reply-To: martijnb@atlas.ipv6.stack.nl
To: gnats-bugs@NetBSD.org
Subject: readlink doesn't grok -f, and there's no alternative (+fix)
X-Send-Pr-Version: 3.95

>Number:         34662
>Category:       bin
>Synopsis:       readlink doesn't grok -f, and there's no alternative (+fix)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          closed
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Sep 29 11:55:00 +0000 2006
>Closed-Date:    Sat Oct 07 10:43:29 +0000 2006
>Last-Modified:  Sat Oct 07 10:45:01 +0000 2006
>Originator:     martijnb@atlas.ipv6.stack.nl
>Release:        NetBSD 4.99.3
>Organization:

>Environment:


System: NetBSD atlas.ipv6.stack.nl 4.99.3 NetBSD 4.99.3 (ATLAS) #4: Thu Sep 28 13:29:00 CEST 2006 martijnb@atlas.ipv6.stack.nl:/usr/obj/sys/arch/amd64/compile/ATLAS amd64
Architecture: x86_64
Machine: amd64
>Description:
	Currently, there is no userland utility to query the absolute pathname
of a given filename by means of realpath(3). Other UNIX-like operatingsystems
either offer a this by means of a realpath(1) binary (Most notably: FreeBSD,
Gentoo Linux), others (OpenBSD, all other Linux distributions)  have a '-f' 
argument to readlink(1) which does the same: Call realpath(3) on the given
argument. To my best knowledge, NetBSD offers neither.
>How-To-Repeat:
	observation. There are programs out there relying on the availability
of this functionality.
>Fix:
	There's three possible approaches:

1)	Do what FreeBSD does: leave stat/readlink as they are, and write a
	small wrapper program to call realpath(3).
2)	Do what OpenBSD/Linux does: Make readlink a seperate program (It is
	currently a symlink to stat) and handle the '-f' case accordingly.  
3)	Keep the current situation (readlink being a symlink to stat), add
	yet another format option to stat and update the readlink stub to 
	accept a '-f' argument.

I considered #3 to be the best option, and introduced a "%y" format option.

Index: stat.1
===================================================================
RCS file: /cvsroot/src/usr.bin/stat/stat.1,v
retrieving revision 1.18
diff -u -r1.18 stat.1
--- stat.1	26 Jun 2005 10:16:46 -0000	1.18
+++ stat.1	29 Sep 2006 11:30:32 -0000
@@ -54,7 +54,7 @@
 .Op Fl t Ar timefmt
 .Op Ar
 .Nm readlink
-.Op Fl n
+.Op Fl nf
 .Op Ar
 .Sh DESCRIPTION
 The
@@ -71,9 +71,19 @@
 When invoked as
 .Nm readlink ,
 only the target of the symbolic link is printed.
-If the given argument is not a symbolic link,
+If the given argument is not a symbolic link and the
+.Fl f
+option is not specified,
 .Nm readlink
-will print nothing and exit with an error.
+will print nothing and exit with an error. If the
+.Fl f
+option is specified, the output is canonicalized by following every symlink
+in every component of the given path recursively. 
+.Nm readlink
+will resolve both absolute and relative paths, and return the absolute pathname
+corresponding to
+.Ar file .
+In this case, the argument does not need to be a symbolic link.
 .Pp
 The information displayed is obtained by calling
 .Xr lstat 2
@@ -379,7 +389,7 @@
 Inode generation number.
 .El
 .Pp
-The following four field specifiers are not drawn directly from the
+The following five field specifiers are not drawn directly from the
 data in struct stat, but are:
 .Bl -tag -width Ds
 .It Cm N
@@ -390,6 +400,8 @@
 or in a more descriptive form if the sub field specifier
 .Cm H
 is given.
+.It Cm y
+The absolute pathname corresponding to the file.
 .It Cm Y
 The target of a symbolic link.
 .It Cm Z
Index: stat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/stat/stat.c,v
retrieving revision 1.23
diff -u -r1.23 stat.c
--- stat.c	23 Jun 2005 03:13:24 -0000	1.23
+++ stat.c	29 Sep 2006 11:30:32 -0000
@@ -176,6 +176,7 @@
 #define SHOW_st_flags	'f'
 #define SHOW_st_gen	'v'
 #define SHOW_symlink	'Y'
+#define SHOW_realpath   'y'
 #define SHOW_filetype	'T'
 #define SHOW_filename	'N'
 #define SHOW_sizerdev	'Z'
@@ -219,8 +220,8 @@

 	if (strcmp(getprogname(), "readlink") == 0) {
 		am_readlink = 1;
-		options = "n";
-		synopsis = "[-n] [file ...]";
+		options = "nf";
+		synopsis = "[-nf] [file ...]";
 		statfmt = "%Y";
 		fmtchar = 'f';
 		quiet = 1;
@@ -244,6 +245,10 @@
 			quiet = 1;
 			break;
 		case 'f':
+			if(am_readlink) {
+				statfmt="%y";
+				break;
+			}
 			statfmt = optarg;
 			/* FALLTHROUGH */
 		case 'l':
@@ -511,6 +516,7 @@
 			fmtcase(what, SHOW_st_flags);
 			fmtcase(what, SHOW_st_gen);
 			fmtcase(what, SHOW_symlink);
+			fmtcase(what, SHOW_realpath);
 			fmtcase(what, SHOW_filetype);
 			fmtcase(what, SHOW_filename);
 			fmtcase(what, SHOW_sizerdev);
@@ -784,6 +790,21 @@
 			ofmt = FMTF_UNSIGNED;
 		break;
 #endif /* HAVE_STRUCT_STAT_ST_GEN */
+	case SHOW_realpath:
+		small = 0;
+		data = 0;
+		snprintf(path, sizeof(path), " -> ");
+		if (realpath(file, path + 4) == NULL ) {
+			linkfail = 1;
+			l = 0;
+			path[0] = '\0';
+		}
+		sdata = path + (ofmt == FMTF_STRING ? 0: 4);
+		
+		formats = FMTF_STRING;
+		if (ofmt == 0)
+			ofmt = FMTF_STRING;
+		break;
 	case SHOW_symlink:
 		small = 0;
 		data = 0;

>Release-Note:

>Audit-Trail:

State-Changed-From-To: open->closed
State-Changed-By: elad@netbsd.org
State-Changed-When: Sat, 07 Oct 2006 10:43:29 +0000
State-Changed-Why:
patch applied, thanks!


From: Elad Efrat <elad@netbsd.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: PR/34662 CVS commit: src/usr.bin/stat
Date: Sat,  7 Oct 2006 10:41:51 +0000 (UTC)

 Module Name:	src
 Committed By:	elad
 Date:		Sat Oct  7 10:41:51 UTC 2006

 Modified Files:
 	src/usr.bin/stat: stat.1 stat.c

 Log Message:
 PR/34662: martijnb at atlas dot ipv6 dot stack dot nl: readlink doesn't
 grok -f, and there's no alternative (+fix)

 Patch applied with minor tweak (%y -> %R, as it was already taken) plus
 some nits from myself. Thanks!


 To generate a diff of this commit:
 cvs rdiff -r1.18 -r1.19 src/usr.bin/stat/stat.1
 cvs rdiff -r1.23 -r1.24 src/usr.bin/stat/stat.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.