[Top][All Lists]

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

bug#36416: realpath doesn't preserve '..' consistently as per POSIX, nor

From: L A Walsh
Subject: bug#36416: realpath doesn't preserve '..' consistently as per POSIX, nor '/.'
Date: Sat, 29 Jun 2019 12:21:23 -0700
User-agent: Thunderbird

On 2019/06/28 12:02, Eric Blake wrote:
> If your application layer is on top of Linux, then yes, the underlying
> OS guarantees that your application processing a path beginning with
> "//" is correct whether it preserves or shortens that path to "/".
        Linux doesn't forever guarantee that it will or won't
use '//'.

> If you port the source code of an application originally built on Linux
> to then operate on some other operating system, then the source code is
> buggy if it shortens the path to "/". But you have to actually check the
> source code to see if it has that bug - just because 'realpath' in
> coreutils shortens '//' to '/' on Linux does NOT mean that it is buggy,
> because the code for realpath has an explicit check (run at
> configure-time) for whether "//" is distinct from "/" - and on platforms
> where that check is answered differently than on Linux, the code behaves
> differently.  That is, the coreutils code is self-adapting to the
> implementation definition of the implementation it is compiled on.
        As long as realpath guarantees that the generated binary 
won't work on any other version of linux, that would be true.  However
the run-time binary isn't recompiled with each version of linux.

>> It would useful if bugs were not closed before asking for more
>> information. 
> They can always be reopened if you provide enough relevant information
> to show it was closed prematurely.  But so far in this case, you have
> not done so, but merely confirmed my suspicions - you noticed a
> difference in behavior between Linux and Cygwin, but both behaviors were
> POSIX-compliant when factoring in the implementation-defined nature of
> the underlying implementation.
        And you confirm that there there is a design flaw in realpath.

        Realpath is not part of the OS and is not regenerated as part
of the kernel build process. If a patch is applied to specifically 
to enable or assign meaning to '//' separately that to '/', 'realpath'
will continue to run as it was configured to run on the earlier version.

        Realpath can't assume either that it was configured properly
for the current linux binary -- neither that the user knows which is
correct, nor that some behavior that was true at compile time is
still true at run time.

        Realpath also trims '.' off of "[dir]/." when these do not have
identical meaning within the linux or cygwin ecospheres.  If I process
source and destination paths through realpath before passing them
to another user app, like 'cp', realpath will alter the behavior.  

        If you look at the historic behavior of cp w/relation to 
to *nix, it behaves differently if the source comes from '<dir>' than
if it comes from '<dir>/.'.

        Similarly if you look at the historic behavior of *nix, you
can't claim '//' and '/' are identical.  Realpath fixes it's
path-modifying behaviors at compile time but doesn't disallow its 
binary being run on differently compiled copies of linux.

        FWIW, for device paths in /etc/fstab, the notation for CIFS remote
mounts is '//', as in:
mount -t cifs //Win_Desktop/C/ /Athenae -o rw,cifsacl,nocase,serverino,vers=2.1

It seems useful for '//' to made available on linux as an automounter path, 
though with nothing mounted, refering to the local system.

I could see concatenating paths '//' & '/usr' being reduced to '/usr',
but concatenating '//' & svrname reducing to '//svrname'.

Other realpath problem:
----- -------- -------

But for a real case now where processing path-args with realpath resulting
in different and unwanted behavior:

using a function for shorthand:

rp() { declare p=(); for e in "$@"; do p+=($(realpath -m "$e")); done ; set 
"${p[@]}"; printf "%s\n" "$@"; }; export rp

  # && sample files && cd to /tmp: 

mkdir /tmp/{a,b}; touch /tmp/a{1,2}; cd /tmp;

cp -a $(rp a/.) $(rp b/.)
cp -a a/. b/.

produce very different results.  I would assert that reducing
'dir/.' to simply 'dir/'

is also incorrect.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]