bug-gnulib
[Top][All Lists]
Advanced

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

Problematic redefinition of 'stat' and 'fstat'


From: Eli Zaretskii
Subject: Problematic redefinition of 'stat' and 'fstat'
Date: Tue, 24 Dec 2019 19:25:42 +0200

The current sys_stat.in.h in Gnulib does this on MinGW:

  /* Large File Support on native Windows.  */
  #if @WINDOWS_64_BIT_ST_SIZE@
  # define stat _stati64
  #endif
  [...]
  #elif @WINDOWS_64_BIT_ST_SIZE@
  /* Above, we define stat to _stati64.  */
  # define fstat _fstati64
  [...]
  #   elif @WINDOWS_64_BIT_ST_SIZE@
       /* Above, we define stat to _stati64.  */
  #    if defined __MINGW32__ && defined _stati64
  #     ifndef _USE_32BIT_TIME_T
         /* The system headers define _stati64 to _stat64.  */
  #      undef _stat64
  #      define _stat64(name, st) rpl_stat (name, st)
  #     endif

This has the effect of redefining every 'struct stat' in a program to
refer to 'struct _stati64'.  The latter uses 64-bit st_size field (and
with MinGW64, also 64-bit time fields).  This happens in any MinGW
build whose size_t field is 32-bit, because largefile.m4 does:

      AC_CACHE_CHECK([for 64-bit st_size], [gl_cv_member_st_size_64],
        [AC_COMPILE_IFELSE(
           [AC_LANG_PROGRAM(
              [[#include <sys/types.h>
                struct stat buf;
                int verify_st_size_size[sizeof (buf.st_size) >= 8 ? 1 : -1];
              ]],
              [[]])],
           [gl_cv_member_st_size_64=yes], [gl_cv_member_st_size_64=no])
        ])
      if test $gl_cv_member_st_size_64 = no; then
        WINDOWS_64_BIT_ST_SIZE=1
      else
        WINDOWS_64_BIT_ST_SIZE=0
      fi

This, @WINDOWS_64_BIT_ST_SIZE@ above is replaced with 1 when the
default 'struct stat' has a 32-bit st_size.

The problem with this redefinition is that if the default definition
of 'struct stat' uses 32-bit st_size field, then linking a program
against a library which was compiled with that default (i.e. without
using the Gnulib overrides) will produce a buggy program, if it passes
'struct stat' to the library.  Which is exactly what happened to me
while building the latest versions of GDB, which uses Gnulib, but
links against the BFD library, which doesn't.

Why is this redefinition forced on programs that use Gnulib on
Windows?  I understand the desire to use 64-bit st_size when
available, but it sounds like this could cause subtle and
hard-to-debug problems, which are much worse than the 32-bit st_size
limitation.  With MinGW64, this trick is just lucky enough to work,
because the default definition of 'struct stat' is compatible with the
above, but mingw.org's MinGW is less lucky.  However, MinGW64 doesn't
really need this trick anyway, because it already does use a 64-bit
st_size by default.

IOW, it sounds like this redefinition is not needed where it works,
and cannot be used safely where it doesn't work.  Which, to me, means
it's best to remove the redefinition, and at most maybe keep it only
as an optional feature.

Comments?



reply via email to

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