Re: readdir is incorrectly implemented at Windows
Andrew Dunstan <andrew.dunstan@2ndquadrant.com>
From: Andrew Dunstan <andrew.dunstan@2ndquadrant.com>
To: Konstantin Knizhnik <k.knizhnik@postgrespro.ru>,
PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2019-03-01T17:36:55Z
Lists: pgsql-hackers
On 2/25/19 10:38 AM, Konstantin Knizhnik wrote:
> Hi hackers,
>
> Small issue with readir implementation for Windows.
> Right now it returns ENOENT in case of any error returned by
> FindFirstFile.
> So all places in Postgres where opendir/listdir are used will assume
> that directory is empty and
> do nothing without reporting any error.
> It is not so good if directory is actually not empty but there are not
> enough permissions for accessing the directory and FindFirstFile
> returns ERROR_ACCESS_DENIED:
>
> struct dirent *
> readdir(DIR *d)
> {
> WIN32_FIND_DATA fd;
>
> if (d->handle == INVALID_HANDLE_VALUE)
> {
> d->handle = FindFirstFile(d->dirname, &fd);
> if (d->handle == INVALID_HANDLE_VALUE)
> {
> errno = ENOENT;
> return NULL;
> }
> }
>
>
> Attached please find small patch fixing the problem.
>
Diagnosis seems correct. I wonder if this is responsible for some odd
things we've seen over time on Windows.
This reads a bit oddly:
{
- errno = ENOENT;
+ if (GetLastError() == ERROR_FILE_NOT_FOUND)
+ {
+ /* No more files, force errno=0 (unlike mingw) */
+ errno = 0;
+ return NULL;
+ }
+ _dosmaperr(GetLastError());
return NULL;
}
Why not something like:
if (GetLastError() == ERROR_FILE_NOT_FOUND)
errno = 0;
else
_dosmaperr(GetLastError());
return NULL;
cheers
andrew
--
Andrew Dunstan https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
Commits
-
Fix error handling of readdir() port implementation on first file lookup
- 81f5b32839ff 9.4.22 landed
- 977f833772de 9.5.17 landed
- d95133163b1b 9.6.13 landed
- 9aa59e64ba75 10.8 landed
- 8722c4daccf8 11.3 landed
- 754b90f657bd 12.0 landed