[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#230857: Preinst should rename old devpts.sh to mountkernfs



On Mon, 2004-03-15 at 12:53, Miquel van Smoorenburg wrote:
> On 2004.03.15 12:22, Thomas Hood wrote:
> > I pursued the readlink() issue with upstream.  Most of the
> > discussion is logged in coreutils bug #225836: "readlink: Please
> > implement --recursive option".
> 
> Nobody noticed, but it's a glibc bug.
>
> According to the glibc docs, realpath() is just a wrapper for
> canonicalize_file_name() [in the actual code, it's the other
> way around, but oh well]

The readlink program doesn't use the C Library realpath().
Check it out -- it uses its own xreadlink() and readlink() 
functions.

There is a long story behind this.  Traditionally (and still,
according to realpath(3) but not according to /usr/include/stdlib.h)
realpath()'s second argument had to be a pointer to a buffer of
size >= PATH_MAX into which realpath would write the real path of
length up to PATH_MAX.  Some systems don't have a fixed PATH_MAX,
however, and the old realpath() was useless on those systems.

So at some point someone added canonicalize_file_name() to the
GNU C library.  This took no second argument but malloc()ed
the buffer into which the real path was to be written.
People porting programs to GNU/Hurd (which lacks a PATH_MAX)
started using canonicalize_file_name(), but since this was a
GNU extension and not part of POSIX, programs intended for use 
outside the GNU system had to roll their own.

Now realpath() has been modified so that its second argument
can be NULL, in which case it acts like canonicalize_file_name():
it malloc()s the necessary buffer and returns a pointer to it.
See the comment preceding the declaration of realpath() in
stdlib.h for details.  From what you say I gather that
canonicalize_file_name() is now a wrapper around the new
improved realpath() instead of vice versa.

However, a lot of programs out there still contain their own
custom code.  Readlink, df and mount are three that I know of.


> The canonicalize_file_name() docs say:
> 
>    Function: char * canonicalize_file_name (const char *name)
>                                                                                 
>            The canonicalize_file_name function returns the absolute name of
>            the file named by name which contains no ., .. components nor any
>            repeated path separators (/) or symlinks. The result is passed
>            back as the return value of the function in a block of memory
>            allocated with malloc. If the result is not used anymore the
>            memory should be freed with a call to free.
>                                                                                 
>            In any of the path components except the last one is missing the
>                                          ^^^^^^^^^^^^^^^^^^^
>            function returns a NULL pointer. This is also what is returned if
>            the length of the path reaches or exceeds PATH_MAX characters. In
>            any case errno is set accordingly.
>                                                                                 
> Unfortunately, the current glibc implementation doesn't do what the docs say
> it should do (the part I underlined with carets).


realpath() is also described as tolerating a missing final component.
We should test it to see if it works.


> It's reasonable behaviour for realpath and canonicalize_file_name to
> succeed if the entire path exists except the last component. I'd build in
> an extra check though - the path leading to the last component must be
> a directory.

Yes.

-- 
Thomas Hood <jdthood@yahoo.co.uk>




Reply to: