On Saturday 17 January 2026 12:59:27 Pali Rohár wrote:
> On Friday 16 January 2026 15:59:44 LIU Hao wrote:
> > 在 2025-12-29 01:35, Pali Rohár 写道:
> > > ---
> > >   mingw-w64-crt/Makefile.am              |  1 +
> > >   mingw-w64-crt/lib-common/msvcrt.def.in |  2 +-
> > >   mingw-w64-crt/misc/_mktime32.c         | 29 ++++++++++++++++++++++++++
> > >   3 files changed, 31 insertions(+), 1 deletion(-)
> > >   create mode 100644 mingw-w64-crt/misc/_mktime32.c
> > > 
> > > diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
> > > index d9578c909253..1e6d344bd40a 100644
> > > --- a/mingw-w64-crt/Makefile.am
> > > +++ b/mingw-w64-crt/Makefile.am
> > > @@ -673,6 +673,7 @@ src_msvcrt64=\
> > >     misc/_initterm_e.c \
> > >     misc/_localtime32.c \
> > >     misc/_mkgmtime32.c \
> > > +  misc/_mktime32.c \
> > >     misc/_set_doserrno.c \
> > >     misc/_set_fmode.c \
> > >     misc/output_format.c \
> > > diff --git a/mingw-w64-crt/lib-common/msvcrt.def.in 
> > > b/mingw-w64-crt/lib-common/msvcrt.def.in
> > > index 1e7eda60a510..9caf981ac30c 100644
> > > --- a/mingw-w64-crt/lib-common/msvcrt.def.in
> > > +++ b/mingw-w64-crt/lib-common/msvcrt.def.in
> > > @@ -1597,7 +1597,7 @@ _mbstrnlen
> > >   _memicmp_l
> > >   F_ARM_ANY(_mkgmtime32) ; i386 and x64 _mkgmtime32 replaced by emu
> > >   F_ARM_ANY(_mktemp_s) ; i386 and x64 _mktemp_s replaced by emu
> > > -_mktime32 F_I386(== mktime) ; i386 _mktime32 replaced by alias
> > > +F_NON_X64(_mktime32 F_I386(== mktime)) ; i386 _mktime32 replaced by 
> > > alias and x64 _mktime32 replaced by emu
> > >   F_NON_I386(_msize_dbg)
> > >   F_I386(_msize_debug)
> > >   _printf_l
> > > diff --git a/mingw-w64-crt/misc/_mktime32.c 
> > > b/mingw-w64-crt/misc/_mktime32.c
> > > new file mode 100644
> > > index 000000000000..7b9ef1b73f8d
> > > --- /dev/null
> > > +++ b/mingw-w64-crt/misc/_mktime32.c
> > > @@ -0,0 +1,29 @@
> > > +/**
> > > + * This file has no copyright assigned and is placed in the Public 
> > > Domain.
> > > + * This file is part of the mingw-w64 runtime package.
> > > + * No warranty is given; refer to the file DISCLAIMER.PD within this 
> > > package.
> > > + */
> > > +
> > > +#include <time.h>
> > > +#include <stdint.h>
> > > +#include <errno.h>
> > > +
> > > +static __time32_t __cdecl emu__mktime32(struct tm *tmptr)
> > > +{
> > > +    struct tm tmbuf = *tmptr;
> > > +    __time64_t time64 = _mktime64(&tmbuf);
> > > +    if (time64 == -1)
> > > +        return -1;
> > > +    if (time64 < 0 || time64 > INT32_MAX) {
> > > +        errno = EINVAL;
> > > +        return -1;
> > > +    }
> > 
> > POSIX says errno in this case should be `EOVERFLOW`.
> > 
> > Besides, I don't see why `time64 < 0` should make any sense -- if
> > `_mktime64()` ever returns a negative value such as -86400 then the value
> > should be forwarded, and if `_mktime64()` fails in that case it would return
> > -1. So this could be just
> > 
> >    if (time64 < INT32_MIN || time64 > INT32_MAX) {
> >        errno = EOVERFLOW;
> >        return -1;
> >    }
> 
> This is not POSIX mktime function, but rather MS _mktime[32] function.
> This implementation tries to match the MS _mktime32 function which is in
> msvcrt.dll since Windows Vista+.
> 
> But I will recheck how it behaves on more Windows versions in msvcrt.dll
> library.
> 
> In any case, if we want correct POSIX functionality, we need to prove
> wrapper around the msvcrt.dll implementation.

I checked this simple test on Windows 11:

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <errno.h>

int main() {
    struct tm tm = {
        .tm_sec = 0,
        .tm_min = 0,
        .tm_hour = 0,
        .tm_mday = 1,
        .tm_mon = 1,
        .tm_year = 1969-1900,
        .tm_wday = 0,
        .tm_yday = 0,
        .tm_isdst = 0,
    };
    __time32_t t = _mktime32(&tm);
    printf("year=%d\n", tm.tm_year+1900);
    printf("t=%ld errno=%d (%s)\n", t, errno, strerror(errno));
    return 0;
}

The result is that it returned errno 22 Invalid argument. Same for year 2050.
For year 1970 it succeeded. I tried to compile it for both 32-bit and
64-bit msvcrt.dll, result was same.

So I think that our mingw-w64 emu version should follow this behavior.


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

Reply via email to