Subject: bug#13347: stat/fstat inappropriately used in cp, install, rm, sort, chown for Windows 7 platforms

From: Eric Blake <[email-masked]>
Date: Thu, 03 Jan 2013 11:38:47 -0700

[adding gnulib]

On 01/03/2013 10:10 AM, Burkhardt, Glenn UTAS wrote:
> MINGW32_NT-6.1 BOS0DT-1QLS1R1 1.0.17(0.48/3/2) 2011-04-24 23:39 i686 Msys
> gcc version 4.7.0 (GCC)
> Windows 7 Enterprise SP1
> coreutils-5.97
> 
> I noticed this when trying to use the "cp" command in a Clearcase locally hosted dynamic view.

Clearcase is notoriously buggy when it comes to POSIX compliance, and
I'm not surprised you are running into problems because of those bugs.
Since you paid for Clearcase (and coreutils is free), you might want to
consider reporting this issue upstream to the clearcase folks; then
again, since clearcase is closed source, I wouldn't hold out any hope
for them to fix their bugs.

> But then it gets interesting. The 'cp' command is built with a different version of 'stat' and 'fstat' than one normally gets with a MinGW build environment. The coreutils need the Msys build environment, and the 'stat/fstat' functions are pulled from libmsys-1.0.dll.a. A build in regular MinGW environment with the current compiler gets the functions from libmoldname.a. So were the coreutils built with gcc-4.7.0, and no libmsys-1.0.dll.a, the copy command would fail for files on the local hard drive, since stat.st_dev is different for stat() and fstat().

If that's the case, then perhaps the right thing to do is to modify
gnulib to replace fstat() on mingw so that it is always massaged to
provide the same st_dev as stat() (on mingw, gnulib is already doing
other things to track the original file name alongside every open fd, to
work around other bugs in POSIX compliance, so it wouldn't actually cost
that much extra).

> 
> I've attached a small test program to show the stat()/fstat() output, and a patch for system.h in coreutils that allows a working version of 'cp.exe

Unfortunately, your patch cannot be accepted upstream as-is, as it would
violate POSIX semantics on systems that actually obey POSIX.  But it
might be something that could be made conditional on whether things are
being targeted to mingw.

> http://sourceforge.net/tracker/?func=detail&aid=3590842&group_id=2435&atid=102435

> 
> *** system.h.orig	Mon Nov 26 16:54:58 2012
> --- system.h	Wed Nov 28 18:15:04 2012
> ***************
> *** 535,542 ****
>   #include "unlocked-io.h"
>   
>   #define SAME_INODE(Stat_buf_1, Stat_buf_2) \
> !   ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
> !    && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
>   
>   #define DOT_OR_DOTDOT(Basename) \
>     (Basename[0] == '.' && (Basename[1] == '\0' \
> --- 535,541 ----
>   #include "unlocked-io.h"
>   
>   #define SAME_INODE(Stat_buf_1, Stat_buf_2) \
> !   ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino)
>   
>   #define DOT_OR_DOTDOT(Basename) \
>     (Basename[0] == '.' && (Basename[1] == '\0' \
> 

Also, while this patch is unlikely to go in as-is to upstream coreutils,
you may want to pursue getting it included into mingw and msys builds as
downstream distros affected by the need for the workaround.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org