diff options
Diffstat (limited to 'contrib/libs/postgresql/src/port/win32stat.c')
-rw-r--r-- | contrib/libs/postgresql/src/port/win32stat.c | 327 |
1 files changed, 0 insertions, 327 deletions
diff --git a/contrib/libs/postgresql/src/port/win32stat.c b/contrib/libs/postgresql/src/port/win32stat.c deleted file mode 100644 index 426e01f0ef..0000000000 --- a/contrib/libs/postgresql/src/port/win32stat.c +++ /dev/null @@ -1,327 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32stat.c - * Replacements for <sys/stat.h> functions using GetFileInformationByHandle - * - * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/win32stat.c - * - *------------------------------------------------------------------------- - */ - -#ifdef WIN32 - -#include "c.h" -#include <windows.h> - -/* - * In order to support MinGW and MSVC2013 we use NtQueryInformationFile as an - * alternative for GetFileInformationByHandleEx. It is loaded from the ntdll - * library. - */ -#if _WIN32_WINNT < 0x0600 -#include <winternl.h> - -#if !defined(__MINGW32__) && !defined(__MINGW64__) -/* MinGW includes this in <winternl.h>, but it is missing in MSVC */ -typedef struct _FILE_STANDARD_INFORMATION -{ - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION; -#define FileStandardInformation 5 -#endif /* !defined(__MINGW32__) && - * !defined(__MINGW64__) */ - -typedef NTSTATUS (NTAPI * PFN_NTQUERYINFORMATIONFILE) - (IN HANDLE FileHandle, - OUT PIO_STATUS_BLOCK IoStatusBlock, - OUT PVOID FileInformation, - IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInformationClass); - -static PFN_NTQUERYINFORMATIONFILE _NtQueryInformationFile = NULL; - -static HMODULE ntdll = NULL; - -/* - * Load DLL file just once regardless of how many functions we load/call in it. - */ -static void -LoadNtdll(void) -{ - if (ntdll != NULL) - return; - ntdll = LoadLibraryEx("ntdll.dll", NULL, 0); -} - -#endif /* _WIN32_WINNT < 0x0600 */ - - -/* - * Convert a FILETIME struct into a 64 bit time_t. - */ -static __time64_t -filetime_to_time(const FILETIME *ft) -{ - ULARGE_INTEGER unified_ft = {0}; - static const uint64 EpochShift = UINT64CONST(116444736000000000); - - unified_ft.LowPart = ft->dwLowDateTime; - unified_ft.HighPart = ft->dwHighDateTime; - - if (unified_ft.QuadPart < EpochShift) - return -1; - - unified_ft.QuadPart -= EpochShift; - unified_ft.QuadPart /= 10 * 1000 * 1000; - - return unified_ft.QuadPart; -} - -/* - * Convert WIN32 file attributes to a Unix-style mode. - * - * Only owner permissions are set. - */ -static unsigned short -fileattr_to_unixmode(int attr) -{ - unsigned short uxmode = 0; - - uxmode |= (unsigned short) ((attr & FILE_ATTRIBUTE_DIRECTORY) ? - (_S_IFDIR) : (_S_IFREG)); - - uxmode |= (unsigned short) ((attr & FILE_ATTRIBUTE_READONLY) ? - (_S_IREAD) : (_S_IREAD | _S_IWRITE)); - - /* there is no need to simulate _S_IEXEC using CMD's PATHEXT extensions */ - uxmode |= _S_IEXEC; - - return uxmode; -} - -/* - * Convert WIN32 file information (from a HANDLE) to a struct stat. - */ -static int -fileinfo_to_stat(HANDLE hFile, struct stat *buf) -{ - BY_HANDLE_FILE_INFORMATION fiData; - - memset(buf, 0, sizeof(*buf)); - - /* - * GetFileInformationByHandle minimum supported version: Windows XP and - * Windows Server 2003, so it exists everywhere we care about. - */ - if (!GetFileInformationByHandle(hFile, &fiData)) - { - _dosmaperr(GetLastError()); - return -1; - } - - if (fiData.ftLastWriteTime.dwLowDateTime || - fiData.ftLastWriteTime.dwHighDateTime) - buf->st_mtime = filetime_to_time(&fiData.ftLastWriteTime); - - if (fiData.ftLastAccessTime.dwLowDateTime || - fiData.ftLastAccessTime.dwHighDateTime) - buf->st_atime = filetime_to_time(&fiData.ftLastAccessTime); - else - buf->st_atime = buf->st_mtime; - - if (fiData.ftCreationTime.dwLowDateTime || - fiData.ftCreationTime.dwHighDateTime) - buf->st_ctime = filetime_to_time(&fiData.ftCreationTime); - else - buf->st_ctime = buf->st_mtime; - - buf->st_mode = fileattr_to_unixmode(fiData.dwFileAttributes); - buf->st_nlink = fiData.nNumberOfLinks; - - buf->st_size = ((((uint64) fiData.nFileSizeHigh) << 32) | - fiData.nFileSizeLow); - - return 0; -} - -/* - * Windows implementation of stat(). - * - * This currently also implements lstat(), though perhaps that should change. - */ -int -_pgstat64(const char *name, struct stat *buf) -{ - /* - * We must use a handle so lstat() returns the information of the target - * file. To have a reliable test for ERROR_DELETE_PENDING, we use - * NtQueryInformationFile from Windows 2000 or - * GetFileInformationByHandleEx from Server 2008 / Vista. - */ - SECURITY_ATTRIBUTES sa; - HANDLE hFile; - int ret; -#if _WIN32_WINNT < 0x0600 - IO_STATUS_BLOCK ioStatus; - FILE_STANDARD_INFORMATION standardInfo; -#else - FILE_STANDARD_INFO standardInfo; -#endif - - if (name == NULL || buf == NULL) - { - errno = EINVAL; - return -1; - } - - /* fast not-exists check */ - if (GetFileAttributes(name) == INVALID_FILE_ATTRIBUTES) - { - _dosmaperr(GetLastError()); - return -1; - } - - /* get a file handle as lightweight as we can */ - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = NULL; - hFile = CreateFile(name, - GENERIC_READ, - (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), - &sa, - OPEN_EXISTING, - (FILE_FLAG_NO_BUFFERING | FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OVERLAPPED), - NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } - - memset(&standardInfo, 0, sizeof(standardInfo)); - -#if _WIN32_WINNT < 0x0600 - if (_NtQueryInformationFile == NULL) - { - /* First time through: load ntdll.dll and find NtQueryInformationFile */ - LoadNtdll(); - if (ntdll == NULL) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } - - _NtQueryInformationFile = (PFN_NTQUERYINFORMATIONFILE) (pg_funcptr_t) - GetProcAddress(ntdll, "NtQueryInformationFile"); - if (_NtQueryInformationFile == NULL) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } - } - - if (!NT_SUCCESS(_NtQueryInformationFile(hFile, &ioStatus, &standardInfo, - sizeof(standardInfo), - FileStandardInformation))) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } -#else - if (!GetFileInformationByHandleEx(hFile, FileStandardInfo, &standardInfo, - sizeof(standardInfo))) - { - DWORD err = GetLastError(); - - CloseHandle(hFile); - _dosmaperr(err); - return -1; - } -#endif /* _WIN32_WINNT < 0x0600 */ - - if (standardInfo.DeletePending) - { - /* - * File has been deleted, but is not gone from the filesystem yet. - * This can happen when some process with FILE_SHARE_DELETE has it - * open, and it will be fully removed once that handle is closed. - * Meanwhile, we can't open it, so indicate that the file just doesn't - * exist. - */ - CloseHandle(hFile); - errno = ENOENT; - return -1; - } - - /* At last we can invoke fileinfo_to_stat */ - ret = fileinfo_to_stat(hFile, buf); - - CloseHandle(hFile); - return ret; -} - -/* - * Windows implementation of fstat(). - */ -int -_pgfstat64(int fileno, struct stat *buf) -{ - HANDLE hFile = (HANDLE) _get_osfhandle(fileno); - BY_HANDLE_FILE_INFORMATION fiData; - - if (hFile == INVALID_HANDLE_VALUE || buf == NULL) - { - errno = EINVAL; - return -1; - } - - /* - * Check if the fileno is a data stream. If so, unless it has been - * redirected to a file, getting information through its HANDLE will fail, - * so emulate its stat information in the most appropriate way and return - * it instead. - */ - if ((fileno == _fileno(stdin) || - fileno == _fileno(stdout) || - fileno == _fileno(stderr)) && - !GetFileInformationByHandle(hFile, &fiData)) - { - memset(buf, 0, sizeof(*buf)); - buf->st_mode = _S_IFCHR; - buf->st_dev = fileno; - buf->st_rdev = fileno; - buf->st_nlink = 1; - return 0; - } - - /* - * Since we already have a file handle there is no need to check for - * ERROR_DELETE_PENDING. - */ - - return fileinfo_to_stat(hFile, buf); -} - -#endif /* WIN32 */ |