[Toybox] Add remaining pwd options
Rob Landley
rob at landley.net
Sun Jan 13 07:57:28 PST 2013
On 01/13/2013 04:34:56 AM, Felix Janda wrote:
> Sorry for this repeated hair-splitting.
Eh, it happens. :)
I'm constantly mucking about in areas I'm brand new to (or haven't got
the background for, or last messed with so long ago I've forgotten
important things, or while massively distracted and sleep deprived...),
so I'm wrong a lot. I just try to fix it when I notice.
> On 01/12/13 at 11:33pm, Rob Landley wrote:
> > On 01/10/2013 02:25:13 PM, Felix Janda wrote:
> > > On 01/02/13 at 12:41am, Rob Landley wrote:
> > > > What I did was disable #3 in the case where cwd doesn't exist.
> So
> > > the
> > > > new rule #3 is:
> > > >
> > > > 3) If cwd exists and $PWD doesn't point to it, fall back to -P.
> > >
> > > Thanks for the clarification.
> > >
> > > Your version of 3) depends on whether pwd is builtin or not. Do
> you
> > > mean
> > > something like "If getcwd() fails ..."?
> >
> > cwd is what getcwd() returns. $PWD is an environment variable.
>
> I wanted to differentiate between the current working directory and
> its
> name.
The kernel has two magic symlinks as part of each process's state:
1) "." which is set by chdir() and returned by getcwd().
2) "/" which is set by chroot() and not really returned by anything
because it's what other paths are explained relative _to_.
Inside the kernel, each points to a dentry, which is pinned by the
reference so you don't have to worry about it going away. (It can be
invalidated by deleting the dentry's attached inode, but I believe it's
still around as a zombie until the reference count drops to zero. And
there's a horrible magic syscall called switch_root that iterates
through every process in the system and redirects the "." and "/" links
of every process from one of these to another, but that does horrible
latency spike locking.)
Each dentry has a ".." link, which is not a process attribute, but a
dentry attribute. (Or is it inode? The fact dentries aren't really
independent of an underlying inode is half the reason you can't
hardlink directories. Anyway, ".." is implemented by following the
dentry parent pointer, with the exception that "/" pointing to the
current dentry is treated the same as the dentry parent pointer being
NULL. Yes, this means that if you go:
mkdir("sub");
chroot("sub");
chdir("../../../../../../../../..");
chroot(".");
You can escape a chroot. Moving the "/" symlink _under_ "." means the
.. test won't hit it, you see. There's no >= test here, just ==.
Anyway, given a dentry the kernel can traverse up to the root (either
equal to "/" or where the dentry parent pointer is NULL) to work out
the absolute path to this dentry, and since each dentry only has one
parent pointer there's only _one_ absolute path to a given dentry.
Does that help?
> Doesn't an unliked current working still exist for the processes
> its the cwd of?
You have a pointer to a zombie dentry, the parent pointer of which is
NULL. It's been unlinked from the tree but won't be garbage collected
until the reference count falls to zero. I'd guess the corresponding
inode has been freed and thus the inode pointer is also NULL (thus
freeing up actual disk space, unlike a filehandle to an open _file_),
but I'd have to go look at the kernel source to know for sure.
> (I was wrong about that 3) depends on whether pwd in
> builtin or not since child processes inherit cwd.)
Child processes inherit environment variables too, but a child process
can't change the parent's attributes. (Ok, it could ptrace it but
that's HORRIBLE and we're not doing that. Sorry, reflexive action
anytime anyone, including me, says "you can't do X". There's usually a
bad way to do it. I have a black belt in bad ways to do things, and a
lot of experience in cleaning them up to look presentable. I do the
"don't ask questions, post errors" thing to _myself_ all the time.)
> > > > > BTW, in the case that one has deleted and recreated one's
> current
> > > > > working
> > > > > directory one could also use "cd ." to get to the new
> directory.
> > > >
> > > > Good to know. (This means the shell is special casing "." as
> well as
> > > > "..". I need to read the susv4 shell stuff thoroughly, it's been
> > > > years...)
> > >
> > > The susv4 page special cases "." and ".." a bit, but it seems to
> me
> > > only
> > > in the $CDPATH handling. Ah, I see that you don't care about
> $CDPATH
> > > from
> > > the about page.
> >
> > $CDPATH and $PWD are separate.
>
> I just read
>
> http://landley.net/toybox/about.html:
I read http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cd.html
(About the above URL: don't ask me why www.opengroup.org redirects to
pubs.opengroup.org but just opengroup.org says the service is
discontinued. The safe thing to do is probably just
http://pubs.opengroup.org/onlinepubs/9699919799/download/ and use a
file:// url on the local disk. That's what I do most of the time, and
then have to dig up a public URL when I want to point somebody else at
a page...)
> > And some things (like $CDPATH support in "cd") await a good
> explanation
> > of why to bother with them.
>
> and interpreted it as a reluctance to implement $CDPATH support.
I am reluctant to implement $CDPATH support. Having a search path so
that when you
"cd frog" it finds /usr/ranunculus/diseases/frog is just _weird_. That
said, someday an actual user of it might show up and change my mind.
> > > Then I think one can leave out step 5 on susv4's page on
> > > cd, and "cd ." is no more special than "cd dir"; it does a chdir
> to
> > > "$PWD/."
> > > or "$PWD/dir" respectively and then updates $PWD to its canonical
> > > form. (and
> > > modifies $OLDPWD also if necessary)
> >
> > Um, steps 4 and 8 are the ones that say cd . and .. are special?
>
> Step 4 means that $CDPATH shouldn't be taken into account when you do
> something like "cd ./dir" or "cd ../dir".
$CDPATH is not the same as $PWD. $CDPATH is a _search_path_ for cd. You
know how when you run an executable it searches $PATH? Apparently when
you cd to a directory it searches $CDPATH. Who knew? I didn't, and I've
been using unix variants since the late 80's. (Well, if you count Vax
Eunice on my father's work machine which had an amiga software library
on it and xmodem. If you count _actual_ unix, more like 1992.)
> In Step 8 the usual formal processes of simplifying a path (by
> removing "."
> dot components and so on) described.
>
> Of course here "." and ".." are treated specially, but this treatment
> affects only $PWD, since chdir("/some/dir/.") should do the same as
> chdir("/some/dir").
I'm only talking about $PWD.
> Step 9 looks like fun...
I have an epic todo list for toysh. "cd" is a shell command, thus part
of toysh.
Part of the reason I haven't been dinking at it in small amounts is
there's so much context to keeps traight in your head I should probably
buckle down and focus on just the shell for a couple months at some
point, and right now the same effort completes multiple smaller
commands.
That said, I should do the basic cleanup pass (remove toybuf dependency
that imposes command line length limitations), add basic environment
variable support, start on conditionals (if/while/for)...
But I need to finish the cleanup pass on cp. And finish the
losetup/umount/mount chain. And review the pile of commands that are
already in but not properly cleaned up. And figure out why current
toolchains stopped doing proper dead function elimination (a toybox
with just "true" on x86-64 is 15k! That's ridiculous. Admittedly a
main() that does nothing but "return 1", built with -s -Os is 6k.
That's gcc+glibc for you. But still, that extra 9k is sad. And if you
objdump -d a toybox built with gcc 4.2.1 it hasn't got parse_optflags()
in it, but one built with ubuntu's current gcc does. Yup, upstream
toolchain regression in the ability to eliminiate dead code. The
<strike>aristocrats</strike> free software foundation!
Rob
1358092648.0
More information about the Toybox
mailing list