Skip site navigation (1)Skip section navigation (2)
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>