Split updatepwd() into two smaller functions. The first one, findpwd(),
computes the new path and the second one, updatepwd(), updates the variables PWD, OLDPWD and the path used for the pwd builtin according to the new directory. For a logical directory change, chdir() is now called between those two functions, no longer causing wrong values to be stored in PWD etc. if it fails. PR: 64990, 101316, 120571
This commit is contained in:
parent
0d54671a48
commit
fe9202bf0f
83
bin/sh/cd.c
83
bin/sh/cd.c
@ -68,7 +68,9 @@ STATIC int cdlogical(char *);
|
|||||||
STATIC int cdphysical(char *);
|
STATIC int cdphysical(char *);
|
||||||
STATIC int docd(char *, int, int);
|
STATIC int docd(char *, int, int);
|
||||||
STATIC char *getcomponent(void);
|
STATIC char *getcomponent(void);
|
||||||
STATIC int updatepwd(char *);
|
STATIC char *findcwd(char *);
|
||||||
|
STATIC void updatepwd(char *);
|
||||||
|
STATIC char *getpwd2(char *, size_t);
|
||||||
|
|
||||||
STATIC char *curdir = NULL; /* current working directory */
|
STATIC char *curdir = NULL; /* current working directory */
|
||||||
STATIC char *prevdir; /* previous working directory */
|
STATIC char *prevdir; /* previous working directory */
|
||||||
@ -201,10 +203,11 @@ cdlogical(char *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
INTOFF;
|
INTOFF;
|
||||||
if (updatepwd(badstat ? NULL : dest) < 0 || chdir(curdir) < 0) {
|
if ((p = findcwd(badstat ? NULL : dest)) == NULL || chdir(p) < 0) {
|
||||||
INTON;
|
INTON;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
updatepwd(p);
|
||||||
INTON;
|
INTON;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -212,12 +215,14 @@ cdlogical(char *dest)
|
|||||||
STATIC int
|
STATIC int
|
||||||
cdphysical(char *dest)
|
cdphysical(char *dest)
|
||||||
{
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
INTOFF;
|
INTOFF;
|
||||||
if (chdir(dest) < 0 || updatepwd(NULL) < 0) {
|
if (chdir(dest) < 0 || (p = findcwd(NULL)) == NULL) {
|
||||||
INTON;
|
INTON;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
updatepwd(p);
|
||||||
INTON;
|
INTON;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -247,38 +252,20 @@ getcomponent(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
STATIC char *
|
||||||
* Update curdir (the name of the current directory) in response to a
|
findcwd(char *dir)
|
||||||
* cd command. We also call hashcd to let the routines in exec.c know
|
|
||||||
* that the current directory has changed.
|
|
||||||
*/
|
|
||||||
STATIC int
|
|
||||||
updatepwd(char *dir)
|
|
||||||
{
|
{
|
||||||
char *new;
|
char *new;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
hashcd(); /* update command hash table */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If our argument is NULL, we don't know the current directory
|
* If our argument is NULL, we don't know the current directory
|
||||||
* any more because we traversed a symbolic link or something
|
* any more because we traversed a symbolic link or something
|
||||||
* we couldn't stat().
|
* we couldn't stat().
|
||||||
*/
|
*/
|
||||||
if (dir == NULL || curdir == NULL) {
|
if (dir == NULL || curdir == NULL) {
|
||||||
if (prevdir)
|
p = stalloc(PATH_MAX);
|
||||||
ckfree(prevdir);
|
return getpwd2(p, PATH_MAX);
|
||||||
INTOFF;
|
|
||||||
prevdir = curdir;
|
|
||||||
curdir = NULL;
|
|
||||||
if (getpwd() == NULL) {
|
|
||||||
INTON;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
setvar("PWD", curdir, VEXPORT);
|
|
||||||
setvar("OLDPWD", prevdir, VEXPORT);
|
|
||||||
INTON;
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
cdcomppath = stalloc(strlen(dir) + 1);
|
cdcomppath = stalloc(strlen(dir) + 1);
|
||||||
scopy(dir, cdcomppath);
|
scopy(dir, cdcomppath);
|
||||||
@ -302,16 +289,25 @@ updatepwd(char *dir)
|
|||||||
if (new == stackblock())
|
if (new == stackblock())
|
||||||
STPUTC('/', new);
|
STPUTC('/', new);
|
||||||
STACKSTRNUL(new);
|
STACKSTRNUL(new);
|
||||||
INTOFF;
|
return stackblock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update curdir (the name of the current directory) in response to a
|
||||||
|
* cd command. We also call hashcd to let the routines in exec.c know
|
||||||
|
* that the current directory has changed.
|
||||||
|
*/
|
||||||
|
STATIC void
|
||||||
|
updatepwd(char *dir)
|
||||||
|
{
|
||||||
|
hashcd(); /* update command hash table */
|
||||||
|
|
||||||
if (prevdir)
|
if (prevdir)
|
||||||
ckfree(prevdir);
|
ckfree(prevdir);
|
||||||
prevdir = curdir;
|
prevdir = curdir;
|
||||||
curdir = savestr(stackblock());
|
curdir = savestr(dir);
|
||||||
setvar("PWD", curdir, VEXPORT);
|
setvar("PWD", curdir, VEXPORT);
|
||||||
setvar("OLDPWD", prevdir, VEXPORT);
|
setvar("OLDPWD", prevdir, VEXPORT);
|
||||||
INTON;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -355,17 +351,31 @@ pwdcmd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find out what the current directory is. If we already know the current
|
* Get the current directory and cache the result in curdir.
|
||||||
* directory, this routine returns immediately.
|
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
getpwd(void)
|
getpwd(void)
|
||||||
{
|
{
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
char *p;
|
||||||
|
|
||||||
if (curdir)
|
if (curdir)
|
||||||
return curdir;
|
return curdir;
|
||||||
if (getcwd(buf, sizeof(buf)) == NULL) {
|
|
||||||
|
p = getpwd2(buf, sizeof(buf));
|
||||||
|
if (p != NULL)
|
||||||
|
curdir = savestr(p);
|
||||||
|
|
||||||
|
return curdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the current directory.
|
||||||
|
*/
|
||||||
|
STATIC char *
|
||||||
|
getpwd2(char *buf, size_t size)
|
||||||
|
{
|
||||||
|
if (getcwd(buf, size) == NULL) {
|
||||||
char *pwd = getenv("PWD");
|
char *pwd = getenv("PWD");
|
||||||
struct stat stdot, stpwd;
|
struct stat stdot, stpwd;
|
||||||
|
|
||||||
@ -373,12 +383,9 @@ getpwd(void)
|
|||||||
stat(pwd, &stpwd) != -1 &&
|
stat(pwd, &stpwd) != -1 &&
|
||||||
stdot.st_dev == stpwd.st_dev &&
|
stdot.st_dev == stpwd.st_dev &&
|
||||||
stdot.st_ino == stpwd.st_ino) {
|
stdot.st_ino == stpwd.st_ino) {
|
||||||
curdir = savestr(pwd);
|
return pwd;
|
||||||
return curdir;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
curdir = savestr(buf);
|
return buf;
|
||||||
|
|
||||||
return curdir;
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user