On 2025-01-25 Pali Rohár wrote:
> On Saturday 25 January 2025 12:39:19 Lasse Collin wrote:
> > The CRT functions prodide timestamps in time_t while Win32 API
> > provides FILETIME. Perhaps the conversion wastes time. The dirent
> > functions don't need file timestamps.  
> 
> Maybe that time conversion is slow. Anyway, it is needed to also check
> how different CRT versions behave. I guess you have done these checks
> against msvcrt.dll. Maybe the last UCRT version is faster?

I had tested with UCRT. With MSVCRT (32-bit) the difference is smaller.

Both test programs are very slow if built as ANSI against MSVCRT. It's
due to the printing of the filenames to stdout; it's not the file
finding APIs. With UCRT, printing stays fast with ANSI.

If the _tprintf calls are commented out, UCRT+_wfindfirst method is
50 % slower than UCRT+FindFirstFileW or MSVCRT+either. UCRT result seems
weird because MSVCRT+_wfindfirst doesn't have that problem.

> Also what could be different is that _findfirst may be affected by
> setlocale function as IIRC UCRT supports changing process locale but
> only for UCRT functions.
> 
> Another important thing is that FindFirstFile is affected by the
> AreFileApisANSI() function. Some info is in SetFileApisToOEM() spec:
> https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileapistooem

I wonder how much this matters. If Win9x compatibility isn't needed,
the new dirent code would only use wide character functions
(_wfindfirst or FindFirstFileW). If I understand correctly, the
functions you mentioned won't affect the wide character APIs.

> For me it looks like that _findfirst and FindFirstFile do not have to
> behave in the same way across different crt versions.

The ANSI versions certainly differ. _findnext crashes the application if
an overlong filename is found (>MAX_PATH). FindNextFileA only fails with
ERROR_MODE_DATA. These issues don't exist in the wide character APIs.

The CRT functions don't provide very useful errno values. For example,
the current dirent.c needs to check for GetLastError() ==
ERROR_NO_MORE_FILES because _findnext() uses ENOENT for both the end of
the directory and some errors. The value from GetLastError() comes from
FindNextFileA/W.

If there is a permission problem, _findfirst uses EINVAL while EACCES
would be correct. One would need to check for ERROR_ACCESS_DENIED to
diagnose it correctly.

So if the CRT APIs are used, one needs to call GetLastError() anyway to
know why the underlying FindNextFileA/W failed. I have started to feel
that the CRT APIs just get in the way instead of being helpful. I
suppose they helped to transition from DOS in 1990s.

> > Is Windows 95/98/ME support needed in <dirent.h> functions still?  
> 
> I guess that no. Basically developers do not care about anything
> pre-WinXP.
> 
> But on the other hand I fixed few bugs related to Win9x/NT4.0 because
> people recently reported them that they are still using it. And those
> bugs were mostly caused by incorrect definitions and fallbacks in
> msvcrt* def files, which I was cleaning up and fixing a lot.
> 
> So it means that there are already "users" who actively use mingw-w64
> with older systems.

Those are core features. The dirent functions are an extension. I
don't know if that difference matters. :-|

> > Other things in libmingwex seem friendly to Win9x still. With a
> > quick search with grep, I only spotted one extremely minor thing:
> > getopt.c calls GetEnvironmentVariableW to read POSIXLY_CORRECT.
> > That function exists on Win98 as a stub so the program still runs.
> > It just won't obey the POSIXLY_CORRECT environment variable on
> > Win9x, which is not a problem at all.  
> 
> IMHO this is a bug. We should use getenv() in POSIX/CRT functions and
> not the GetEnvironmentVariable[AW]() because the WinAPI function does
> not address things like direct modification of 3rd main argument env,
> or similar thing which is used in POSIX applications. There is also
> _enviroment symbol (or function which returns pointer to this symbol)
> which can be and also is used by windows (msvcrt) applications.

I understand what you mean. Luckily POSIXLY_CORRECT is such an
environment variable that there's no problem *in practice*. It's
highly unlikely that the value would be changed after main() has been
called.

getopt.c used to call getenv(). It was changed in 2020 in the commit
8917aca09469 ("crt: use GetEnvironmentVariableW in getopt"). I suppose
there's no perfect solution but the current way shouldn't cause any
problems in practice. In some other place than getopt.c it could be
different.

-- 
Lasse Collin


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

Reply via email to