From: Stephane Chazelas <stephane@chazelas.org>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: can we have an option for cd to do a plain chdir()
Date: Sun, 6 Feb 2022 17:44:06 +0000 [thread overview]
Message-ID: <20220206174406.rirklyrkzlx6winw@chazelas.org> (raw)
I was surprised to see that after:
ln -s /proc/self/cwd/.. link; cd link
I ended up two directories up instead of one.
strace revealed:
$ strace -fe getcwd,readlink,chdir,fchdir zsh -c 'cd link'
readlink("/proc/self/fd/0", "/dev/pts/4", 4095) = 10
chdir("/home/chazelas/link") = 0
chdir("/home/chazelas/link") = 0
+++ exited with 0 +++
Not sure why the two chdir()s there.
That it prepends $PWD to the path is also a problem if the
current working directory has been renamed, but most shells do
that without -P.
It's better in that case with cd -P or with chaselinks:
$ strace -fe getcwd,readlink,chdir,fchdir zsh -c 'cd -P link'
readlink("/proc/self/fd/0", "/dev/pts/4", 4095) = 10
chdir("/home/chazelas/link") = 0
readlink("/home", 0x7ffe6ba34f00, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/chazelas", 0x7ffe6ba34f00, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/chazelas/link", "/proc/self/cwd/..", 4096) = 17
readlink("/proc", 0x7ffe6ba2fe70, 4096) = -1 EINVAL (Invalid argument)
readlink("/proc/self", "1000438", 4096) = 7
readlink("/proc/1000438", 0x7ffe6ba2ade0, 4096) = -1 EINVAL (Invalid argument)
readlink("/proc/1000438/cwd", "/home", 4096) = 5
readlink("/home", 0x7ffe6ba2ade0, 4096) = -1 EINVAL (Invalid argument)
chdir("..") = 0
chdir("/home") = 0
+++ exited with 0 +++
~$ strace -fe getcwd,readlink,chdir,fchdir zsh -o chaselinks -c 'cd link'
readlink("/proc/self/fd/0", "/dev/pts/4", 4095) = 10
readlink("/home", 0x7ffdfc3e0f40, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/chazelas", 0x7ffdfc3e0f40, 4096) = -1 EINVAL (Invalid argument)
chdir("/home/chazelas/link") = 0
readlink("/home", 0x7ffdfc3df960, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/chazelas", 0x7ffdfc3df960, 4096) = -1 EINVAL (Invalid argument)
readlink("/home/chazelas/link", "/proc/self/cwd/..", 4096) = 17
readlink("/proc", 0x7ffdfc3da8d0, 4096) = -1 EINVAL (Invalid argument)
readlink("/proc/self", "1002598", 4096) = 7
readlink("/proc/1002598", 0x7ffdfc3d5840, 4096) = -1 EINVAL (Invalid argument)
readlink("/proc/1002598/cwd", "/home", 4096) = 5
readlink("/home", 0x7ffdfc3d5840, 4096) = -1 EINVAL (Invalid argument)
chdir("..") = 0
chdir("/home") = 0
+++ exited with 0 +++
But that sounds a bit overkill and racy.
In scripts, you usually want your cd's to do plain chdir()s but
there are many things that get in the way:
- the need for -P to avoid the logical traversal
- the need to -- as usual for avoid problems with dirnames
starting with -
- CDPATH (it is inherited from the environment but at least when
not in POSIX mode, that doesn't take precedence over actual
relative path).
- The "-" string that is taken as $OLDPWD
- Also in zsh, the -n +n ones.
- and then there's that special fancy chasing of symlinks
So, to do an actual chdir, we need something like:
chdir() {
case $1 in
(/*) cd -P "$1";;
('') print -u2 "not sure out to chdir to an empty string";;
(*) cd -P "./$1";;
esac
}
Which addresses the first 5 points, but not the 6th.
It would be nice if we could just do for instance cd -r -- $dir
which would just a do chdir($dir) and set $PWD to getcwd() if
successful.
(or have chdir (which atm exits as a builtin for tcsh junkies I
suppose) do that and not take any option).
What do you think?
--
Stephane
next reply other threads:[~2022-02-06 17:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-06 17:44 Stephane Chazelas [this message]
2022-02-09 17:16 ` Bart Schaefer
2022-02-10 20:27 ` Stephane Chazelas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220206174406.rirklyrkzlx6winw@chazelas.org \
--to=stephane@chazelas.org \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).