Date: Mon, 4 Feb 2002 11:09:44 +1100 From: "Tim J. Robbins" <tim@robbins.dropbear.id.au> To: Mike Barcroft <mike@FreeBSD.ORG> Cc: freebsd-standards@FreeBSD.ORG Subject: Re: pwd -L option Message-ID: <20020204110944.A20748@descent.robbins.dropbear.id.au> In-Reply-To: <20020203174511.A6496@espresso.q9media.com>; from mike@FreeBSD.ORG on Sun, Feb 03, 2002 at 05:45:11PM -0500 References: <20020130181638.A8510@descent.robbins.dropbear.id.au> <20020202032917.K10222@espresso.q9media.com> <20020202210237.A2326@descent.robbins.dropbear.id.au> <20020203174511.A6496@espresso.q9media.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--ZPt4rx8FFjLCG7dd Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Feb 03, 2002 at 05:45:11PM -0500, Mike Barcroft wrote: > > -.St -p1003.2 > > +.St -p1003.1-2001 > > compatible. > > Let's be assertive here and say that this utility does conform. I think this should be -p1003.2-2001, but we don't have a macro for that. > This isn't quite right yet. realpath(1) should never call getopt(). > It expects no options, so `realpath -L' should return a valid path > ending with `/-L'. Conceptually pwd and realpath have something in common, but their implementations don't. I don't agree with having realpath built in to pwd. There's probably not much I can do about that, though. Here's another attempt at a patch. Tim --ZPt4rx8FFjLCG7dd Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="pwd.diff" Index: pwd/pwd.1 =================================================================== RCS file: /home/ncvs/src/bin/pwd/pwd.1,v retrieving revision 1.15 diff -u -r1.15 pwd.1 --- pwd/pwd.1 2001/08/15 09:09:36 1.15 +++ pwd/pwd.1 2002/02/03 23:49:52 @@ -43,6 +43,7 @@ .Nd return working directory name .Sh SYNOPSIS .Nm +.Op Fl L | P .Sh DESCRIPTION .Nm Pwd writes the absolute pathname of the current working directory to @@ -54,17 +55,29 @@ Consult the .Xr builtin 1 manual page. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl L +Display the logical current working directory. +.It Fl P +Display the physical current working directory (all symbolic links resolved). +This is the default. +.El +.Sh ENVIRONMENT +Environment variables used by +.Nm : +.Bl -tag -width PWD +.It Ev PWD +Logical current working directory. .Sh DIAGNOSTICS .Ex -std .Sh STANDARDS The .Nm -utility is expected to be -.St -p1003.2 -compatible. -The -.Fl L -flag is not supported. +utility is compliant with the +.St -p1003.1-2001 +specification. .Sh SEE ALSO .Xr builtin 1 , .Xr cd 1 , @@ -80,3 +93,9 @@ However, it can give a different answer in the rare case that the current directory or a containing directory was moved after the shell descended into it. +.Pp +The +.Fl L +option does not work unless the +.Ev PWD +variable is exported by the shell. Index: pwd/pwd.c =================================================================== RCS file: /home/ncvs/src/bin/pwd/pwd.c,v retrieving revision 1.14 diff -u -r1.14 pwd.c --- pwd/pwd.c 2002/02/02 06:48:10 1.14 +++ pwd/pwd.c 2002/02/03 23:49:53 @@ -45,31 +45,47 @@ "$FreeBSD: src/bin/pwd/pwd.c,v 1.14 2002/02/02 06:48:10 imp Exp $"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/stat.h> + #include <err.h> +#include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/param.h> +extern char *__progname; + +static char *getcwd_logical(void); void usage(void); int main(int argc, char *argv[]) { + int Lflag, Pflag; int ch; char *p; char buf[PATH_MAX]; - /* - * Flags for pwd are a bit strange. The POSIX 1003.2B/D9 document - * has an optional -P flag for physical, which is what this program - * will produce by default. The logical flag, -L, should fail, as - * there's no way to display a logical path after forking. - */ - while ((ch = getopt(argc, argv, "P")) != -1) + if (strcmp(__progname, "realpath") == 0) { + if (argc != 2) + usage(); + if ((p = realpath(argv[1], buf)) == NULL) + err(1, "%s", argv[1]); + (void)printf("%s\n", p); + exit(0); + } + + Lflag = Pflag = 0; + while ((ch = getopt(argc, argv, "LP")) != -1) switch (ch) { + case 'L': + Lflag = 1; + break; case 'P': + Pflag = 1; break; case '?': default: @@ -78,19 +94,13 @@ argc -= optind; argv += optind; - if (argc == 1) { - p = realpath(argv[0], buf); - if (p == NULL) - err(1, "%s", argv[0]); - (void)printf("%s\n", p); - } else if (argc == 0) { - p = getcwd(NULL, (size_t)0); - if (p == NULL) - err(1, "."); - (void)printf("%s\n", p); - } else { + if (argc != 0 || (Lflag && Pflag)) usage(); - } + + p = Lflag ? getcwd_logical() : getcwd(NULL, 0); + if (p == NULL) + err(1, "."); + (void)printf("%s\n", p); exit(0); } @@ -98,7 +108,32 @@ void usage(void) { + + if (strcmp(__progname, "realpath") == 0) + (void)fprintf(stderr, "usage: realpath [file ...]\n"); + else + (void)fprintf(stderr, "usage: pwd [-LP]\n"); + + exit(1); +} + +static char * +getcwd_logical(void) +{ + struct stat log, phy; + char *pwd; + + /* + * Check that $PWD is an absolute logical pathname referring to + * the current working directory. + */ + if ((pwd = getenv("PWD")) != NULL && *pwd == '/') { + if (stat(pwd, &log) == -1 || stat(".", &phy) == -1) + return (NULL); + if (log.st_dev == phy.st_dev && log.st_ino == phy.st_ino) + return (pwd); + } - (void)fprintf(stderr, "usage: pwd\n"); - exit(1); + errno = ENOENT; + return (NULL); } --ZPt4rx8FFjLCG7dd-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020204110944.A20748>