summaryrefslogtreecommitdiffstats
path: root/bin/sh/cd.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/sh/cd.c')
-rw-r--r--bin/sh/cd.c83
1 files changed, 45 insertions, 38 deletions
diff --git a/bin/sh/cd.c b/bin/sh/cd.c
index d52c9b8..4abe91e 100644
--- a/bin/sh/cd.c
+++ b/bin/sh/cd.c
@@ -68,7 +68,9 @@ STATIC int cdlogical(char *);
STATIC int cdphysical(char *);
STATIC int docd(char *, int, int);
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 *prevdir; /* previous working directory */
@@ -201,10 +203,11 @@ cdlogical(char *dest)
}
INTOFF;
- if (updatepwd(badstat ? NULL : dest) < 0 || chdir(curdir) < 0) {
+ if ((p = findcwd(badstat ? NULL : dest)) == NULL || chdir(p) < 0) {
INTON;
return (-1);
}
+ updatepwd(p);
INTON;
return (0);
}
@@ -212,12 +215,14 @@ cdlogical(char *dest)
STATIC int
cdphysical(char *dest)
{
+ char *p;
INTOFF;
- if (chdir(dest) < 0 || updatepwd(NULL) < 0) {
+ if (chdir(dest) < 0 || (p = findcwd(NULL)) == NULL) {
INTON;
return (-1);
}
+ updatepwd(p);
INTON;
return (0);
}
@@ -247,38 +252,20 @@ getcomponent(void)
}
-/*
- * 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 int
-updatepwd(char *dir)
+STATIC char *
+findcwd(char *dir)
{
char *new;
char *p;
- hashcd(); /* update command hash table */
-
/*
* If our argument is NULL, we don't know the current directory
* any more because we traversed a symbolic link or something
* we couldn't stat().
*/
if (dir == NULL || curdir == NULL) {
- if (prevdir)
- ckfree(prevdir);
- INTOFF;
- prevdir = curdir;
- curdir = NULL;
- if (getpwd() == NULL) {
- INTON;
- return (-1);
- }
- setvar("PWD", curdir, VEXPORT);
- setvar("OLDPWD", prevdir, VEXPORT);
- INTON;
- return (0);
+ p = stalloc(PATH_MAX);
+ return getpwd2(p, PATH_MAX);
}
cdcomppath = stalloc(strlen(dir) + 1);
scopy(dir, cdcomppath);
@@ -302,16 +289,25 @@ updatepwd(char *dir)
if (new == stackblock())
STPUTC('/', 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)
ckfree(prevdir);
prevdir = curdir;
- curdir = savestr(stackblock());
+ curdir = savestr(dir);
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
- INTON;
-
- return (0);
}
int
@@ -355,17 +351,31 @@ pwdcmd(int argc, char **argv)
}
/*
- * Find out what the current directory is. If we already know the current
- * directory, this routine returns immediately.
+ * Get the current directory and cache the result in curdir.
*/
char *
getpwd(void)
{
char buf[PATH_MAX];
+ char *p;
if (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");
struct stat stdot, stpwd;
@@ -373,12 +383,9 @@ getpwd(void)
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
- curdir = savestr(pwd);
- return curdir;
+ return pwd;
}
return NULL;
}
- curdir = savestr(buf);
-
- return curdir;
+ return buf;
}
OpenPOWER on IntegriCloud