diff options
Diffstat (limited to 'contrib/libs/postgresql/src/port/dirmod.c')
-rw-r--r-- | contrib/libs/postgresql/src/port/dirmod.c | 355 |
1 files changed, 0 insertions, 355 deletions
diff --git a/contrib/libs/postgresql/src/port/dirmod.c b/contrib/libs/postgresql/src/port/dirmod.c deleted file mode 100644 index 46c9c235c8..0000000000 --- a/contrib/libs/postgresql/src/port/dirmod.c +++ /dev/null @@ -1,355 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dirmod.c - * directory handling functions - * - * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * This includes replacement versions of functions that work on - * Win32 (NT4 and newer). - * - * IDENTIFICATION - * src/port/dirmod.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -/* Don't modify declarations in system headers */ -#if defined(WIN32) || defined(__CYGWIN__) -#undef rename -#undef unlink -#endif - -#include <unistd.h> -#include <sys/stat.h> - -#if defined(WIN32) || defined(__CYGWIN__) -#ifndef __CYGWIN__ -#include <winioctl.h> -#else -#include <windows.h> -#error #include <w32api/winioctl.h> -#endif -#endif - -#if defined(WIN32) || defined(__CYGWIN__) - -/* - * pgrename - */ -int -pgrename(const char *from, const char *to) -{ - int loops = 0; - - /* - * We need to loop because even though PostgreSQL uses flags that allow - * rename while the file is open, other applications might have the file - * open without those flags. However, we won't wait indefinitely for - * someone else to close the file, as the caller might be holding locks - * and blocking other backends. - */ -#if defined(WIN32) && !defined(__CYGWIN__) - while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)) -#else - while (rename(from, to) < 0) -#endif - { -#if defined(WIN32) && !defined(__CYGWIN__) - DWORD err = GetLastError(); - - _dosmaperr(err); - - /* - * Modern NT-based Windows versions return ERROR_SHARING_VIOLATION if - * another process has the file open without FILE_SHARE_DELETE. - * ERROR_LOCK_VIOLATION has also been seen with some anti-virus - * software. This used to check for just ERROR_ACCESS_DENIED, so - * presumably you can get that too with some OS versions. We don't - * expect real permission errors where we currently use rename(). - */ - if (err != ERROR_ACCESS_DENIED && - err != ERROR_SHARING_VIOLATION && - err != ERROR_LOCK_VIOLATION) - return -1; -#else - if (errno != EACCES) - return -1; -#endif - - if (++loops > 100) /* time out after 10 sec */ - return -1; - pg_usleep(100000); /* us */ - } - return 0; -} - - -/* - * pgunlink - */ -int -pgunlink(const char *path) -{ - int loops = 0; - - /* - * We need to loop because even though PostgreSQL uses flags that allow - * unlink while the file is open, other applications might have the file - * open without those flags. However, we won't wait indefinitely for - * someone else to close the file, as the caller might be holding locks - * and blocking other backends. - */ - while (unlink(path)) - { - if (errno != EACCES) - return -1; - if (++loops > 100) /* time out after 10 sec */ - return -1; - pg_usleep(100000); /* us */ - } - return 0; -} - -/* We undefined these above; now redefine for possible use below */ -#define rename(from, to) pgrename(from, to) -#define unlink(path) pgunlink(path) -#endif /* defined(WIN32) || defined(__CYGWIN__) */ - - -#if defined(WIN32) && !defined(__CYGWIN__) /* Cygwin has its own symlinks */ - -/* - * pgsymlink support: - * - * This struct is a replacement for REPARSE_DATA_BUFFER which is defined in VC6 winnt.h - * but omitted in later SDK functions. - * We only need the SymbolicLinkReparseBuffer part of the original struct's union. - */ -typedef struct -{ - DWORD ReparseTag; - WORD ReparseDataLength; - WORD Reserved; - /* SymbolicLinkReparseBuffer */ - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - WCHAR PathBuffer[FLEXIBLE_ARRAY_MEMBER]; -} REPARSE_JUNCTION_DATA_BUFFER; - -#define REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE \ - FIELD_OFFSET(REPARSE_JUNCTION_DATA_BUFFER, SubstituteNameOffset) - - -/* - * pgsymlink - uses Win32 junction points - * - * For reference: http://www.codeproject.com/KB/winsdk/junctionpoints.aspx - */ -int -pgsymlink(const char *oldpath, const char *newpath) -{ - HANDLE dirhandle; - DWORD len; - char buffer[MAX_PATH * sizeof(WCHAR) + offsetof(REPARSE_JUNCTION_DATA_BUFFER, PathBuffer)]; - char nativeTarget[MAX_PATH]; - char *p = nativeTarget; - REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer; - - CreateDirectory(newpath, 0); - dirhandle = CreateFile(newpath, GENERIC_READ | GENERIC_WRITE, - 0, 0, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0); - - if (dirhandle == INVALID_HANDLE_VALUE) - return -1; - - /* make sure we have an unparsed native win32 path */ - if (memcmp("\\??\\", oldpath, 4) != 0) - snprintf(nativeTarget, sizeof(nativeTarget), "\\??\\%s", oldpath); - else - strlcpy(nativeTarget, oldpath, sizeof(nativeTarget)); - - while ((p = strchr(p, '/')) != NULL) - *p++ = '\\'; - - len = strlen(nativeTarget) * sizeof(WCHAR); - reparseBuf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - reparseBuf->ReparseDataLength = len + 12; - reparseBuf->Reserved = 0; - reparseBuf->SubstituteNameOffset = 0; - reparseBuf->SubstituteNameLength = len; - reparseBuf->PrintNameOffset = len + sizeof(WCHAR); - reparseBuf->PrintNameLength = 0; - MultiByteToWideChar(CP_ACP, 0, nativeTarget, -1, - reparseBuf->PathBuffer, MAX_PATH); - - /* - * FSCTL_SET_REPARSE_POINT is coded differently depending on SDK version; - * we use our own definition - */ - if (!DeviceIoControl(dirhandle, - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS), - reparseBuf, - reparseBuf->ReparseDataLength + REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE, - 0, 0, &len, 0)) - { - LPSTR msg; - - errno = 0; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - (LPSTR) &msg, 0, NULL); -#ifndef FRONTEND - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not set junction for \"%s\": %s", - nativeTarget, msg))); -#else - fprintf(stderr, _("could not set junction for \"%s\": %s\n"), - nativeTarget, msg); -#endif - LocalFree(msg); - - CloseHandle(dirhandle); - RemoveDirectory(newpath); - return -1; - } - - CloseHandle(dirhandle); - - return 0; -} - -/* - * pgreadlink - uses Win32 junction points - */ -int -pgreadlink(const char *path, char *buf, size_t size) -{ - DWORD attr; - HANDLE h; - char buffer[MAX_PATH * sizeof(WCHAR) + offsetof(REPARSE_JUNCTION_DATA_BUFFER, PathBuffer)]; - REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer; - DWORD len; - int r; - - attr = GetFileAttributes(path); - if (attr == INVALID_FILE_ATTRIBUTES) - { - _dosmaperr(GetLastError()); - return -1; - } - if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) - { - errno = EINVAL; - return -1; - } - - h = CreateFile(path, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - 0); - if (h == INVALID_HANDLE_VALUE) - { - _dosmaperr(GetLastError()); - return -1; - } - - if (!DeviceIoControl(h, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - (LPVOID) reparseBuf, - sizeof(buffer), - &len, - NULL)) - { - LPSTR msg; - - errno = 0; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - (LPSTR) &msg, 0, NULL); -#ifndef FRONTEND - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not get junction for \"%s\": %s", - path, msg))); -#else - fprintf(stderr, _("could not get junction for \"%s\": %s\n"), - path, msg); -#endif - LocalFree(msg); - CloseHandle(h); - errno = EINVAL; - return -1; - } - CloseHandle(h); - - /* Got it, let's get some results from this */ - if (reparseBuf->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT) - { - errno = EINVAL; - return -1; - } - - r = WideCharToMultiByte(CP_ACP, 0, - reparseBuf->PathBuffer, -1, - buf, - size, - NULL, NULL); - - if (r <= 0) - { - errno = EINVAL; - return -1; - } - - /* - * If the path starts with "\??\", which it will do in most (all?) cases, - * strip those out. - */ - if (r > 4 && strncmp(buf, "\\??\\", 4) == 0) - { - memmove(buf, buf + 4, strlen(buf + 4) + 1); - r -= 4; - } - return r; -} - -/* - * Assumes the file exists, so will return false if it doesn't - * (since a nonexistent file is not a junction) - */ -bool -pgwin32_is_junction(const char *path) -{ - DWORD attr = GetFileAttributes(path); - - if (attr == INVALID_FILE_ATTRIBUTES) - { - _dosmaperr(GetLastError()); - return false; - } - return ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT); -} -#endif /* defined(WIN32) && !defined(__CYGWIN__) */ |