On 2025-02-27 Pali Rohár wrote:
> I did not wanted to open also this discussion about stat, but as you
> have opened it, I write some important details, which needs to be
> taken into account, otherwise another breakage can happen.

Thank you for writing it! It is useful. I apologize if opening this
thread was bad timing.

> But let this mess as is, all those are underscored functions which MS
> somehow defined and it is well known API/ABI.

Here was my main confusion a few emails ago and why I opened this
thread: With UCRT, even _stat64i32 has mingw-w64-specific behavior.
This felt unexpected because it's a Microsoft function, not POSIX. When
_stat is defined to _stat64i32, _stat is affected too. It was extra
confusing because of the inline function that appears only when
optimizations are enabled.

The trailing slash removal was added in the commit 32ec57d19d96
("_mingw_no_trailing_slash() for _stat64i32() and _wstat64i32()") in
2017. The commit message only has that one line, giving no hints why the
change was made. <sys/stat.h> wasn't modified, thus the inline function
_stat64i32 got out of sync with the code in _stat64i32.c. There is no
inline function _wstat64i32. Thus, most of the time this commit made no
difference to the code that calls _stat64i32.

From the mailing list, I only found [1] which explains why 02ad8d9cc38a
("fix for previous commit") was made. I didn't find anything else, but
I didn't search much either.

If these two commits were reverted, I suppose UCRT's _stat64i32 should
work correctly with optimizations disabled (I didn't test). With
correctly I mean having whatever behavior the MS CRT function has. As a
side effect, stat (without underscore) with UCRT would behave better
when the #defines are such that stat calls _stat64i32.

[1] 
https://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/thread/alpine.DEB.2.20.1708031327560.2300%40cone.martin.st/

> Now the interesting part is: How should non-underscored POSIX stat()
> and fstat() behaves?
> 
> I think that header file for POSIX stat() and fstat() should follow
> application definition of _USE_32BIT_TIME_T or the largely used the
> "-D_TIME_BITS=64" or "-D_FILE_OFFSET_BITS=64" compile flags.

Right, I think four versions are needed because POSIX struct stat
contains both off_t and time_t (in current POSIX, time_t comes via
struct timespec, and st_mtime macro expands to st_mtim.tv_sec).

> As the msvcrt.dll's _stat() function has somehow strange behavior of
> trailing slash, for POSIX stat() purposes, it is needed to define
> mingw-w64 wrapper.

Correct.

> But as there are 4 variants of "-D_TIME_BITS=64" +
> "-D_FILE_OFFSET_BITS=64" combinations, it is needed to define 4
> variants of POSIX stat function. Maybe call them similarly: stat32,
> stat64, stat64i32 and stat32i64.

It's not ideal to add stat64i32 and stat32i64 into the public
namespace but maybe it's OK in practice. stat64 comes from LFS so in
that sense it's a standard name. mingw-w64-headers/crt/_mingw_stat64.h
has these:

    #define stat64   _stat64  /* for POSIX */
    #define fstat64  _fstat64 /* for POSIX */

Maybe it could be safest to put the four functions into private
namespace, naming them like __mingw64_stat64i32. Then the macro stat
could have four different values and the macro stat64 two different
values. On the other hand, changing stat64 to depend on _TIME_BITS is
AP/ABI change. *sigh* I don't know what makes sense now.

> I think that providing any inline function for any stat* variant would
> just cause a bigger mess. So I would propose to define 4 mingw-w64
> wrappers (for each variant) and in header file just add a proper
> #define stat based on the macros configuration.

I agree.

> Similarly it would be needed to define fstat macro, but should just
> expand to correct _fstat as there is no need for wrapper.

Sounds good too.

However... if the symbols stat and fstat (and maybe stat64 and fstat64)
don't exist, will Autoconf find those symbols? AC_CHECK_FUNC is overly
clever (that is, sort of broken) because it doesn't take a parameter to
specify the headers to include. Simplified, it tries if this can be
compiled and linked:

    char somefunc(void);

    int main(void)
    {
        return somefunc();
        return 0;
    }

I don't know if many packages check if stat and fstat are available
this way. Maybe many enough assume that they just are available. I hope
this is overworrying and doesn't matter at all. :-)

I suppose improving the POSIX variants isn't a high priority, but maybe
the _stat64i32 oddity could be worth fixing sooner than the other
<sys/stat.h> things.

-- 
Lasse Collin


_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to