[Toybox] realpath implementation

Rob Landley rob at landley.net
Fri Feb 17 03:26:40 PST 2012


On 02/14/2012 02:16 PM, Andre Renaud wrote:
> Hi Elie,
> 
>> Just a question/suggestion, now you're using your own
>>
>> char buffer[PATH_MAX];
>>
>> to hold your result, why not make use of the globally existing char
>> toybuff[4096] (see toys.h/main.c), most other tools make use of this
>> buffer for similar needs.
> 
> Thanks for that - I wasn't aware of the toybuf scratch space.
> 
> Attached is the (trivially) updated implementation.
> 
> Regards,
> Andre

I note that loopfiles() opens each file argument, and that if you do
something like:

  ln -s /root/thing blah
  ./toybox realpath blah

It gives a permission denied error trying to open blah before it gets to
calling do_realpath(), and thus the perror_exit() never triggers.

I moved it to a for(;;) loop instead of loopfiles(), since we should be
able to determine the real location of a file we haven't got permission
to actually read from, as long as we've got permission to read the
directory info.  Also switched to perror_msg() instead of exit so it
doesn't stop at the first failure, and moved the xprintf() to the else
case (and switched to xputs() since it's just printing one line), and
added a usage: line.

I'm also sort of torn on this one since on my system:

$ realpath
The program 'realpath' is currently not installed.  You can install it
by typing:
sudo apt-get install realpath

I.E. not installed by default on Ubuntu 10.04 LTS.

Yeah it's in busybox, but there's a lot of stuff in busybox that
probably shouldn't be.  It's not in susv4, it does the same thing as
readlink -f, and I vaguely recall there's a shell builtin required by
posix that does the same thing readlink -f did. (Again, that last one is
something you'd think I'd have noted in my blog, but I haven't been
blogging conscientiously lately.)

What I really want to do is make this an OLDTOY() variant of readlink
-f, then the overhead of having another way to say the same thing is low
enough not to bother me.  Possibly OLDTOY() should have a way to set a
flag bit when calling another function's main()?  The overhead of having
an extra field in toy_list[] for that would be unacceptable, but there
are plenty of bits left in toy_list.flags, or I could teach options
parsing to have some sort of "always consider this one set" annotation,
maybe * is a good character for that...

Think think think...

Oh, the reason I hadn't done this before is the comments in
man 3 readlink about PATH_MAX being obsolete.  In Linux, path lengths
are now unbounded (since sometime in 2.5 I think), so it is posible for
a deep enough directory tree to blow past any fixed size buffer.  I
believe I sent a patch to uClibc a year or two back to teach it the NULL
means malloc() a big enough buffer trick, although all that did was
malloc a PATH_MAX sized block which isn't a _proper_ fix.  No idea what
Android's bionic's doing...

(Surprising amount of complication for such a simple command, isn't it?
 I tend to overthink things...)

Rob



More information about the Toybox mailing list