Add the SUSv3 -L and -P options to the cd and pwd builtin utilities. `Logical'

handling of .. is now the default.
This commit is contained in:
Tim J. Robbins 2002-05-20 07:54:39 +00:00
parent a0cfa93972
commit 178897f127
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96980
2 changed files with 111 additions and 25 deletions

View File

@ -67,7 +67,7 @@ static const char rcsid[] =
#include "show.h"
#include "cd.h"
STATIC int docd(char *, int);
STATIC int docd(char *, int, int);
STATIC char *getcomponent(void);
STATIC void updatepwd(char *);
@ -76,16 +76,36 @@ char *prevdir; /* previous working directory */
STATIC char *cdcomppath;
int
cdcmd(int argc __unused, char **argv __unused)
cdcmd(int argc, char **argv)
{
char *dest;
char *path;
char *p;
struct stat statb;
int print = 0;
int ch, phys, print = 0;
nextopt(nullstr);
if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME", 1)) == NULL)
optreset = 1; optind = 1; /* initialize getopt */
phys = 0;
while ((ch = getopt(argc, argv, "LP")) != -1) {
switch (ch) {
case 'L':
phys = 0;
break;
case 'P':
phys = 1;
break;
default:
error("unknown option: -%c", optopt);
break;
}
}
argc -= optind;
argv += optind;
if (argc > 1)
error("too many arguments");
if ((dest = *argv) == NULL && (dest = bltinlookup("HOME", 1)) == NULL)
error("HOME not set");
if (*dest == '\0')
dest = ".";
@ -108,9 +128,8 @@ cdcmd(int argc __unused, char **argv __unused)
p += 2;
print = strcmp(p, dest);
}
if (docd(p, print) >= 0)
if (docd(p, print, phys) >= 0)
return 0;
}
}
error("can't cd to %s", dest);
@ -124,7 +143,7 @@ cdcmd(int argc __unused, char **argv __unused)
* directory name if "print" is nonzero.
*/
STATIC int
docd(char *dest, int print)
docd(char *dest, int print, int phys)
{
char *p;
char *q;
@ -133,7 +152,20 @@ docd(char *dest, int print)
int first;
int badstat;
TRACE(("docd(\"%s\", %d) called\n", dest, print));
TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, phys));
if (phys) {
INTOFF;
if (chdir(dest) < 0) {
INTON;
return -1;
}
updatepwd(NULL);
INTON;
if (print && iflag && curdir)
out1fmt("%s\n", curdir);
return 0;
}
/*
* Check each component of the path. If we find a symlink or
@ -161,20 +193,18 @@ docd(char *dest, int print)
if (equal(component, ".."))
continue;
STACKSTRNUL(p);
if ((lstat(stackblock(), &statb) < 0)
|| (S_ISLNK(statb.st_mode))) {
/* print = 1; */
if (lstat(stackblock(), &statb) < 0) {
badstat = 1;
break;
}
}
INTOFF;
if (chdir(dest) < 0) {
updatepwd(badstat ? NULL : dest);
if (chdir(curdir) < 0) {
INTON;
return -1;
}
updatepwd(badstat ? NULL : dest);
INTON;
if (print && iflag && curdir)
out1fmt("%s\n", curdir);
@ -270,22 +300,48 @@ updatepwd(char *dir)
INTON;
}
#define MAXPWD 256
int
pwdcmd(int argc __unused, char **argv __unused)
{
if (!getpwd())
error("getcwd() failed: %s", strerror(errno));
out1str(curdir);
out1c('\n');
char buf[MAXPWD];
int ch, phys;
optreset = 1; optind = 1; /* initialize getopt */
phys = 0;
while ((ch = getopt(argc, argv, "LP")) != -1) {
switch (ch) {
case 'L':
phys = 0;
break;
case 'P':
phys = 1;
break;
default:
error("unknown option: -%c", optopt);
break;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
error("too many arguments");
if (!phys && getpwd()) {
out1str(curdir);
out1c('\n');
} else {
if (getcwd(buf, sizeof(buf)) == NULL)
error(".: %s", strerror(errno));
out1str(buf);
out1c('\n');
}
return 0;
}
#define MAXPWD 256
/*
* Find out what the current directory is. If we already know the current
* directory, this routine returns immediately.

View File

@ -1317,7 +1317,11 @@ Execute the specified builtin command,
.Ar cmd .
This is useful when the user wishes to override a shell function
with the same name as a builtin command.
.It Ic cd Op Ar directory
.It Xo
.Ic cd
.Op Fl LP
.Op Ar directory
.Xc
Switch to the specified
.Ar directory ,
or to the directory specified in the
@ -1351,6 +1355,20 @@ if this is different from the name that the user gave.
These may be different either because the
.Ev CDPATH
mechanism was used or because a symbolic link was crossed.
.Pp
If the
.Fl P
option is specified,
.Dq \&..
is handled physically and symbolic links are resolved before
.Dq \&..
components are processed.
If the
.Fl L
option is specified,
.Dq \&..
is handled logically.
This is the default.
.It Ic chdir
A synonym for the
.Ic cd
@ -1622,7 +1640,10 @@ argument is omitted, use the current job.
.It Ic jobs
This command lists out all the background processes
which are children of the current shell process.
.It Ic pwd
.It Xo
.Ic pwd
.Op Fl LP
.Xc
Print the path of the current directory. The builtin command may
differ from the program of the same name because the
builtin command remembers what the current directory
@ -1632,6 +1653,15 @@ renamed,
the builtin version of
.Xr pwd 1
will continue to print the old name for the directory.
.Pp
If the
.Fl P
option is specified, symbolic links are resolved.
If the
.Fl L
option is specified, the shell's notion of the current directory
is printed (symbolic links are not resolved).
This is the default.
.It Xo
.Ic read
.Op Fl p Ar prompt