GNU bug report logs -
#36416
realpath doesn't preserve '//' in -m mode
Previous Next
Reported by: L A Walsh <coreutils <at> tlinx.org>
Date: Fri, 28 Jun 2019 12:54:02 UTC
Severity: normal
Tags: notabug
Done: Eric Blake <eblake <at> redhat.com>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
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/.)
#versus
cp -a a/. b/.
produce very different results. I would assert that reducing
'dir/.' to simply 'dir/'
is also incorrect.
This bug report was last modified 6 years and 22 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.