Date: Sat, 2 Feb 2002 03:29:17 -0500 From: Mike Barcroft <mike@FreeBSD.ORG> To: "Tim J. Robbins" <tim@robbins.dropbear.id.au> Cc: freebsd-standards@FreeBSD.ORG Subject: Re: pwd -L option Message-ID: <20020202032917.K10222@espresso.q9media.com> In-Reply-To: <20020130181638.A8510@descent.robbins.dropbear.id.au>; from tim@robbins.dropbear.id.au on Wed, Jan 30, 2002 at 06:16:38PM %2B1100 References: <20020130181638.A8510@descent.robbins.dropbear.id.au>
next in thread | previous in thread | raw e-mail | index | archive | help
Tim J. Robbins <tim@robbins.dropbear.id.au> writes:
> This patch adds the -L option to pwd; most of the source changes were taken
> from NetBSD, but adapted so as not to break FreeBSD's realpath utility.
> I added an info line in usage() for realpath while I was at it.
>
> It uses the PWD environment variable that sh, ksh93, etc. export and checks
> to make sure it "points" to the physical CWD.
Good approach.
Warner made some modifications to this utility, so you will have to
merge his changes in.
> 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/01/30 07:18:10
> @@ -43,6 +43,7 @@
> .Nd return working directory name
> .Sh SYNOPSIS
> .Nm
> +.Op Fl LP
> .Sh DESCRIPTION
> .Nm Pwd
> writes the absolute pathname of the current working directory to
> @@ -54,17 +55,28 @@
> 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)
> +(default).
Having two sections enclosed in parens is kind of strange. Can you
break the default part out into its own sentence?
> .Sh DIAGNOSTICS
> .Ex -std
> +.Sh ENVIRONMENT
This section belongs above DIAGNOSTICS; see mdoc(7) for details.
> +Environment variables used by
> +.Nm :
> +.Bl -tag -width PWD
> +.It Ev PWD
> +Logical current working directory.
> .Sh STANDARDS
> The
> .Nm
> utility is expected to be
> .St -p1003.2
> compatible.
Please update this part. We are working on `.St -p1003.1-2001'.
> -The
> -.Fl L
> -flag is not supported.
> .Sh SEE ALSO
> .Xr builtin 1 ,
> .Xr cd 1 ,
> @@ -80,3 +92,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.13
> diff -u -r1.13 pwd.c
> --- pwd/pwd.c 2001/05/30 03:28:29 1.13
> +++ pwd/pwd.c 2002/01/30 07:18:11
> @@ -45,13 +45,18 @@
> "$FreeBSD: src/bin/pwd/pwd.c,v 1.13 2001/05/30 03:28:29 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>
>
> +static char *getcwd_logical __P((char *, size_t));
> int main __P((int, char *[]));
> void usage __P((void));
>
> @@ -63,16 +68,15 @@
> int ch;
> char *p;
> char buf[PATH_MAX];
> + int lflag = 0;
Style bug: initialization in the declaration.
This variable should be called `Lflag'.
>
> - /*
> - * 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)
> + while ((ch = getopt(argc, argv, "LP")) != -1)
Old bug: realpath(1) silently ignored the -P option.
New bug: realpath(1) accepts the -L option.
> switch (ch) {
> + case 'L':
> + lflag = 1;
> + break;
> case 'P':
> + lflag = 0;
One option shouldn't override another. I recommend you add a `Pflag'
and make sure both are not specified at the end of the while loop. If
they are, usage() is the correct place to go.
> break;
> case '?':
> default:
> @@ -87,7 +91,8 @@
> err(1, "%s", argv[0]);
> (void)printf("%s\n", p);
> } else if (argc == 0) {
> - p = getcwd(NULL, (size_t)0);
> + p = lflag ? getcwd_logical(NULL, (size_t)0) :
> + getcwd(NULL, (size_t)0);
Style bug: continuation of a line only adds 4 spaces not a tab.
The cast to size_t was and still is bogus here. Please remove it/them.
> if (p == NULL)
> err(1, ".");
> (void)printf("%s\n", p);
> @@ -98,10 +103,51 @@
> exit(0);
> }
>
> +static char *
> +getcwd_logical(char *pt, size_t size)
Style bug: ANSI-style prototypes. This is a problem because the rest
of the file uses K&R-style.
Neither of these arguments are needed.
> +{
> + char *pwd;
> + size_t pwdlen;
> + dev_t dev;
> + ino_t ino;
> + struct stat s;
Style bug: variable types should be sorted in order of size.
> +
> + /* Check $PWD -- if it's right, it's fast. */
This is a silly comment. It suggests that the alternative is slow.
There is no alternative.
> + if ((pwd = getenv("PWD")) != NULL && pwd[0] == '/') {
> + if (stat(pwd, &s) != -1) {
> + dev = s.st_dev;
> + ino = s.st_ino;
> + if (stat(".", &s) != -1 && dev == s.st_dev &&
> + ino == s.st_ino) {
> + pwdlen = strlen(pwd);
> + if (pt) {
> + if (!size) {
> + errno = EINVAL;
> + return (NULL);
> + }
> + if (pwdlen + 1 > size) {
> + errno = ERANGE;
> + return (NULL);
> + }
This code path isn't needed. It might be if this were being
considered for libc.
> + } else if ((pt = malloc(pwdlen + 1)) == NULL)
> + return (NULL);
> + (void)memmove(pt, pwd, pwdlen);
> + pt[pwdlen] = '\0';
This part doesn't make much sense. We already trust the environment
variable to be NUL terminated (see strlen() above). I recommend this
be changed to use strdup(3).
> + return (pt);
> + }
> + }
> + } else
> + errno = ENOENT;
> +
> + return (NULL);
> +}
> +
> +
Style bug: one line too many.
> void
> usage()
> {
>
> - (void)fprintf(stderr, "usage: pwd\n");
> + (void)fprintf(stderr, "usage: pwd [-LP]\n");
> + (void)fprintf(stderr, " realpath [file ...]\n");
> exit(1);
> }
An alternative might be to display different usages based on the
program executed.
Best regards,
Mike Barcroft
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?20020202032917.K10222>
