From 36146d4d54488c0fc605374735224e4fb7a6bd14 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Thu, 10 Apr 2008 16:59:10 +0000 Subject: [PATCH] Create wrapper pgwin32_safestat() and redefine stat() to it on win32, because the stat() function in the runtime cannot be trusted to always update the st_size field. Per report and research by Sergey Zubkovsky. --- src/include/port.h | 15 ++++++++++++++- src/port/dirmod.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/include/port.h b/src/include/port.h index 2374476c1f..8e16c14eac 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/port.h,v 1.116.2.1 2008/02/29 15:31:40 mha Exp $ + * $PostgreSQL: pgsql/src/include/port.h,v 1.116.2.2 2008/04/10 16:59:10 mha Exp $ * *------------------------------------------------------------------------- */ @@ -297,6 +297,19 @@ extern FILE *pgwin32_fopen(const char *, const char *); #define popen(a,b) _popen(a,b) #define pclose(a) _pclose(a) +/* + * stat() is not guaranteed to set the st_size field on win32, so we + * redefine it to our own implementation that is. + * + * We must pull in sys/stat.h here so the system header definition + * goes in first, and we redefine that, and not the other way around. + */ +extern int pgwin32_safestat(const char *path, struct stat *buf); +#if !defined(FRONTEND) && !defined(_DIRMOD_C) +#include +#define stat(a,b) pgwin32_safestat(a,b) +#endif + /* Missing rand functions */ extern long lrand48(void); extern void srand48(long seed); diff --git a/src/port/dirmod.c b/src/port/dirmod.c index ac01b83205..92e2414a4e 100644 --- a/src/port/dirmod.c +++ b/src/port/dirmod.c @@ -10,7 +10,7 @@ * Win32 (NT, Win2k, XP). replace() doesn't work on Win95/98/Me. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/dirmod.c,v 1.51 2008/01/01 19:46:00 momjian Exp $ + * $PostgreSQL: pgsql/src/port/dirmod.c,v 1.51.2.1 2008/04/10 16:59:10 mha Exp $ * *------------------------------------------------------------------------- */ @@ -447,3 +447,37 @@ report_and_fail: pgfnames_cleanup(filenames); return false; } + + +#ifdef WIN32 +/* + * The stat() function in win32 is not guaranteed to update the st_size + * field when run. So we define our own version that uses the Win32 API + * to update this field. + */ +#undef stat +int +pgwin32_safestat(const char *path, struct stat *buf) +{ + int r; + WIN32_FILE_ATTRIBUTE_DATA attr; + + r = stat(path, buf); + if (r < 0) + return r; + + if (!GetFileAttributesEx(path, GetFileExInfoStandard, &attr)) + { + _dosmaperr(GetLastError()); + return -1; + } + + /* + * XXX no support for large files here, but we don't do that in + * general on Win32 yet. + */ + buf->st_size = attr.nFileSizeLow; + + return 0; +} +#endif -- GitLab