Skip to content

Commit bed9075

Browse files
committed
Fix our Windows stat() emulation to handle file sizes > 4GB.
Hack things so that our idea of "struct stat" is equivalent to Windows' struct __stat64, allowing it to have a wide enough st_size field. Instead of relying on native stat(), use GetFileInformationByHandle(). This avoids a number of issues with Microsoft's multiple and rather slipshod emulations of stat(). We still need to jump through hoops to deal with ERROR_DELETE_PENDING, though :-( Pull the relevant support code out of dirmod.c and put it into its own file, win32stat.c. Still TODO: do we need to do something different with lstat(), rather than treating it identically to stat()? Juan José Santamaría Flecha, reviewed by Emil Iggland; based on prior work by Michael Paquier, Sergey Zubkovsky, and others Discussion: https://postgr.es/m/1803D792815FC24D871C00D17AE95905CF5099@g01jpexmbkw24 Discussion: https://postgr.es/m/15858-9572469fd3b73263@postgresql.org
1 parent f13f2e4 commit bed9075

File tree

6 files changed

+339
-65
lines changed

6 files changed

+339
-65
lines changed

configure

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16137,6 +16137,12 @@ esac
1613716137
;;
1613816138
esac
1613916139

16140+
case " $LIBOBJS " in
16141+
*" win32stat.$ac_objext "* ) ;;
16142+
*) LIBOBJS="$LIBOBJS win32stat.$ac_objext"
16143+
;;
16144+
esac
16145+
1614016146

1614116147
$as_echo "#define HAVE_SYMLINK 1" >>confdefs.h
1614216148

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,7 @@ if test "$PORTNAME" = "win32"; then
18071807
AC_LIBOBJ(win32error)
18081808
AC_LIBOBJ(win32security)
18091809
AC_LIBOBJ(win32setlocale)
1810+
AC_LIBOBJ(win32stat)
18101811
AC_DEFINE([HAVE_SYMLINK], 1,
18111812
[Define to 1 if you have the `symlink' function.])
18121813
AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [

src/include/port/win32_port.h

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@
5151
#include <signal.h>
5252
#include <direct.h>
5353
#undef near
54-
#include <sys/stat.h> /* needed before sys/stat hacking below */
54+
55+
/* needed before sys/stat hacking below: */
56+
#define fstat microsoft_native_fstat
57+
#define stat microsoft_native_stat
58+
#include <sys/stat.h>
59+
#undef fstat
60+
#undef stat
5561

5662
/* Must be here to avoid conflicting with prototype in windows.h */
5763
#define mkdir(a,b) mkdir(a)
@@ -240,20 +246,34 @@ typedef int pid_t;
240246
* Supplement to <sys/stat.h>.
241247
*
242248
* We must pull in sys/stat.h before this part, else our overrides lose.
243-
*/
244-
#define lstat(path, sb) stat(path, sb)
245-
246-
/*
249+
*
247250
* stat() is not guaranteed to set the st_size field on win32, so we
248-
* redefine it to our own implementation that is.
251+
* redefine it to our own implementation. See src/port/win32stat.c.
249252
*
250-
* Some frontends don't need the size from stat, so if UNSAFE_STAT_OK
251-
* is defined we don't bother with this.
253+
* The struct stat is 32 bit in MSVC, so we redefine it as a copy of
254+
* struct __stat64. This also fixes the struct size for MINGW builds.
252255
*/
253-
#ifndef UNSAFE_STAT_OK
254-
extern int pgwin32_safestat(const char *path, struct stat *buf);
255-
#define stat(a,b) pgwin32_safestat(a,b)
256-
#endif
256+
struct stat /* This should match struct __stat64 */
257+
{
258+
_dev_t st_dev;
259+
_ino_t st_ino;
260+
unsigned short st_mode;
261+
short st_nlink;
262+
short st_uid;
263+
short st_gid;
264+
_dev_t st_rdev;
265+
__int64 st_size;
266+
__time64_t st_atime;
267+
__time64_t st_mtime;
268+
__time64_t st_ctime;
269+
};
270+
271+
extern int _pgfstat64(int fileno, struct stat *buf);
272+
extern int _pgstat64(const char *name, struct stat *buf);
273+
274+
#define fstat(fileno, sb) _pgfstat64(fileno, sb)
275+
#define stat(path, sb) _pgstat64(path, sb)
276+
#define lstat(path, sb) _pgstat64(path, sb)
257277

258278
/* These macros are not provided by older MinGW, nor by MSVC */
259279
#ifndef S_IRUSR

src/port/dirmod.c

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -353,55 +353,3 @@ pgwin32_is_junction(const char *path)
353353
return ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT);
354354
}
355355
#endif /* defined(WIN32) && !defined(__CYGWIN__) */
356-
357-
358-
#if defined(WIN32) && !defined(__CYGWIN__)
359-
360-
#undef stat
361-
362-
/*
363-
* The stat() function in win32 is not guaranteed to update the st_size
364-
* field when run. So we define our own version that uses the Win32 API
365-
* to update this field.
366-
*/
367-
int
368-
pgwin32_safestat(const char *path, struct stat *buf)
369-
{
370-
int r;
371-
WIN32_FILE_ATTRIBUTE_DATA attr;
372-
373-
r = stat(path, buf);
374-
if (r < 0)
375-
{
376-
if (GetLastError() == ERROR_DELETE_PENDING)
377-
{
378-
/*
379-
* File has been deleted, but is not gone from the filesystem yet.
380-
* This can happen when some process with FILE_SHARE_DELETE has it
381-
* open and it will be fully removed once that handle is closed.
382-
* Meanwhile, we can't open it, so indicate that the file just
383-
* doesn't exist.
384-
*/
385-
errno = ENOENT;
386-
return -1;
387-
}
388-
389-
return r;
390-
}
391-
392-
if (!GetFileAttributesEx(path, GetFileExInfoStandard, &attr))
393-
{
394-
_dosmaperr(GetLastError());
395-
return -1;
396-
}
397-
398-
/*
399-
* XXX no support for large files here, but we don't do that in general on
400-
* Win32 yet.
401-
*/
402-
buf->st_size = attr.nFileSizeLow;
403-
404-
return 0;
405-
}
406-
407-
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy