summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/cd.c27
-rw-r--r--bin/sh/cd.h2
-rw-r--r--bin/sh/main.c5
-rw-r--r--tools/regression/bin/sh/parameters/pwd2.024
4 files changed, 48 insertions, 10 deletions
diff --git a/bin/sh/cd.c b/bin/sh/cd.c
index 40801ba..aee06e8 100644
--- a/bin/sh/cd.c
+++ b/bin/sh/cd.c
@@ -70,6 +70,7 @@ STATIC int docd(char *, int, int);
STATIC char *getcomponent(void);
STATIC char *findcwd(char *);
STATIC void updatepwd(char *);
+STATIC char *getpwd(void);
STATIC char *getpwd2(void);
STATIC char *curdir = NULL; /* current working directory */
@@ -351,7 +352,7 @@ pwdcmd(int argc, char **argv)
/*
* Get the current directory and cache the result in curdir.
*/
-char *
+STATIC char *
getpwd(void)
{
char *p;
@@ -374,7 +375,6 @@ getpwd(void)
STATIC char *
getpwd2(void)
{
- struct stat stdot, stpwd;
char *pwd;
int i;
@@ -387,12 +387,29 @@ getpwd2(void)
break;
}
- pwd = getenv("PWD");
+ return NULL;
+}
+
+/*
+ * Initialize PWD in a new shell.
+ * If the shell is interactive, we need to warn if this fails.
+ */
+void
+pwd_init(int warn)
+{
+ char *pwd;
+ struct stat stdot, stpwd;
+
+ pwd = lookupvar("PWD");
if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
- return pwd;
+ if (curdir)
+ ckfree(curdir);
+ curdir = savestr(pwd);
}
- return NULL;
+ if (getpwd() == NULL && warn)
+ out2fmt_flush("sh: cannot determine working directory\n");
+ setvar("PWD", curdir, VEXPORT);
}
diff --git a/bin/sh/cd.h b/bin/sh/cd.h
index 0a2d489..f88ce26 100644
--- a/bin/sh/cd.h
+++ b/bin/sh/cd.h
@@ -29,6 +29,6 @@
* $FreeBSD$
*/
-char *getpwd(void);
+void pwd_init(int);
int cdcmd (int, char **);
int pwdcmd(int, char **);
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 50a8813..ecbb12d 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -153,10 +153,7 @@ main(int argc, char *argv[])
init();
setstackmark(&smark);
procargs(argc, argv);
- if (getpwd() == NULL && iflag)
- out2fmt_flush("sh: cannot determine working directory\n");
- if (getpwd() != NULL)
- setvar ("PWD", getpwd(), VEXPORT);
+ pwd_init(iflag);
if (iflag)
chkmail(1);
if (argv[0] && argv[0][0] == '-') {
diff --git a/tools/regression/bin/sh/parameters/pwd2.0 b/tools/regression/bin/sh/parameters/pwd2.0
new file mode 100644
index 0000000..29b5531
--- /dev/null
+++ b/tools/regression/bin/sh/parameters/pwd2.0
@@ -0,0 +1,24 @@
+# $FreeBSD$
+# Check that PWD is exported and accepted from the environment.
+set -e
+
+T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX)
+trap 'rm -rf $T' 0
+cd -P $T
+TP=$(pwd)
+mkdir test1
+ln -s test1 link
+cd link
+[ "$PWD" = "$TP/link" ]
+[ "$(pwd)" = "$TP/link" ]
+[ "$(pwd -P)" = "$TP/test1" ]
+[ "$(sh -c pwd)" = "$TP/link" ]
+[ "$(sh -c pwd\ -P)" = "$TP/test1" ]
+cd ..
+[ "$(pwd)" = "$TP" ]
+cd -P link
+[ "$PWD" = "$TP/test1" ]
+[ "$(pwd)" = "$TP/test1" ]
+[ "$(pwd -P)" = "$TP/test1" ]
+[ "$(sh -c pwd)" = "$TP/test1" ]
+[ "$(sh -c pwd\ -P)" = "$TP/test1" ]
OpenPOWER on IntegriCloud