aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-08-29 19:36:18 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-08-30 01:14:59 +0300
commita05826a29a408f0c7122d7b5b63ae686bdb53c7e (patch)
tree8de87c7bec203c098c38f419f8731570d50447db /contrib/libs
parent7563368187b7c65f64abbf2418713fd3ebd51949 (diff)
downloadydb-a05826a29a408f0c7122d7b5b63ae686bdb53c7e.tar.gz
Update contrib/libs/postgresql to 15.1
Diffstat (limited to 'contrib/libs')
-rw-r--r--contrib/libs/postgresql/src/backend/port/posix_sema.c2
-rw-r--r--contrib/libs/postgresql/src/backend/port/sysv_shmem.c51
-rw-r--r--contrib/libs/postgresql/src/backend/port/win32/crashdump.c4
-rw-r--r--contrib/libs/postgresql/src/backend/port/win32/signal.c14
-rw-r--r--contrib/libs/postgresql/src/backend/port/win32/socket.c13
-rw-r--r--contrib/libs/postgresql/src/backend/port/win32/timer.c2
-rw-r--r--contrib/libs/postgresql/src/backend/port/win32_sema.c2
-rw-r--r--contrib/libs/postgresql/src/backend/port/win32_shmem.c16
-rw-r--r--contrib/libs/postgresql/src/include/port/win32_msvc/unistd.h8
-rw-r--r--contrib/libs/postgresql/src/include/port/win32ntdll.h32
-rw-r--r--contrib/libs/postgresql/src/port/dirmod.c2
-rw-r--r--contrib/libs/postgresql/src/port/dlopen.c2
-rw-r--r--contrib/libs/postgresql/src/port/getaddrinfo.c46
-rw-r--r--contrib/libs/postgresql/src/port/getrusage.c2
-rw-r--r--contrib/libs/postgresql/src/port/kill.c2
-rw-r--r--contrib/libs/postgresql/src/port/open.c106
-rw-r--r--contrib/libs/postgresql/src/port/pread.c2
-rw-r--r--contrib/libs/postgresql/src/port/pwrite.c2
-rw-r--r--contrib/libs/postgresql/src/port/pwritev.c2
-rw-r--r--contrib/libs/postgresql/src/port/system.c2
-rw-r--r--contrib/libs/postgresql/src/port/win32common.c68
-rw-r--r--contrib/libs/postgresql/src/port/win32env.c2
-rw-r--r--contrib/libs/postgresql/src/port/win32error.c2
-rw-r--r--contrib/libs/postgresql/src/port/win32fseek.c75
-rw-r--r--contrib/libs/postgresql/src/port/win32ntdll.c69
-rw-r--r--contrib/libs/postgresql/src/port/win32security.c20
-rw-r--r--contrib/libs/postgresql/src/port/win32setlocale.c2
-rw-r--r--contrib/libs/postgresql/src/port/win32stat.c215
28 files changed, 337 insertions, 428 deletions
diff --git a/contrib/libs/postgresql/src/backend/port/posix_sema.c b/contrib/libs/postgresql/src/backend/port/posix_sema.c
index 114da3b30c..a97a3ed99e 100644
--- a/contrib/libs/postgresql/src/backend/port/posix_sema.c
+++ b/contrib/libs/postgresql/src/backend/port/posix_sema.c
@@ -15,7 +15,7 @@
* forked backends, but they could not be accessed by exec'd backends.
*
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
diff --git a/contrib/libs/postgresql/src/backend/port/sysv_shmem.c b/contrib/libs/postgresql/src/backend/port/sysv_shmem.c
index 35cce89e9c..ea287c733d 100644
--- a/contrib/libs/postgresql/src/backend/port/sysv_shmem.c
+++ b/contrib/libs/postgresql/src/backend/port/sysv_shmem.c
@@ -9,7 +9,7 @@
* exist, though, because mmap'd shmem provides no way to find out how
* many processes are attached, which we need for interlocking purposes.
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
@@ -289,7 +289,7 @@ static void
IpcMemoryDetach(int status, Datum shmaddr)
{
/* Detach System V shared memory block. */
- if (shmdt(DatumGetPointer(shmaddr)) < 0)
+ if (shmdt((void *) DatumGetPointer(shmaddr)) < 0)
elog(LOG, "shmdt(%p) failed: %m", DatumGetPointer(shmaddr));
}
@@ -323,7 +323,7 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
IpcMemoryState state;
state = PGSharedMemoryAttach((IpcMemoryId) id2, NULL, &memAddress);
- if (memAddress && shmdt(memAddress) < 0)
+ if (memAddress && shmdt((void *) memAddress) < 0)
elog(LOG, "shmdt(%p) failed: %m", memAddress);
switch (state)
{
@@ -456,8 +456,6 @@ PGSharedMemoryAttach(IpcMemoryId shmId,
return shmStat.shm_nattch == 0 ? SHMSTATE_UNATTACHED : SHMSTATE_ATTACHED;
}
-#ifdef MAP_HUGETLB
-
/*
* Identify the huge page size to use, and compute the related mmap flags.
*
@@ -475,13 +473,19 @@ PGSharedMemoryAttach(IpcMemoryId shmId,
* hugepage sizes, we might want to think about more invasive strategies,
* such as increasing shared_buffers to absorb the extra space.
*
- * Returns the (real, assumed or config provided) page size into *hugepagesize,
- * and the hugepage-related mmap flags to use into *mmap_flags.
+ * Returns the (real, assumed or config provided) page size into
+ * *hugepagesize, and the hugepage-related mmap flags to use into
+ * *mmap_flags if requested by the caller. If huge pages are not supported,
+ * *hugepagesize and *mmap_flags are set to 0.
*/
-static void
+void
GetHugePageSize(Size *hugepagesize, int *mmap_flags)
{
+#ifdef MAP_HUGETLB
+
Size default_hugepagesize = 0;
+ Size hugepagesize_local = 0;
+ int mmap_flags_local = 0;
/*
* System-dependent code to find out the default huge page size.
@@ -519,12 +523,12 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
if (huge_page_size != 0)
{
/* If huge page size is requested explicitly, use that. */
- *hugepagesize = (Size) huge_page_size * 1024;
+ hugepagesize_local = (Size) huge_page_size * 1024;
}
else if (default_hugepagesize != 0)
{
/* Otherwise use the system default, if we have it. */
- *hugepagesize = default_hugepagesize;
+ hugepagesize_local = default_hugepagesize;
}
else
{
@@ -536,26 +540,39 @@ GetHugePageSize(Size *hugepagesize, int *mmap_flags)
* writing, there are no reports of any non-Linux systems being picky
* about that.
*/
- *hugepagesize = 2 * 1024 * 1024;
+ hugepagesize_local = 2 * 1024 * 1024;
}
- *mmap_flags = MAP_HUGETLB;
+ mmap_flags_local = MAP_HUGETLB;
/*
* On recent enough Linux, also include the explicit page size, if
* necessary.
*/
#if defined(MAP_HUGE_MASK) && defined(MAP_HUGE_SHIFT)
- if (*hugepagesize != default_hugepagesize)
+ if (hugepagesize_local != default_hugepagesize)
{
- int shift = pg_ceil_log2_64(*hugepagesize);
+ int shift = pg_ceil_log2_64(hugepagesize_local);
- *mmap_flags |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
+ mmap_flags_local |= (shift & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
}
#endif
-}
+
+ /* assign the results found */
+ if (mmap_flags)
+ *mmap_flags = mmap_flags_local;
+ if (hugepagesize)
+ *hugepagesize = hugepagesize_local;
+
+#else
+
+ if (hugepagesize)
+ *hugepagesize = 0;
+ if (mmap_flags)
+ *mmap_flags = 0;
#endif /* MAP_HUGETLB */
+}
/*
* Creates an anonymous mmap()ed shared memory segment.
@@ -790,7 +807,7 @@ PGSharedMemoryCreate(Size size,
break;
}
- if (oldhdr && shmdt(oldhdr) < 0)
+ if (oldhdr && shmdt((void *) oldhdr) < 0)
elog(LOG, "shmdt(%p) failed: %m", oldhdr);
}
diff --git a/contrib/libs/postgresql/src/backend/port/win32/crashdump.c b/contrib/libs/postgresql/src/backend/port/win32/crashdump.c
index 45b6696ba1..cea7be2896 100644
--- a/contrib/libs/postgresql/src/backend/port/win32/crashdump.c
+++ b/contrib/libs/postgresql/src/backend/port/win32/crashdump.c
@@ -28,7 +28,7 @@
* be added, though at the cost of a greater chance of the crash dump failing.
*
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/port/win32/crashdump.c
@@ -38,8 +38,6 @@
#include "postgres.h"
-#define WIN32_LEAN_AND_MEAN
-
/*
* Some versions of the MS SDK contain "typedef enum { ... } ;" which the MS
* compiler quite sanely complains about. Well done, Microsoft.
diff --git a/contrib/libs/postgresql/src/backend/port/win32/signal.c b/contrib/libs/postgresql/src/backend/port/win32/signal.c
index 580a517f3f..b71164d8db 100644
--- a/contrib/libs/postgresql/src/backend/port/win32/signal.c
+++ b/contrib/libs/postgresql/src/backend/port/win32/signal.c
@@ -3,7 +3,7 @@
* signal.c
* Microsoft Windows Win32 Signal Emulation Functions
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/port/win32/signal.c
@@ -52,7 +52,17 @@ static BOOL WINAPI pg_console_handler(DWORD dwCtrlType);
void
pg_usleep(long microsec)
{
- Assert(pgwin32_signal_event != NULL);
+ if (unlikely(pgwin32_signal_event == NULL))
+ {
+ /*
+ * If we're reached by pgwin32_open_handle() early in startup before
+ * the signal event is set up, just fall back to a regular
+ * non-interruptible sleep.
+ */
+ SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE);
+ return;
+ }
+
if (WaitForSingleObject(pgwin32_signal_event,
(microsec < 500 ? 1 : (microsec + 500) / 1000))
== WAIT_OBJECT_0)
diff --git a/contrib/libs/postgresql/src/backend/port/win32/socket.c b/contrib/libs/postgresql/src/backend/port/win32/socket.c
index af151e8470..52944a0d33 100644
--- a/contrib/libs/postgresql/src/backend/port/win32/socket.c
+++ b/contrib/libs/postgresql/src/backend/port/win32/socket.c
@@ -3,7 +3,7 @@
* socket.c
* Microsoft Windows Win32 Socket Functions
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/port/win32/socket.c
@@ -47,8 +47,8 @@ int pgwin32_noblock = 0;
*
* Note: where there is a direct correspondence between a WSAxxx error code
* and a Berkeley error symbol, this mapping is actually a no-op, because
- * in win32.h we redefine the network-related Berkeley error symbols to have
- * the values of their WSAxxx counterparts. The point of the switch is
+ * in win32_port.h we redefine the network-related Berkeley error symbols to
+ * have the values of their WSAxxx counterparts. The point of the switch is
* mostly to translate near-miss error codes into something that's sensible
* in the Berkeley universe.
*/
@@ -141,10 +141,15 @@ TranslateSocketError(void)
case WSAEDISCON:
errno = ENOTCONN;
break;
+ case WSAETIMEDOUT:
+ errno = ETIMEDOUT;
+ break;
default:
ereport(NOTICE,
- (errmsg_internal("unrecognized win32 socket error code: %d", WSAGetLastError())));
+ (errmsg_internal("unrecognized win32 socket error code: %d",
+ WSAGetLastError())));
errno = EINVAL;
+ break;
}
}
diff --git a/contrib/libs/postgresql/src/backend/port/win32/timer.c b/contrib/libs/postgresql/src/backend/port/win32/timer.c
index 53fdae9468..3405253af3 100644
--- a/contrib/libs/postgresql/src/backend/port/win32/timer.c
+++ b/contrib/libs/postgresql/src/backend/port/win32/timer.c
@@ -8,7 +8,7 @@
* - Does not support interval timer (value->it_interval)
* - Only supports ITIMER_REAL
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/port/win32/timer.c
diff --git a/contrib/libs/postgresql/src/backend/port/win32_sema.c b/contrib/libs/postgresql/src/backend/port/win32_sema.c
index 858b88adae..8e9c0f9307 100644
--- a/contrib/libs/postgresql/src/backend/port/win32_sema.c
+++ b/contrib/libs/postgresql/src/backend/port/win32_sema.c
@@ -3,7 +3,7 @@
* win32_sema.c
* Microsoft Windows Win32 Semaphores Emulation
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/port/win32_sema.c
diff --git a/contrib/libs/postgresql/src/backend/port/win32_shmem.c b/contrib/libs/postgresql/src/backend/port/win32_shmem.c
index d7a71992d8..6cf69411db 100644
--- a/contrib/libs/postgresql/src/backend/port/win32_shmem.c
+++ b/contrib/libs/postgresql/src/backend/port/win32_shmem.c
@@ -3,7 +3,7 @@
* win32_shmem.c
* Implement shared memory using win32 facilities
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/port/win32_shmem.c
@@ -605,3 +605,17 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
return true;
}
+
+/*
+ * This function is provided for consistency with sysv_shmem.c and does not
+ * provide any useful information for Windows. To obtain the large page size,
+ * use GetLargePageMinimum() instead.
+ */
+void
+GetHugePageSize(Size *hugepagesize, int *mmap_flags)
+{
+ if (hugepagesize)
+ *hugepagesize = 0;
+ if (mmap_flags)
+ *mmap_flags = 0;
+}
diff --git a/contrib/libs/postgresql/src/include/port/win32_msvc/unistd.h b/contrib/libs/postgresql/src/include/port/win32_msvc/unistd.h
index b63f4770a1..b7795ba03c 100644
--- a/contrib/libs/postgresql/src/include/port/win32_msvc/unistd.h
+++ b/contrib/libs/postgresql/src/include/port/win32_msvc/unistd.h
@@ -1 +1,9 @@
/* src/include/port/win32_msvc/unistd.h */
+
+/*
+ * MSVC does not define these, nor does _fileno(stdin) etc reliably work
+ * (returns -1 if stdin/out/err are closed).
+ */
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
diff --git a/contrib/libs/postgresql/src/include/port/win32ntdll.h b/contrib/libs/postgresql/src/include/port/win32ntdll.h
new file mode 100644
index 0000000000..291b067ea4
--- /dev/null
+++ b/contrib/libs/postgresql/src/include/port/win32ntdll.h
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * win32ntdll.h
+ * Dynamically loaded Windows NT functions.
+ *
+ * Portions Copyright (c) 2021-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/port/win32ntdll.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef WIN32NTDLL_H
+#define WIN32NTDLL_H
+
+/*
+ * Because this includes NT headers that normally conflict with Win32 headers,
+ * any translation unit that includes it should #define UMDF_USING_NTSTATUS
+ * before including <windows.h>.
+ */
+
+#include <ntstatus.h>
+#include <winternl.h>
+
+typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void);
+
+extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
+
+extern int initialize_ntdll(void);
+
+#endif /* WIN32NTDLL_H */
diff --git a/contrib/libs/postgresql/src/port/dirmod.c b/contrib/libs/postgresql/src/port/dirmod.c
index 46c9c235c8..62daec7af8 100644
--- a/contrib/libs/postgresql/src/port/dirmod.c
+++ b/contrib/libs/postgresql/src/port/dirmod.c
@@ -3,7 +3,7 @@
* dirmod.c
* directory handling functions
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* This includes replacement versions of functions that work on
diff --git a/contrib/libs/postgresql/src/port/dlopen.c b/contrib/libs/postgresql/src/port/dlopen.c
index f7948b861f..d441dc8196 100644
--- a/contrib/libs/postgresql/src/port/dlopen.c
+++ b/contrib/libs/postgresql/src/port/dlopen.c
@@ -3,7 +3,7 @@
* dlopen.c
* dynamic loader for platforms without dlopen()
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
diff --git a/contrib/libs/postgresql/src/port/getaddrinfo.c b/contrib/libs/postgresql/src/port/getaddrinfo.c
index bb194da529..3284c6eb52 100644
--- a/contrib/libs/postgresql/src/port/getaddrinfo.c
+++ b/contrib/libs/postgresql/src/port/getaddrinfo.c
@@ -13,7 +13,7 @@
* use the Windows native routines, but if not, we use our own.
*
*
- * Copyright (c) 2003-2021, PostgreSQL Global Development Group
+ * Copyright (c) 2003-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/getaddrinfo.c
@@ -34,6 +34,14 @@
#include "port/pg_bswap.h"
+#ifdef FRONTEND
+static int pqGethostbyname(const char *name,
+ struct hostent *resultbuf,
+ char *buffer, size_t buflen,
+ struct hostent **result,
+ int *herrno);
+#endif
+
#ifdef WIN32
/*
* The native routines may or may not exist on the Windows platform we are on,
@@ -394,3 +402,39 @@ getnameinfo(const struct sockaddr *sa, int salen,
return 0;
}
+
+/*
+ * Wrapper around gethostbyname() or gethostbyname_r() to mimic
+ * POSIX gethostbyname_r() behaviour, if it is not available or required.
+ */
+#ifdef FRONTEND
+static int
+pqGethostbyname(const char *name,
+ struct hostent *resultbuf,
+ char *buffer, size_t buflen,
+ struct hostent **result,
+ int *herrno)
+{
+#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
+
+ /*
+ * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
+ * hostent *'
+ */
+ *result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
+ return (*result == NULL) ? -1 : 0;
+#else
+
+ /* no gethostbyname_r(), just use gethostbyname() */
+ *result = gethostbyname(name);
+
+ if (*result != NULL)
+ *herrno = h_errno;
+
+ if (*result != NULL)
+ return 0;
+ else
+ return -1;
+#endif
+}
+#endif /* FRONTEND */
diff --git a/contrib/libs/postgresql/src/port/getrusage.c b/contrib/libs/postgresql/src/port/getrusage.c
index 99f240f6da..8369fd2793 100644
--- a/contrib/libs/postgresql/src/port/getrusage.c
+++ b/contrib/libs/postgresql/src/port/getrusage.c
@@ -3,7 +3,7 @@
* getrusage.c
* get information about resource utilisation
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
diff --git a/contrib/libs/postgresql/src/port/kill.c b/contrib/libs/postgresql/src/port/kill.c
index 99b35de45b..ff0862683c 100644
--- a/contrib/libs/postgresql/src/port/kill.c
+++ b/contrib/libs/postgresql/src/port/kill.c
@@ -3,7 +3,7 @@
* kill.c
* kill()
*
- * Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* This is a replacement version of kill for Win32 which sends
* signals that the backend can recognize.
diff --git a/contrib/libs/postgresql/src/port/open.c b/contrib/libs/postgresql/src/port/open.c
index 14c6debba9..8c09c7c1f7 100644
--- a/contrib/libs/postgresql/src/port/open.c
+++ b/contrib/libs/postgresql/src/port/open.c
@@ -4,7 +4,7 @@
* Win32 open() replacement
*
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* src/port/open.c
*
@@ -13,17 +13,20 @@
#ifdef WIN32
+#define UMDF_USING_NTSTATUS
+
#ifndef FRONTEND
#include "postgres.h"
#else
#include "postgres_fe.h"
#endif
+#include "port/win32ntdll.h"
+
#include <fcntl.h>
#include <assert.h>
#include <sys/stat.h>
-
static int
openFlagsToCreateFileFlags(int openFlags)
{
@@ -56,38 +59,25 @@ openFlagsToCreateFileFlags(int openFlags)
}
/*
- * - file attribute setting, based on fileMode?
+ * Internal function used by pgwin32_open() and _pgstat64(). When
+ * backup_semantics is true, directories may be opened (for limited uses). On
+ * failure, INVALID_HANDLE_VALUE is returned and errno is set.
*/
-int
-pgwin32_open(const char *fileName, int fileFlags,...)
+HANDLE
+pgwin32_open_handle(const char *fileName, int fileFlags, bool backup_semantics)
{
- int fd;
- HANDLE h = INVALID_HANDLE_VALUE;
+ HANDLE h;
SECURITY_ATTRIBUTES sa;
int loops = 0;
+ if (initialize_ntdll() < 0)
+ return INVALID_HANDLE_VALUE;
+
/* Check that we can handle the request */
assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND |
(O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) |
_O_SHORT_LIVED | O_DSYNC | O_DIRECT |
(O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags);
-#ifndef FRONTEND
- Assert(pgwin32_signal_event != NULL); /* small chance of pg_usleep() */
-#endif
-
-#ifdef FRONTEND
-
- /*
- * Since PostgreSQL 12, those concurrent-safe versions of open() and
- * fopen() can be used by frontends, having as side-effect to switch the
- * file-translation mode from O_TEXT to O_BINARY if none is specified.
- * Caller may want to enforce the binary or text mode, but if nothing is
- * defined make sure that the default mode maps with what versions older
- * than 12 have been doing.
- */
- if ((fileFlags & O_BINARY) == 0)
- fileFlags |= O_TEXT;
-#endif
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
@@ -102,6 +92,7 @@ pgwin32_open(const char *fileName, int fileFlags,...)
&sa,
openFlagsToCreateFileFlags(fileFlags),
FILE_ATTRIBUTE_NORMAL |
+ (backup_semantics ? FILE_FLAG_BACKUP_SEMANTICS : 0) |
((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) |
((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) |
((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) |
@@ -140,38 +131,55 @@ pgwin32_open(const char *fileName, int fileFlags,...)
/*
* ERROR_ACCESS_DENIED is returned if the file is deleted but not yet
* gone (Windows NT status code is STATUS_DELETE_PENDING). In that
- * case we want to wait a bit and try again, giving up after 1 second
- * (since this condition should never persist very long). However,
- * there are other commonly-hit cases that return ERROR_ACCESS_DENIED,
- * so care is needed. In particular that happens if we try to open a
- * directory, or of course if there's an actual file-permissions
- * problem. To distinguish these cases, try a stat(). In the
- * delete-pending case, it will either also get STATUS_DELETE_PENDING,
- * or it will see the file as gone and fail with ENOENT. In other
- * cases it will usually succeed. The only somewhat-likely case where
- * this coding will uselessly wait is if there's a permissions problem
- * with a containing directory, which we hope will never happen in any
- * performance-critical code paths.
+ * case, we'd better ask for the NT status too so we can translate it
+ * to a more Unix-like error. We hope that nothing clobbers the NT
+ * status in between the internal NtCreateFile() call and CreateFile()
+ * returning.
+ *
+ * If there's no O_CREAT flag, then we'll pretend the file is
+ * invisible. With O_CREAT, we have no choice but to report that
+ * there's a file in the way (which wouldn't happen on Unix).
*/
- if (err == ERROR_ACCESS_DENIED)
+ if (err == ERROR_ACCESS_DENIED &&
+ pg_RtlGetLastNtStatus() == STATUS_DELETE_PENDING)
{
- if (loops < 10)
- {
- struct stat st;
-
- if (stat(fileName, &st) != 0)
- {
- pg_usleep(100000);
- loops++;
- continue;
- }
- }
+ if (fileFlags & O_CREAT)
+ err = ERROR_FILE_EXISTS;
+ else
+ err = ERROR_FILE_NOT_FOUND;
}
_dosmaperr(err);
- return -1;
+ return INVALID_HANDLE_VALUE;
}
+ return h;
+}
+
+int
+pgwin32_open(const char *fileName, int fileFlags,...)
+{
+ HANDLE h;
+ int fd;
+
+ h = pgwin32_open_handle(fileName, fileFlags, false);
+ if (h == INVALID_HANDLE_VALUE)
+ return -1;
+
+#ifdef FRONTEND
+
+ /*
+ * Since PostgreSQL 12, those concurrent-safe versions of open() and
+ * fopen() can be used by frontends, having as side-effect to switch the
+ * file-translation mode from O_TEXT to O_BINARY if none is specified.
+ * Caller may want to enforce the binary or text mode, but if nothing is
+ * defined make sure that the default mode maps with what versions older
+ * than 12 have been doing.
+ */
+ if ((fileFlags & O_BINARY) == 0)
+ fileFlags |= O_TEXT;
+#endif
+
/* _open_osfhandle will, on error, set errno accordingly */
if ((fd = _open_osfhandle((intptr_t) h, fileFlags & O_APPEND)) < 0)
CloseHandle(h); /* will not affect errno */
diff --git a/contrib/libs/postgresql/src/port/pread.c b/contrib/libs/postgresql/src/port/pread.c
index a35d3f4b07..bbf12ee027 100644
--- a/contrib/libs/postgresql/src/port/pread.c
+++ b/contrib/libs/postgresql/src/port/pread.c
@@ -3,7 +3,7 @@
* pread.c
* Implementation of pread(2) for platforms that lack one.
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/pread.c
diff --git a/contrib/libs/postgresql/src/port/pwrite.c b/contrib/libs/postgresql/src/port/pwrite.c
index e3a132aa7a..cadecc481c 100644
--- a/contrib/libs/postgresql/src/port/pwrite.c
+++ b/contrib/libs/postgresql/src/port/pwrite.c
@@ -3,7 +3,7 @@
* pwrite.c
* Implementation of pwrite(2) for platforms that lack one.
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/pwrite.c
diff --git a/contrib/libs/postgresql/src/port/pwritev.c b/contrib/libs/postgresql/src/port/pwritev.c
index 082bed9abf..bc53704ef7 100644
--- a/contrib/libs/postgresql/src/port/pwritev.c
+++ b/contrib/libs/postgresql/src/port/pwritev.c
@@ -3,7 +3,7 @@
* pwritev.c
* Implementation of pwritev(2) for platforms that lack one.
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/pwritev.c
diff --git a/contrib/libs/postgresql/src/port/system.c b/contrib/libs/postgresql/src/port/system.c
index 8618e47f97..20a830fd5c 100644
--- a/contrib/libs/postgresql/src/port/system.c
+++ b/contrib/libs/postgresql/src/port/system.c
@@ -29,7 +29,7 @@
* quote character on the command line, preserving any text after the last
* quote character.
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* src/port/system.c
*
diff --git a/contrib/libs/postgresql/src/port/win32common.c b/contrib/libs/postgresql/src/port/win32common.c
deleted file mode 100644
index 2fd78f7f93..0000000000
--- a/contrib/libs/postgresql/src/port/win32common.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * win32common.c
- * Common routines shared among the win32*.c ports.
- *
- * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * src/port/win32common.c
- *
- *-------------------------------------------------------------------------
- */
-
-#ifdef FRONTEND
-#include "postgres_fe.h"
-#else
-#include "postgres.h"
-#endif
-
-#ifdef WIN32
-
-/*
- * pgwin32_get_file_type
- *
- * Convenience wrapper for GetFileType() with specific error handling for all the
- * port implementations. Returns the file type associated with a HANDLE.
- *
- * On error, sets errno with FILE_TYPE_UNKNOWN as file type.
- */
-DWORD
-pgwin32_get_file_type(HANDLE hFile)
-{
- DWORD fileType = FILE_TYPE_UNKNOWN;
- DWORD lastError;
-
- errno = 0;
-
- /*
- * When stdin, stdout, and stderr aren't associated with a stream the
- * special value -2 is returned:
- * https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle
- */
- if (hFile == INVALID_HANDLE_VALUE || hFile == (HANDLE) -2)
- {
- errno = EINVAL;
- return FILE_TYPE_UNKNOWN;
- }
-
- fileType = GetFileType(hFile);
- lastError = GetLastError();
-
- /*
- * Invoke GetLastError in order to distinguish between a "valid" return of
- * FILE_TYPE_UNKNOWN and its return due to a calling error. In case of
- * success, GetLastError() returns NO_ERROR.
- */
- if (fileType == FILE_TYPE_UNKNOWN && lastError != NO_ERROR)
- {
- _dosmaperr(lastError);
- return FILE_TYPE_UNKNOWN;
- }
-
- return fileType;
-}
-
-#endif /* WIN32 */
diff --git a/contrib/libs/postgresql/src/port/win32env.c b/contrib/libs/postgresql/src/port/win32env.c
index a03556078c..7aa5a3081e 100644
--- a/contrib/libs/postgresql/src/port/win32env.c
+++ b/contrib/libs/postgresql/src/port/win32env.c
@@ -6,7 +6,7 @@
* These functions update both the process environment and caches in
* (potentially multiple) C run-time library (CRT) versions.
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
diff --git a/contrib/libs/postgresql/src/port/win32error.c b/contrib/libs/postgresql/src/port/win32error.c
index 0e5f91adfa..fca867ba3d 100644
--- a/contrib/libs/postgresql/src/port/win32error.c
+++ b/contrib/libs/postgresql/src/port/win32error.c
@@ -3,7 +3,7 @@
* win32error.c
* Map win32 error codes to errno values
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/win32error.c
diff --git a/contrib/libs/postgresql/src/port/win32fseek.c b/contrib/libs/postgresql/src/port/win32fseek.c
deleted file mode 100644
index 985313c825..0000000000
--- a/contrib/libs/postgresql/src/port/win32fseek.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * win32fseek.c
- * Replacements for fseeko() and ftello().
- *
- * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
- *
- * IDENTIFICATION
- * src/port/win32fseek.c
- *
- *-------------------------------------------------------------------------
- */
-
-#ifdef FRONTEND
-#include "postgres_fe.h"
-#else
-#include "postgres.h"
-#endif
-
-#if defined(WIN32) && defined(_MSC_VER)
-
-/*
- * _pgfseeko64
- *
- * Calling fseek() on a handle to a non-seeking device such as a pipe or
- * a communications device is not supported, and fseek() may not return
- * an error. This wrapper relies on the file type to check which cases
- * are supported.
- */
-int
-_pgfseeko64(FILE *stream, pgoff_t offset, int origin)
-{
- DWORD fileType;
- HANDLE hFile = (HANDLE) _get_osfhandle(_fileno(stream));
-
- fileType = pgwin32_get_file_type(hFile);
- if (errno != 0)
- return -1;
-
- if (fileType == FILE_TYPE_DISK)
- return _fseeki64(stream, offset, origin);
- else if (fileType == FILE_TYPE_CHAR || fileType == FILE_TYPE_PIPE)
- errno = ESPIPE;
- else
- errno = EINVAL;
-
- return -1;
-}
-
-/*
- * _pgftello64
- *
- * Same as _pgfseeko64().
- */
-pgoff_t
-_pgftello64(FILE *stream)
-{
- DWORD fileType;
- HANDLE hFile = (HANDLE) _get_osfhandle(_fileno(stream));
-
- fileType = pgwin32_get_file_type(hFile);
- if (errno != 0)
- return -1;
-
- if (fileType == FILE_TYPE_DISK)
- return _ftelli64(stream);
- else if (fileType == FILE_TYPE_CHAR || fileType == FILE_TYPE_PIPE)
- errno = ESPIPE;
- else
- errno = EINVAL;
-
- return -1;
-}
-
-#endif /* defined(WIN32) && defined(_MSC_VER) */
diff --git a/contrib/libs/postgresql/src/port/win32ntdll.c b/contrib/libs/postgresql/src/port/win32ntdll.c
new file mode 100644
index 0000000000..10c33c6a01
--- /dev/null
+++ b/contrib/libs/postgresql/src/port/win32ntdll.c
@@ -0,0 +1,69 @@
+/*-------------------------------------------------------------------------
+ *
+ * win32ntdll.c
+ * Dynamically loaded Windows NT functions.
+ *
+ * Portions Copyright (c) 2021-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/port/win32ntdll.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define UMDF_USING_NTSTATUS
+
+#include "c.h"
+
+#include "port/win32ntdll.h"
+
+RtlGetLastNtStatus_t pg_RtlGetLastNtStatus;
+
+typedef struct NtDllRoutine
+{
+ const char *name;
+ pg_funcptr_t *address;
+} NtDllRoutine;
+
+static const NtDllRoutine routines[] = {
+ {"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus}
+};
+
+static bool initialized;
+
+int
+initialize_ntdll(void)
+{
+ HMODULE module;
+
+ if (initialized)
+ return 0;
+
+ if (!(module = LoadLibraryEx("ntdll.dll", NULL, 0)))
+ {
+ _dosmaperr(GetLastError());
+ return -1;
+ }
+
+ for (int i = 0; i < lengthof(routines); ++i)
+ {
+ pg_funcptr_t address;
+
+ address = (pg_funcptr_t) GetProcAddress(module, routines[i].name);
+ if (!address)
+ {
+ _dosmaperr(GetLastError());
+ FreeLibrary(module);
+
+ return -1;
+ }
+
+ *(pg_funcptr_t *) routines[i].address = address;
+ }
+
+ initialized = true;
+
+ return 0;
+}
diff --git a/contrib/libs/postgresql/src/port/win32security.c b/contrib/libs/postgresql/src/port/win32security.c
index 4a673fde19..1235199f2f 100644
--- a/contrib/libs/postgresql/src/port/win32security.c
+++ b/contrib/libs/postgresql/src/port/win32security.c
@@ -3,7 +3,7 @@
* win32security.c
* Microsoft Windows Win32 Security Support Functions
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/win32security.c
@@ -95,8 +95,11 @@ pgwin32_is_admin(void)
* We consider ourselves running as a service if one of the following is
* true:
*
- * 1) We are running as LocalSystem (only used by services)
- * 2) Our token contains SECURITY_SERVICE_RID (automatically added to the
+ * 1) Standard error is not valid (always the case for services, and pg_ctl
+ * running as a service "passes" that down to postgres,
+ * c.f. CreateRestrictedProcess())
+ * 2) We are running as LocalSystem (only used by services)
+ * 3) Our token contains SECURITY_SERVICE_RID (automatically added to the
* process token by the SCM when starting a service)
*
* The check for LocalSystem is needed, because surprisingly, if a service
@@ -121,12 +124,21 @@ pgwin32_is_service(void)
PSID ServiceSid;
PSID LocalSystemSid;
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+ HANDLE stderr_handle;
/* Only check the first time */
if (_is_service != -1)
return _is_service;
- /* First check for LocalSystem */
+ /* Check if standard error is not valid */
+ stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
+ if (stderr_handle != INVALID_HANDLE_VALUE && stderr_handle != NULL)
+ {
+ _is_service = 0;
+ return _is_service;
+ }
+
+ /* Check if running as LocalSystem */
if (!AllocateAndInitializeSid(&NtAuthority, 1,
SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
&LocalSystemSid))
diff --git a/contrib/libs/postgresql/src/port/win32setlocale.c b/contrib/libs/postgresql/src/port/win32setlocale.c
index 4edae05bb7..aadd09a4e9 100644
--- a/contrib/libs/postgresql/src/port/win32setlocale.c
+++ b/contrib/libs/postgresql/src/port/win32setlocale.c
@@ -3,7 +3,7 @@
* win32setlocale.c
* Wrapper to work around bugs in Windows setlocale() implementation
*
- * Copyright (c) 2011-2021, PostgreSQL Global Development Group
+ * Copyright (c) 2011-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/port/win32setlocale.c
diff --git a/contrib/libs/postgresql/src/port/win32stat.c b/contrib/libs/postgresql/src/port/win32stat.c
index acbf4c7e27..e03ed5f35c 100644
--- a/contrib/libs/postgresql/src/port/win32stat.c
+++ b/contrib/libs/postgresql/src/port/win32stat.c
@@ -3,7 +3,7 @@
* win32stat.c
* Replacements for <sys/stat.h> functions using GetFileInformationByHandle
*
- * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
@@ -19,53 +19,6 @@
#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
@@ -162,120 +115,18 @@ 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.
+ * Our open wrapper will report STATUS_DELETE_PENDING as ENOENT. We
+ * request FILE_FLAG_BACKUP_SEMANTICS so that we can open directories too,
+ * for limited purposes. We use the private handle-based version, so we
+ * don't risk running out of fds.
*/
- 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);
+ hFile = pgwin32_open_handle(name, O_RDONLY, true);
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);
@@ -289,50 +140,34 @@ int
_pgfstat64(int fileno, struct stat *buf)
{
HANDLE hFile = (HANDLE) _get_osfhandle(fileno);
- DWORD fileType = FILE_TYPE_UNKNOWN;
- unsigned short st_mode;
+ BY_HANDLE_FILE_INFORMATION fiData;
- if (buf == NULL)
+ if (hFile == INVALID_HANDLE_VALUE || buf == NULL)
{
errno = EINVAL;
return -1;
}
- fileType = pgwin32_get_file_type(hFile);
- if (errno != 0)
- return -1;
-
- switch (fileType)
+ /*
+ * 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))
{
- /* The specified file is a disk file */
- case FILE_TYPE_DISK:
- return fileinfo_to_stat(hFile, buf);
-
- /*
- * The specified file is a socket, a named pipe, or an anonymous
- * pipe.
- */
- case FILE_TYPE_PIPE:
- st_mode = _S_IFIFO;
- break;
- /* The specified file is a character file */
- case FILE_TYPE_CHAR:
- st_mode = _S_IFCHR;
- break;
- /* Unused flag and unknown file type */
- case FILE_TYPE_REMOTE:
- case FILE_TYPE_UNKNOWN:
- default:
- errno = EINVAL;
- return -1;
+ memset(buf, 0, sizeof(*buf));
+ buf->st_mode = _S_IFCHR;
+ buf->st_dev = fileno;
+ buf->st_rdev = fileno;
+ buf->st_nlink = 1;
+ return 0;
}
- memset(buf, 0, sizeof(*buf));
- buf->st_mode = st_mode;
- buf->st_dev = fileno;
- buf->st_rdev = fileno;
- buf->st_nlink = 1;
- return 0;
+ return fileinfo_to_stat(hFile, buf);
}
#endif /* WIN32 */