On Mar 29 19:34, LIU Hao wrote:
> 在 2023/3/29 16:40, Corinna Vinschen 写道:
> > > > No, this would allow splitting `\\host\\share` as `host` and `share`. In
> > > > this path the share name is `\share`, and does not match `share`.
> > 
> > I was just pointing out that "\foo" can't be a share name, because
> > backslashes can't be part of a name.
> > 
> > On second thought, maybe I don't understand what you were trying to say.
> > Can you rephrase, please?
> 
> Apologies for the confusion.
> 
> There was a mistake in the quote above, but the point in that message holds:
> `\\host\\share` is not a valid UNC path. If we allowed `dirname()` to remove
> the share name as a plain component, then, because `dirname()` treats
> consecutive separators as a single one, the result would be
> 
>    dirname("\\host\\share")   = "\\host"
>    basename("\\host\\share")  = "share"
> 
> which would be incorrect. "\\host\\share" is a UNC path with an empty share
> name (that's why it's invalid),

I don't think this is correct.  Multiple backslashes are folded into a
single backslash by the Windows API layer.  Thus \\host\\share is not
equivalent to

  \\host\<empty-share>\<dir-called-share>

but to

  \\host\share

Try this example, please:

$ cat > gfp.c <<EOF
#include <stdio.h>
#include <windows.h>

int
main (int argc, char **argv)
{
  char buf[256];

  GetFullPathNameA (argv[1], 256, buf, NULL);
  printf ("%s\n", buf);
}
EOF
$ gcc -g -o gfp gfp.c
$ ./gfp '\\host\share'
\\host\share
$ ./gfp '\\host\\share'
\\host\share
$ ./gfp '\\host\\\share'
\\host\share

And here's the same for an existing share:

$ cat > gfp2.c <<EOF
#include <stdio.h>
#include <windows.h>

int
main (int argc, char **argv)
{
  char buf[256];
  HANDLE h;

  h = CreateFileA (argv[1], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                   NULL, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL);
  if (h != INVALID_HANDLE_VALUE)
    {
      GetFinalPathNameByHandleA (h, buf, 256,
                                 FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
      printf ("%s\n", buf);
      CloseHandle (h);
    }
}
EOF
$ gcc -g -o gfp2 gfp2.c
$ ./gfp '\\calimero\corinna'
\\?\UNC\calimero\corinna
$ ./gfp '\\calimero\\corinna'
\\?\UNC\calimero\corinna
$ ./gfp '\\calimero\\\corinna'
\\?\UNC\calimero\corinna

> and we probably shouldn't make it
> indistinguishable from `\\host\share`. So it should be
> 
>    dirname("\\host\\share")   = "\\host\"
>    basename("\\host\\share")  = "share"
> 
> 
> > Actually, the dirname function is not supposed to fold slashes (or
> > backslashes) at all, except at the start of the path.  It's also not
> > supposed to throw any errors.  It just cuts the path so that the last
> > path component is dropped.
> 
> My point is that `\\host\share` is a volume name (the 'prefix', like `C:`)
> and is not made up of two components. `dirname()` is supposed to remove the
> last component, but there is no such component to remove.

Yes, that's a valid point.  My point of view differs, but ultimately that
doesn't matter much.


Corinna


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to