- summary: 20040217 Defect in current_directory --> Defect in current_directory
I'm trying to use Poplog on a shared machine on which
the directory /home is executable but not
readable.
[/home] % ls -ald
drwx--x--x 47 root root 4096 Feb 17 16:56 .
However, there is a defect in the implementation of
current_directory that prevents basepop11 from
opening relative path names such as
/home/steve/.bashrc
An attempt to open a file such as this involves a walk
up the directory hierarchy in order to
determine a canonical path. At each step up the
hierarchy the procedure Read_entry, which is
implemented in terms of readdir, is used to search for
a sub-directory with a matching inode.
There are two errors in this implementation. Firstly,
there is no guarantee that readdir can be
applied to all super-directories - indeed this is a
very bad assumption. Secondly, this will not
generate the canonical path in the presence of hard links.
The implementation is defined in $popsrc/unix_dir.p and
the relevant procedure appears to be
Get_curr_dir on line 155. The calls to Read_entry are
on line 192 and 199. (Note that there are two
different implementations of Read_entry distinguished
by conditional compilation.)
There are many situations under which this
implementation bails out when the obvious
implementation, which would use getcwd, would succeed.
I regard it as an error to mishap in the
pursuit of the "ultimate" canonical pathname rather
than simply fallback to the more obvious
approach.
The procedure current_directory is central to the
proper functioning of Poplog. It is employed by
Sys_open (from $popsrc/sysopen.p) to produce absolute
filenames for sysopen, for example. This
completely disables core functionality such as Ved.
To fix this problem, I suggest implementing an
alternative version of Get_curr_dir that utilizes
getcwd (see man 3 getcwd). Then modify both versions
so that they take an extra flag indicating
whether or not they are permitted to fail or should
simply return <false>. It would then be simple to
provide an umbrella Get_curr_dir that tries both, only
mishapping after having tried both.
(The only catch to this proposal is that getcwd has an
especially poor interface in view of memory
handling. I would suggest passing in sysstring and
bailing out if the path length is longer than that -
it is only a fallback strategy.)
--
Steve