Posix requires that 'pwd -P' reset the shells saved cwd value - so a

subsequent 'pwd -L' will report the same value.
Update man page to be a closer match to reality.
This commit is contained in:
dsl 2003-11-14 20:00:28 +00:00
parent 4e90dd053f
commit 296844fe72
2 changed files with 92 additions and 44 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cd.c,v 1.33 2003/10/30 09:40:26 dsl Exp $ */
/* $NetBSD: cd.c,v 1.34 2003/11/14 20:00:28 dsl Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: cd.c,v 1.33 2003/10/30 09:40:26 dsl Exp $");
__RCSID("$NetBSD: cd.c,v 1.34 2003/11/14 20:00:28 dsl Exp $");
#endif
#endif /* not lint */
@ -69,7 +69,7 @@ __RCSID("$NetBSD: cd.c,v 1.33 2003/10/30 09:40:26 dsl Exp $");
STATIC int docd(char *, int);
STATIC char *getcomponent(void);
STATIC void updatepwd(char *);
STATIC char *find_pwd(int noerror);
STATIC void find_curdir(int noerror);
char *curdir = NULL; /* current working directory */
char *prevdir; /* previous working directory */
@ -86,8 +86,10 @@ cdcmd(int argc, char **argv)
nextopt(nullstr);
/* Try (quite hard) to have 'curdir' defined, nothing has set
it on entry to the shell, but we want 'cd fred; cd -' to work. */
/*
* Try (quite hard) to have 'curdir' defined, nothing has set
* it on entry to the shell, but we want 'cd fred; cd -' to work.
*/
getpwd(1);
dest = *argptr;
if (dest == NULL) {
@ -111,16 +113,12 @@ cdcmd(int argc, char **argv)
}
}
if (*dest == '\0')
dest = ".";
if (dest[0] == '-' && dest[1] == '\0') {
dest = prevdir ? prevdir : curdir;
print = 1;
if (dest)
print = 1;
else
dest = ".";
}
if (*dest == '\0')
dest = ".";
if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL)
path = nullstr;
while ((p = padvance(&path, dest)) != NULL) {
@ -298,27 +296,32 @@ updatepwd(char *dir)
INTON;
}
/*
* Posix says the default should be 'pwd -L' (as below), however
* the 'cd' command (above) does something much nearer to the
* posix 'cd -P' (not the posix default of 'cd -L').
* If 'cd' is changed to support -P/L then the default here
* needs to be revisited if the historic behaviour is to be kept.
*/
int
pwdcmd(int argc, char **argv)
{
int i;
char opt = 'L';
char *pwd;
while ((i = nextopt("LP")) != '\0')
opt = i;
if (*argptr)
error("unexpected argument");
if (opt == 'L') {
if (opt == 'L')
getpwd(0);
pwd = curdir;
} else
pwd = find_pwd(0);
else
find_curdir(0);
out1str(pwd);
setvar("PWD", curdir, VEXPORT);
out1str(curdir);
out1c('\n');
return 0;
}
@ -354,15 +357,13 @@ getpwd(int noerror)
}
}
pwd = find_pwd(noerror);
find_curdir(noerror);
if (pwd != NULL)
curdir = savestr(pwd);
return;
}
STATIC char *
find_pwd(int noerror)
STATIC void
find_curdir(int noerror)
{
int i;
char *pwd;
@ -383,14 +384,16 @@ find_pwd(int noerror)
for (i = MAXPWD;; i *= 2) {
pwd = stalloc(i);
if (getcwd(pwd, i) != NULL)
return pwd;
if (getcwd(pwd, i) != NULL) {
curdir = savestr(pwd);
return;
}
stunalloc(pwd);
if (errno == ERANGE)
continue;
if (!noerror)
error("getcwd() failed: %s", strerror(errno));
return NULL;
return;
}
#else
{
@ -398,9 +401,8 @@ find_pwd(int noerror)
int status;
struct job *jp;
int pip[2];
char *buf;
buf = stalloc(MAXPWD);
pwd = stalloc(MAXPWD);
INTOFF;
if (pipe(pip) < 0)
error("Pipe call failed");
@ -417,8 +419,8 @@ find_pwd(int noerror)
}
(void) close(pip[1]);
pip[1] = -1;
p = buf;
while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0
p = pwd;
while ((i = read(pip[0], p, pwd + MAXPWD - p)) > 0
|| (i == -1 && errno == EINTR)) {
if (i > 0)
p += i;
@ -428,16 +430,17 @@ find_pwd(int noerror)
status = waitforjob(jp);
if (status != 0)
error((char *)0);
if (i < 0 || p == buf || p[-1] != '\n') {
if (i < 0 || p == pwd || p[-1] != '\n') {
if (noerror) {
INTON;
return NULL;
return;
}
error("pwd command failed");
}
p[-1] = '\0';
INTON;
return buf;
curdir = savestr(pwd);
return;
}
#endif
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sh.1,v 1.70 2003/10/27 08:23:40 wiz Exp $
.\" $NetBSD: sh.1,v 1.71 2003/11/14 20:00:28 dsl Exp $
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@ -31,7 +31,7 @@
.\"
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95
.\"
.Dd February 12, 2003
.Dd November 14, 2003
.Os
.Dt SH 1
.Sh NAME
@ -299,6 +299,11 @@ section below.)
.It Fl b Em notify
Enable asynchronous notification of background job completion.
(UNIMPLEMENTED for 4.4alpha)
.It "\ \ " Em cdprint
Make an interactive shell always print the new directory name when
changed by the
.Ic cd
command.
.El
.Ss Lexical Structure
The shell reads input in terms of lines from a file and breaks it up into
@ -1178,10 +1183,17 @@ Do not execute the command but
search for the command and print the absolute pathname
of utilities, the name for builtins or the expansion of aliases.
.El
.It cd Op Ar directory
.It cd Op Ar directory Op Ar replace
Switch to the specified directory (default
.Ev $HOME ) .
If an entry for
If
.Ar replace
is specified, then the new directory name is generated by replacing
the first occurance of
.Ar directory
in the current directory name with
.Ar replace .
Otherwise if an entry for
.Ev CDPATH
appears in the environment of the
.Ic cd
@ -1463,15 +1475,48 @@ argument is omitted, the current job is used.
.It jobs
This command lists out all the background processes
which are children of the current shell process.
.It pwd
.It pwd Op Fl LP
Print the current directory.
The builtin command may differ from the program of the same name because the
builtin command remembers what the current directory
is rather than recomputing it each time.
This makes it faster.
However, if the current directory is renamed, the builtin version of
If
.Fl L
is specified the cached value (initially set from
.Ev PWD )
is checked to see if it refers to the current directory, if it does
the value is printed.
Otherwise the current directory name is found using
.Xr getcwd(3) .
The environment variable
.Ev PWD
is set to printed value.
.Pp
The default is
.Ic pwd
will continue to print the old name for the directory.
.Fl L ,
but note that the builtin
.Ic cd
command doesn't currently support
.Fl L
or
.Fl P
and will cache (almost) the absolute path.
If
.Ic cd
is changed,
.Ic pwd
may be changed to default to
.Ic pwd
.Fl P .
.Pp
If the current directory is renamed and replaced by a symlink to the
same directory, or the initial
.Ev PWD
value followed a symbolic link, then the cached value may not
be the absolute path.
.Pp
The builtin command may differ from the program of the same name because
the program will use
.Ev PWD
and the builtin uses a separately cached value.
.It Xo read Op Fl p Ar prompt
.Op Fl r
.Ar variable