1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 11:42:21 +00:00

cd: Fork if $PWD exists but is not actually the PWD (re: d1483150)

Commit d1483150 did not fully fix #153.
Test case from Harald van Dijk that was still failing:

$ mkdir test
$ cd test
$ rmdir $PWD
$ mkdir $PWD
$ ksh -c "(cd /); pwd"
/

Forking a virtual subshell in that case is needed to avoid ending
up in a directory that replaced the PWD, because it will not be
possible for a process to change back to the original directory.

src/cmd/ksh93/bltins/cd_pwd.c:
- When deciding whether to fork, instead of attempting to opendir
  the PWD, compare the inodes $PWD and "." to determine if $PWD
  still actually refers to the current directory. This uses the
  test_inode() function which is also used by 'test foo -ef bar'.

src/cmd/ksh93/tests/subshell.sh:
- Add test based on the above.

Progresses: https://github.com/ksh93/ksh/issues/153
This commit is contained in:
Martijn Dekker 2021-01-20 05:43:46 +00:00
parent ec0155ee65
commit 5ee290c7a8
2 changed files with 10 additions and 5 deletions

View file

@ -37,7 +37,6 @@
#include "name.h"
#include "builtins.h"
#include <ls.h>
#include <ast_dir.h>
/*
* Invalidate path name bindings to relative paths
@ -99,10 +98,7 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
if(shp->subshell && !shp->subshare)
{
#if _lib_fchdir
DIR *testdir;
if(testdir = opendir(nv_getval(pwdnod)))
closedir(testdir);
else
if(!test_inode(nv_getval(pwdnod),e_dot))
#endif
sh_subfork();
}

View file

@ -904,6 +904,15 @@ exp="PWD=$PWD"
got=$( { "$SHELL" -c '(cd /; (cd /)); print -r -- "PWD=$PWD"'; } 2>&1 )
((!(e = $?))) && [[ $got == "$exp" ]] || err_exit 'failed to restore nonexistent PWD on exiting a virtual subshell' \
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
cd "$tmp"
mkdir recreated
cd recreated
tmp=$tmp "$SHELL" -c 'cd /; rmdir "$tmp/recreated"; mkdir "$tmp/recreated"'
exp="PWD=$PWD"
got=$( { "$SHELL" -c '(cd /); print -r -- "PWD=$PWD"'; } 2>&1 )
((!(e = $?))) && [[ $got == "$exp" ]] || err_exit 'failed to restore re-created PWD on exiting a virtual subshell' \
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
cd "$tmp"
# ======
exit $((Errors<125?Errors:125))