diff --git a/Makefile b/Makefile index ab3bc673..aaf5d42e 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ PGDIRBZ2 = $(root_dir)/tmp/postgres.tar.bz2 PG_VERSION = 16.1 PG_VERSION_MAJOR = $(call word-dot,$(PG_VERSION),1) +PG_VERSION_NUM = 160001 PROTOC_VERSION = 25.1 VERSION = 5.0.0 @@ -126,68 +127,14 @@ $(PGDIR): cd $(PGDIR); make -C src/port pg_config_paths.h cd $(PGDIR); make -C src/backend generated-headers cd $(PGDIR); make -C src/backend parser-recursive # Triggers copying of includes to where they belong, as well as generating gram.c/scan.c - # This causes compatibility problems on some Linux distros, with "xlocale.h" not being available - echo "#undef HAVE_LOCALE_T" >> $(PGDIR)/src/include/pg_config.h - echo "#undef LOCALE_T_IN_XLOCALE" >> $(PGDIR)/src/include/pg_config.h - echo "#undef WCSTOMBS_L_IN_XLOCALE" >> $(PGDIR)/src/include/pg_config.h - # Support 32-bit systems without reconfiguring - echo "#undef PG_INT128_TYPE" >> $(PGDIR)/src/include/pg_config.h - # Support gcc earlier than 4.6.0 without reconfiguring - echo "#undef HAVE__STATIC_ASSERT" >> $(PGDIR)/src/include/pg_config.h # Avoid problems with static asserts echo "#undef StaticAssertDecl" >> $(PGDIR)/src/include/c.h echo "#define StaticAssertDecl(condition, errmessage)" >> $(PGDIR)/src/include/c.h - # Avoid dependency on execinfo (requires extra library on musl-libc based systems) - echo "#undef HAVE_EXECINFO_H" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_BACKTRACE_SYMBOLS" >> $(PGDIR)/src/include/pg_config.h - # Avoid dependency on hardware popcount instructions (POPQNTQ) on x86 - echo "#undef HAVE_X86_64_POPCNTQ" >> $(PGDIR)/src/include/pg_config.h - # Avoid dependency on cpuid.h (only supported on x86 systems) - echo "#undef HAVE__GET_CPUID" >> $(PGDIR)/src/include/pg_config.h - # Avoid CRC extension usage to ensure we are not architecture-dependent - echo "#undef USE_ARMV8_CRC32C" >> $(PGDIR)/src/include/pg_config.h - echo "#undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK" >> $(PGDIR)/src/include/pg_config.h - # Ensure we don't fail on systems that have strchrnul support (FreeBSD and NetBSD) - echo "#include " >> $(PGDIR)/src/include/pg_config.h - echo "#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2))" >> $(PGDIR)/src/include/pg_config.h - echo "#define HAVE_STRCHRNUL" >> $(PGDIR)/src/include/pg_config.h - echo "#endif" >> $(PGDIR)/src/include/pg_config.h - # Optionally support 32-bit - echo "#if defined(_WIN32) || __SIZEOF_POINTER__ == 4" >> $(PGDIR)/src/include/pg_config.h - echo "#undef ALIGNOF_DOUBLE" >> $(PGDIR)/src/include/pg_config.h - echo "#define ALIGNOF_DOUBLE 4" >> $(PGDIR)/src/include/pg_config.h - echo "#undef ALIGNOF_LONG" >> $(PGDIR)/src/include/pg_config.h - echo "#define ALIGNOF_LONG 4" >> $(PGDIR)/src/include/pg_config.h - echo "#define ALIGNOF_LONG_LONG_INT 4" >> $(PGDIR)/src/include/pg_config.h - echo "#undef ALIGNOF_PG_INT128_TYPE" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_LONG_INT_64" >> $(PGDIR)/src/include/pg_config.h - echo "#define HAVE_LONG_LONG_INT_64 1" >> $(PGDIR)/src/include/pg_config.h - echo "#undef INT64_MODIFIER" >> $(PGDIR)/src/include/pg_config.h - echo "#define INT64_MODIFIER \"ll\"" >> $(PGDIR)/src/include/pg_config.h - echo "#undef PG_INT128_TYPE" >> $(PGDIR)/src/include/pg_config.h - echo "#undef PG_INT64_TYPE" >> $(PGDIR)/src/include/pg_config.h - echo "#define PG_INT64_TYPE long long int" >> $(PGDIR)/src/include/pg_config.h - echo "#undef SIZEOF_LONG" >> $(PGDIR)/src/include/pg_config.h - echo "#define SIZEOF_LONG 4" >> $(PGDIR)/src/include/pg_config.h - echo "#undef SIZEOF_SIZE_T" >> $(PGDIR)/src/include/pg_config.h - echo "#define SIZEOF_SIZE_T 4" >> $(PGDIR)/src/include/pg_config.h - echo "#undef SIZEOF_VOID_P" >> $(PGDIR)/src/include/pg_config.h - echo "#define SIZEOF_VOID_P 4" >> $(PGDIR)/src/include/pg_config.h - echo "#endif" >> $(PGDIR)/src/include/pg_config.h - # Windows - echo "#if defined(_WIN32) || defined(_WIN64)" >> $(PGDIR)/src/include/pg_config.h - echo "#define WIN32 1" >> $(PGDIR)/src/include/pg_config.h - echo "#define __thread __declspec( thread )" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_STRINGS_H" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_VISIBILITY_ATTRIBUTE" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE__BUILTIN_CONSTANT_P" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_TYPEOF" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_GETOPT_H" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_SYSLOG" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_PTHREAD" >> $(PGDIR)/src/include/pg_config.h - echo "#undef HAVE_PTHREAD_IS_THREADED_NP" >> $(PGDIR)/src/include/pg_config.h - echo "#endif" >> $(PGDIR)/src/include/pg_config.h + # Add pg_config.h overrides + cat scripts/pg_config_overrides.h >> $(PGDIR)/src/include/pg_config.h + # Only define strlcpy when needed + sed -i "" '$(shell echo 's/\#include "c.h"/#include "c.h"\n#if HAVE_DECL_STRLCPY == 0/')' $(PGDIR)/src/port/strlcpy.c + echo "#endif // HAVE_DECL_STRLCPY == 0" >> $(PGDIR)/src/port/strlcpy.c extract_source: $(PGDIR) -@ $(RM) -rf ./src/postgres/ @@ -203,10 +150,18 @@ extract_source: $(PGDIR) cp $(PGDIR)/src/include/port/win32_port.h ./src/postgres/include/port cp -a $(PGDIR)/src/include/port/win32 ./src/postgres/include/port cp -a $(PGDIR)/src/include/port/win32_msvc ./src/postgres/include/port + # Override OS-specific pg_config_os.h to only load Win32 logic (the primary port logic that matters for libpg_query), if needed + echo "#if defined(_WIN32) || defined(_WIN64)" > ./src/postgres/include/pg_config_os.h + echo "#include \"port/win32.h\"" >> ./src/postgres/include/pg_config_os.h + # Load windows.h early so ERROR is defined so win_32.port.h can undef it (loaded via postgres.h/c.h) + echo "#include " >> ./src/postgres/include/pg_config_os.h + echo "#endif" >> ./src/postgres/include/pg_config_os.h + # Adjust version string to ignore differences in build environments + sed -i "" '$(shell echo 's/\#define PG_VERSION_STR .*/#define PG_VERSION_STR "PostgreSQL $(PG_VERSION) \(libpg_query\)"/')' ./src/postgres/include/pg_config.h # Copy version information so its easily accessible - sed -i "" '$(shell echo 's/\#define PG_MAJORVERSION .*/'`grep "\#define PG_MAJORVERSION " ./src/postgres/include/pg_config.h`'/')' pg_query.h - sed -i "" '$(shell echo 's/\#define PG_VERSION .*/'`grep "\#define PG_VERSION " ./src/postgres/include/pg_config.h`'/')' pg_query.h - sed -i "" '$(shell echo 's/\#define PG_VERSION_NUM .*/'`grep "\#define PG_VERSION_NUM " ./src/postgres/include/pg_config.h`'/')' pg_query.h + sed -i "" '$(shell echo 's/\#define PG_MAJORVERSION .*/#define PG_MAJORVERSION "$(PG_VERSION_MAJOR)"/')' pg_query.h + sed -i "" '$(shell echo 's/\#define PG_VERSION .*/#define PG_VERSION "$(PG_VERSION)"/')' pg_query.h + sed -i "" '$(shell echo 's/\#define PG_VERSION_NUM .*/#define PG_VERSION_NUM $(PG_VERSION_NUM)/')' pg_query.h # Copy regress SQL files so we can use them in tests rm -f ./test/sql/postgres_regress/*.sql cp $(PGDIR)/src/test/regress/sql/*.sql ./test/sql/postgres_regress/ diff --git a/scripts/extract_source.rb b/scripts/extract_source.rb index 8810bd00..5b807ce8 100644 --- a/scripts/extract_source.rb +++ b/scripts/extract_source.rb @@ -103,7 +103,7 @@ def run @basepath + 'src/port/win32env.c', # Win32 only @basepath + 'src/port/win32security.c', # Win32 only @basepath + 'src/port/gettimeofday.c', # Win32 only - @basepath + 'src/port/strlcpy.c', # Not needed and conflicts with available function + @basepath + 'src/port/strnlen.c', # Not needed and conflicts with available function @basepath + 'src/port/strlcat.c', # Not needed and conflicts with available function @basepath + 'src/port/unsetenv.c', # Not needed and conflicts with available function @basepath + 'src/port/getaddrinfo.c', # Not needed and conflicts with available function @@ -214,15 +214,30 @@ def self.analysis_filename(filename, basepath) def analyze_file(file) index = FFI::Clang::Index.new(true, true) - translation_unit = index.parse_translation_unit(file, [ + flags = [ '-I', @basepath + 'src/include', '-I', '/usr/local/opt/openssl/include', '-I', `xcrun --sdk macosx --show-sdk-path`.strip + '/usr/include', '-DDLSUFFIX=".bundle"', '-g', '-DUSE_ASSERT_CHECKING', - '-DEXEC_BACKEND' # Ensure we remove any unnecessary EXEC_BACKEND (Win32) code - ]) + # EXEC_BACKEND is used on Windows, and can always be safely set during code analysis + '-DEXEC_BACKEND', + ] + + # For certain files, use WIN32 define - we can't always do this since it pulls unnecessary code in other cases + if file == @basepath + 'src/backend/utils/error/elog.c' || file == @basepath + 'src/backend/utils/mb/mbutils.c' + flags << '-DWIN32' + flags << '-D__CYGWIN__' # Avoid pulling in win32_port.h (which includes a bunch of system headers we don't actually have) + end + + # To override built-ins, we must avoid pulling in any system headers, so pretend we already defined c.h + if file == @basepath + 'src/port/strlcpy.c' + flags << '-DC_H' + end + + translation_unit = index.parse_translation_unit(file, flags) + cursor = translation_unit.cursor func_cursor = nil @@ -535,6 +550,20 @@ def write_out } )) # We're always working with fn_rettype = VOIDOID, due to our use of plpgsql_compile_inline +# Mocks REQUIRED for Windows support +runner.mock('write_stderr', %( +void +write_stderr(const char *fmt,...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fflush(stderr); + va_end(ap); +} +)) # Avoid pulling in write_console/write_eventlog, and instead always output to stderr (like on POSIX) +runner.mock('should_output_to_client', 'static inline bool should_output_to_client(int elevel) { return false; }') # Avoid pulling in postmaster.c, which has a bunch of Windows-specific code hidden behind a define + ## --- # SQL Parsing @@ -593,8 +622,8 @@ def write_out runner.deep_resolve('pg_leftmost_one_pos') runner.deep_resolve('pg_rightmost_one_pos') runner.deep_resolve('pg_number_of_ones') -runner.deep_resolve('strlcpy') runner.deep_resolve('GetMessageEncoding') +runner.deep_resolve('__builtin___strlcpy_chk') # aka "strlcpy" on Windows runner.write_out diff --git a/scripts/pg_config_overrides.h b/scripts/pg_config_overrides.h new file mode 100644 index 00000000..c412ba43 --- /dev/null +++ b/scripts/pg_config_overrides.h @@ -0,0 +1,145 @@ +/* This causes compatibility problems on some Linux distros, with "xlocale.h" not being available */ +#undef HAVE_LOCALE_T +#undef LOCALE_T_IN_XLOCALE +#undef WCSTOMBS_L_IN_XLOCALE + +/* Support gcc earlier than 4.6.0 and MSVC */ +#undef HAVE__STATIC_ASSERT + +/* Avoid dependency on execinfo (requires extra library on musl-libc based systems, not supported on Windows) */ +#undef HAVE_EXECINFO_H +#undef HAVE_BACKTRACE_SYMBOLS + +/* Avoid dependency on hardware popcount instructions (POPQNTQ) on x86 */ +#undef HAVE_X86_64_POPCNTQ + +/* Avoid dependency on cpuid.h (only supported on x86 systems) */ +#undef HAVE__GET_CPUID + +/* Avoid CRC extension usage to ensure we are not architecture-dependent */ +#undef USE_ARMV8_CRC32C +#undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK + +/* Ensure we do not fail on systems that have strchrnul support (FreeBSD, NetBSD and newer glibc) */ +#include +#if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2)) +#define HAVE_STRCHRNUL +#endif + +/* 32-bit */ +#if defined(_WIN32) || __SIZEOF_POINTER__ == 4 +#undef ALIGNOF_DOUBLE +#define ALIGNOF_DOUBLE 4 +#undef ALIGNOF_LONG +#define ALIGNOF_LONG 4 +#define ALIGNOF_LONG_LONG_INT 4 +#undef ALIGNOF_PG_INT128_TYPE +#undef HAVE_LONG_INT_64 +#define HAVE_LONG_LONG_INT_64 1 +#undef INT64_MODIFIER +#define INT64_MODIFIER "ll" +#undef PG_INT128_TYPE +#undef PG_INT64_TYPE +#define PG_INT64_TYPE long long int +#undef SIZEOF_LONG +#define SIZEOF_LONG 4 +#undef SIZEOF_OFF_T +#define SIZEOF_OFF_T 4 +#undef SIZEOF_SIZE_T +#define SIZEOF_SIZE_T 4 +#undef SIZEOF_VOID_P +#define SIZEOF_VOID_P 4 +#endif + +/* Windows */ +#if defined(_WIN32) || defined(_WIN64) +#undef HAVE_COPYFILE +#undef HAVE_COPYFILE_H +#undef HAVE_DECL_F_FULLFSYNC +#define HAVE_DECL_F_FULLFSYNC 0 +#undef HAVE_DECL_PREADV +#define HAVE_DECL_PREADV 0 +#undef HAVE_DECL_PWRITEV +#define HAVE_DECL_PWRITEV 0 +#undef HAVE_DECL_STRLCAT +#define HAVE_DECL_STRLCAT 0 +#undef HAVE_DECL_STRLCPY +#define HAVE_DECL_STRLCPY 0 +#undef HAVE_GETIFADDRS +#undef HAVE_GETPEEREID +#undef HAVE_IFADDRS_H +#undef HAVE_INET_ATON +#undef HAVE_INT_OPTRESET +#undef HAVE_KQUEUE +#undef HAVE_LANGINFO_H +#undef HAVE_MEMSET_S +#undef HAVE_MKDTEMP +#undef HAVE_PTHREAD +#undef HAVE_PTHREAD_BARRIER_WAIT +#undef HAVE_PTHREAD_IS_THREADED_NP +#undef HAVE_PTHREAD_PRIO_INHERIT +#undef HAVE_STRERROR_R +#undef HAVE_STRLCAT +#undef HAVE_STRLCPY +#undef HAVE_STRSIGNAL +#undef HAVE_STRUCT_SOCKADDR_SA_LEN +#undef HAVE_STRUCT_TM_TM_ZONE +#undef HAVE_SYSLOG +#undef HAVE_SYS_EVENT_H +#undef HAVE_SYS_UCRED_H +#undef HAVE_TERMIOS_H +#undef HAVE_UNION_SEMUN +#undef HAVE_USELOCALE +#define HAVE__CONFIGTHREADLOCALE 1 +#undef STRERROR_R_INT +#undef USE_SYSV_SEMAPHORES +#undef USE_SYSV_SHARED_MEMORY +#define USE_WIN32_SEMAPHORES 1 +#define USE_WIN32_SHARED_MEMORY 1 +#undef PG_PRINTF_ATTRIBUTE +#if defined(__MINGW32__) || defined(__MINGW64__) +#define PG_PRINTF_ATTRIBUTE gnu_printf +#undef HAVE_MBSTOWCS_L +#undef HAVE_WCSTOMBS_L +#define HAVE_CRTDEFS_H 1 +#define HAVE_PTHREAD_BARRIER_WAIT 1 +#endif +#endif + +/* Microsoft Visual Studio Compiler */ +#ifdef _MSC_VER +#undef HAVE_COMPUTED_GOTO +#undef HAVE_GCC__ATOMIC_INT32_CAS +#undef HAVE_GCC__ATOMIC_INT64_CAS +#undef HAVE_GCC__SYNC_CHAR_TAS +#undef HAVE_GCC__SYNC_INT32_CAS +#undef HAVE_GCC__SYNC_INT32_TAS +#undef HAVE_GCC__SYNC_INT64_CAS +#undef HAVE_GETOPT +#undef HAVE_GETOPT_H +#undef HAVE_GETOPT_LONG +#undef HAVE_INTTYPES_H +#undef HAVE_INT_OPTERR +#undef HAVE_LIBM +#undef HAVE_STRINGS_H +#undef HAVE_STRUCT_OPTION +#undef HAVE_TYPEOF +#undef HAVE_VISIBILITY_ATTRIBUTE +#undef HAVE__BOOL +#undef HAVE__BUILTIN_BSWAP16 +#undef HAVE__BUILTIN_BSWAP32 +#undef HAVE__BUILTIN_BSWAP64 +#undef HAVE__BUILTIN_CLZ +#undef HAVE__BUILTIN_CONSTANT_P +#undef HAVE__BUILTIN_CTZ +#undef HAVE__BUILTIN_FRAME_ADDRESS +#undef HAVE__BUILTIN_OP_OVERFLOW +#undef HAVE__BUILTIN_POPCOUNT +#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#undef HAVE__BUILTIN_UNREACHABLE +#ifndef __cplusplus +#define inline __inline +#endif +#undef restrict +#define __thread __declspec( thread ) +#endif diff --git a/src/postgres/include/common/ip.h b/src/postgres/include/common/ip.h deleted file mode 100644 index 9f2ed5fe..00000000 --- a/src/postgres/include/common/ip.h +++ /dev/null @@ -1,33 +0,0 @@ -/*------------------------------------------------------------------------- - * - * ip.h - * Definitions for IPv6-aware network access. - * - * These definitions are used by both frontend and backend code. - * - * Copyright (c) 2003-2023, PostgreSQL Global Development Group - * - * src/include/common/ip.h - * - *------------------------------------------------------------------------- - */ -#ifndef IP_H -#define IP_H - -#include -#include - -#include "libpq/pqcomm.h" /* pgrminclude ignore */ - - -extern int pg_getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo *hintp, - struct addrinfo **result); -extern void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); - -extern int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags); - -#endif /* IP_H */ diff --git a/src/postgres/include/nodes/nodes.h b/src/postgres/include/nodes/nodes.h index 13ea9cae..4a32b2cf 100644 --- a/src/postgres/include/nodes/nodes.h +++ b/src/postgres/include/nodes/nodes.h @@ -161,7 +161,7 @@ typedef struct Node * Fortunately, this macro isn't recursive so we just define * a global variable for this purpose. */ -extern PGDLLIMPORT Node *newNodeMacroHolder; +extern PGDLLIMPORT __thread Node *newNodeMacroHolder; #define newNode(size, tag) \ ( \ diff --git a/src/postgres/include/pg_config.h b/src/postgres/include/pg_config.h index a08a0832..7b6303db 100644 --- a/src/postgres/include/pg_config.h +++ b/src/postgres/include/pg_config.h @@ -650,7 +650,7 @@ #define PG_VERSION_NUM 160001 /* A string containing the version number, platform, and C compiler */ -#define PG_VERSION_STR "PostgreSQL 16.1 on aarch64-apple-darwin22.3.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.202), 64-bit" +#define PG_VERSION_STR "PostgreSQL 16.1 (libpg_query)" /* Define to 1 to allow profiling output to be saved separately for each process. */ @@ -826,21 +826,35 @@ /* Define to how the compiler spells `typeof'. */ /* #undef typeof */ +/* This causes compatibility problems on some Linux distros, with "xlocale.h" not being available */ #undef HAVE_LOCALE_T #undef LOCALE_T_IN_XLOCALE #undef WCSTOMBS_L_IN_XLOCALE -#undef PG_INT128_TYPE + +/* Support gcc earlier than 4.6.0 and MSVC */ #undef HAVE__STATIC_ASSERT + +/* Avoid dependency on execinfo (requires extra library on musl-libc based systems, not supported on Windows) */ #undef HAVE_EXECINFO_H #undef HAVE_BACKTRACE_SYMBOLS + +/* Avoid dependency on hardware popcount instructions (POPQNTQ) on x86 */ #undef HAVE_X86_64_POPCNTQ + +/* Avoid dependency on cpuid.h (only supported on x86 systems) */ #undef HAVE__GET_CPUID + +/* Avoid CRC extension usage to ensure we are not architecture-dependent */ #undef USE_ARMV8_CRC32C #undef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK + +/* Ensure we do not fail on systems that have strchrnul support (FreeBSD, NetBSD and newer glibc) */ #include #if defined(__FreeBSD__) || defined(__NetBSD__) || (defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 38) || __GLIBC__ > 2)) #define HAVE_STRCHRNUL #endif + +/* 32-bit */ #if defined(_WIN32) || __SIZEOF_POINTER__ == 4 #undef ALIGNOF_DOUBLE #define ALIGNOF_DOUBLE 4 @@ -857,26 +871,103 @@ #define PG_INT64_TYPE long long int #undef SIZEOF_LONG #define SIZEOF_LONG 4 +#undef SIZEOF_OFF_T +#define SIZEOF_OFF_T 4 #undef SIZEOF_SIZE_T #define SIZEOF_SIZE_T 4 #undef SIZEOF_VOID_P #define SIZEOF_VOID_P 4 #endif + +/* Windows */ #if defined(_WIN32) || defined(_WIN64) -#define WIN32 1 -#define __thread __declspec( thread ) +#undef HAVE_COPYFILE +#undef HAVE_COPYFILE_H +#undef HAVE_DECL_F_FULLFSYNC +#define HAVE_DECL_F_FULLFSYNC 0 +#undef HAVE_DECL_PREADV +#define HAVE_DECL_PREADV 0 +#undef HAVE_DECL_PWRITEV +#define HAVE_DECL_PWRITEV 0 +#undef HAVE_DECL_STRLCAT +#define HAVE_DECL_STRLCAT 0 +#undef HAVE_DECL_STRLCPY +#define HAVE_DECL_STRLCPY 0 +#undef HAVE_GETIFADDRS +#undef HAVE_GETPEEREID +#undef HAVE_IFADDRS_H +#undef HAVE_INET_ATON +#undef HAVE_INT_OPTRESET +#undef HAVE_KQUEUE +#undef HAVE_LANGINFO_H +#undef HAVE_MEMSET_S +#undef HAVE_MKDTEMP +#undef HAVE_PTHREAD +#undef HAVE_PTHREAD_BARRIER_WAIT +#undef HAVE_PTHREAD_IS_THREADED_NP +#undef HAVE_PTHREAD_PRIO_INHERIT +#undef HAVE_STRERROR_R +#undef HAVE_STRLCAT +#undef HAVE_STRLCPY +#undef HAVE_STRSIGNAL +#undef HAVE_STRUCT_SOCKADDR_SA_LEN +#undef HAVE_STRUCT_TM_TM_ZONE +#undef HAVE_SYSLOG +#undef HAVE_SYS_EVENT_H +#undef HAVE_SYS_UCRED_H +#undef HAVE_TERMIOS_H +#undef HAVE_UNION_SEMUN +#undef HAVE_USELOCALE +#define HAVE__CONFIGTHREADLOCALE 1 +#undef STRERROR_R_INT +#undef USE_SYSV_SEMAPHORES +#undef USE_SYSV_SHARED_MEMORY +#define USE_WIN32_SEMAPHORES 1 +#define USE_WIN32_SHARED_MEMORY 1 +#undef PG_PRINTF_ATTRIBUTE +#if defined(__MINGW32__) || defined(__MINGW64__) +#define PG_PRINTF_ATTRIBUTE gnu_printf +#undef HAVE_MBSTOWCS_L +#undef HAVE_WCSTOMBS_L +#define HAVE_CRTDEFS_H 1 +#define HAVE_PTHREAD_BARRIER_WAIT 1 +#endif +#endif + +/* Microsoft Visual Studio Compiler */ +#ifdef _MSC_VER +#undef HAVE_COMPUTED_GOTO +#undef HAVE_GCC__ATOMIC_INT32_CAS +#undef HAVE_GCC__ATOMIC_INT64_CAS +#undef HAVE_GCC__SYNC_CHAR_TAS +#undef HAVE_GCC__SYNC_INT32_CAS +#undef HAVE_GCC__SYNC_INT32_TAS +#undef HAVE_GCC__SYNC_INT64_CAS +#undef HAVE_GETOPT +#undef HAVE_GETOPT_H +#undef HAVE_GETOPT_LONG +#undef HAVE_INTTYPES_H +#undef HAVE_INT_OPTERR +#undef HAVE_LIBM #undef HAVE_STRINGS_H +#undef HAVE_STRUCT_OPTION +#undef HAVE_TYPEOF #undef HAVE_VISIBILITY_ATTRIBUTE -#undef HAVE__BUILTIN_CONSTANT_P -#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P -#undef HAVE__BUILTIN_UNREACHABLE +#undef HAVE__BOOL +#undef HAVE__BUILTIN_BSWAP16 +#undef HAVE__BUILTIN_BSWAP32 +#undef HAVE__BUILTIN_BSWAP64 #undef HAVE__BUILTIN_CLZ +#undef HAVE__BUILTIN_CONSTANT_P #undef HAVE__BUILTIN_CTZ +#undef HAVE__BUILTIN_FRAME_ADDRESS +#undef HAVE__BUILTIN_OP_OVERFLOW #undef HAVE__BUILTIN_POPCOUNT -#undef HAVE_TYPEOF -#undef HAVE_GETOPT_H -#undef HAVE_SYSLOG -#undef HAVE_PTHREAD -#undef HAVE_PTHREAD_IS_THREADED_NP -#undef HAVE_STRERROR_R +#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#undef HAVE__BUILTIN_UNREACHABLE +#ifndef __cplusplus +#define inline __inline +#endif +#undef restrict +#define __thread __declspec( thread ) #endif diff --git a/src/postgres/include/pg_config_os.h b/src/postgres/include/pg_config_os.h index 15fb69d6..9348fa62 100644 --- a/src/postgres/include/pg_config_os.h +++ b/src/postgres/include/pg_config_os.h @@ -1,8 +1,4 @@ -/* src/include/port/darwin.h */ - -#define __darwin__ 1 - -#if HAVE_DECL_F_FULLFSYNC /* not present before macOS 10.3 */ -#define HAVE_FSYNC_WRITETHROUGH - +#if defined(_WIN32) || defined(_WIN64) +#include "port/win32.h" +#include #endif diff --git a/src/postgres/include/port/win32_port.h b/src/postgres/include/port/win32_port.h index 954e272b..b957d5c5 100644 --- a/src/postgres/include/port/win32_port.h +++ b/src/postgres/include/port/win32_port.h @@ -63,8 +63,6 @@ #include #include -#undef ERROR - #undef small #include #include diff --git a/src/postgres/include/postmaster/auxprocess.h b/src/postgres/include/postmaster/auxprocess.h deleted file mode 100644 index 5c2d6527..00000000 --- a/src/postgres/include/postmaster/auxprocess.h +++ /dev/null @@ -1,20 +0,0 @@ -/*------------------------------------------------------------------------- - * auxprocess.h - * include file for functions related to auxiliary processes. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/postmaster/auxprocess.h - *------------------------------------------------------------------------- - */ -#ifndef AUXPROCESS_H -#define AUXPROCESS_H - -#include "miscadmin.h" - -extern void AuxiliaryProcessMain(AuxProcType auxtype) pg_attribute_noreturn(); - -#endif /* AUXPROCESS_H */ diff --git a/src/postgres/include/postmaster/fork_process.h b/src/postgres/include/postmaster/fork_process.h deleted file mode 100644 index 12decc81..00000000 --- a/src/postgres/include/postmaster/fork_process.h +++ /dev/null @@ -1,17 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fork_process.h - * Exports from postmaster/fork_process.c. - * - * Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * src/include/postmaster/fork_process.h - * - *------------------------------------------------------------------------- - */ -#ifndef FORK_PROCESS_H -#define FORK_PROCESS_H - -extern pid_t fork_process(void); - -#endif /* FORK_PROCESS_H */ diff --git a/src/postgres/include/postmaster/postmaster.h b/src/postgres/include/postmaster/postmaster.h index cdee1968..3b3889c5 100644 --- a/src/postgres/include/postmaster/postmaster.h +++ b/src/postgres/include/postmaster/postmaster.h @@ -22,7 +22,7 @@ extern PGDLLIMPORT int Unix_socket_permissions; extern PGDLLIMPORT char *Unix_socket_group; extern PGDLLIMPORT char *Unix_socket_directories; extern PGDLLIMPORT char *ListenAddresses; -extern PGDLLIMPORT __thread bool ClientAuthInProgress; +extern PGDLLIMPORT bool ClientAuthInProgress; extern PGDLLIMPORT int PreAuthDelay; extern PGDLLIMPORT int AuthenticationTimeout; extern PGDLLIMPORT bool Log_connections; diff --git a/src/postgres/include/utils/guc.h b/src/postgres/include/utils/guc.h index 2355fc2d..2025039b 100644 --- a/src/postgres/include/utils/guc.h +++ b/src/postgres/include/utils/guc.h @@ -257,7 +257,7 @@ extern PGDLLIMPORT int log_parameter_max_length; extern PGDLLIMPORT int log_parameter_max_length_on_error; extern PGDLLIMPORT int log_min_error_statement; extern PGDLLIMPORT __thread int log_min_messages; -extern PGDLLIMPORT __thread int client_min_messages; +extern PGDLLIMPORT int client_min_messages; extern PGDLLIMPORT int log_min_duration_sample; extern PGDLLIMPORT int log_min_duration_statement; extern PGDLLIMPORT int log_temp_files; diff --git a/src/postgres/include/utils/pidfile.h b/src/postgres/include/utils/pidfile.h deleted file mode 100644 index 1393a534..00000000 --- a/src/postgres/include/utils/pidfile.h +++ /dev/null @@ -1,56 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pidfile.h - * Declarations describing the data directory lock file (postmaster.pid) - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/utils/pidfile.h - * - *------------------------------------------------------------------------- - */ -#ifndef UTILS_PIDFILE_H -#define UTILS_PIDFILE_H - -/* - * As of Postgres 10, the contents of the data-directory lock file are: - * - * line # - * 1 postmaster PID (or negative of a standalone backend's PID) - * 2 data directory path - * 3 postmaster start timestamp (time_t representation) - * 4 port number - * 5 first Unix socket directory path (empty if none) - * 6 first listen_address (IP address or "*"; empty if no TCP port) - * 7 shared memory key (empty on Windows) - * 8 postmaster status (see values below) - * - * Lines 6 and up are added via AddToDataDirLockFile() after initial file - * creation; also, line 5 is initially empty and is changed after the first - * Unix socket is opened. Onlookers should not assume that lines 4 and up - * are filled in any particular order. - * - * Socket lock file(s), if used, have the same contents as lines 1-5, with - * line 5 being their own directory. - */ -#define LOCK_FILE_LINE_PID 1 -#define LOCK_FILE_LINE_DATA_DIR 2 -#define LOCK_FILE_LINE_START_TIME 3 -#define LOCK_FILE_LINE_PORT 4 -#define LOCK_FILE_LINE_SOCKET_DIR 5 -#define LOCK_FILE_LINE_LISTEN_ADDR 6 -#define LOCK_FILE_LINE_SHMEM_KEY 7 -#define LOCK_FILE_LINE_PM_STATUS 8 - -/* - * The PM_STATUS line may contain one of these values. All these strings - * must be the same length, per comments for AddToDataDirLockFile(). - * We pad with spaces as needed to make that true. - */ -#define PM_STATUS_STARTING "starting" /* still starting up */ -#define PM_STATUS_STOPPING "stopping" /* in shutdown sequence */ -#define PM_STATUS_READY "ready " /* ready for connections */ -#define PM_STATUS_STANDBY "standby " /* up, won't accept connections */ - -#endif /* UTILS_PIDFILE_H */ diff --git a/src/postgres/src_backend_nodes_nodes.c b/src/postgres/src_backend_nodes_nodes.c index 1913a4bd..69d302ca 100644 --- a/src/postgres/src_backend_nodes_nodes.c +++ b/src/postgres/src_backend_nodes_nodes.c @@ -1,3 +1,9 @@ +/*-------------------------------------------------------------------- + * Symbols referenced in this file: + * - newNodeMacroHolder + *-------------------------------------------------------------------- + */ + /*------------------------------------------------------------------------- * * nodes.c @@ -28,4 +34,5 @@ * loadable module being loaded into a GCC-built backend. */ -Node *newNodeMacroHolder; +__thread Node *newNodeMacroHolder; + diff --git a/src/postgres/src_backend_postmaster_postmaster.c b/src/postgres/src_backend_postmaster_postmaster.c deleted file mode 100644 index 4dab5791..00000000 --- a/src/postgres/src_backend_postmaster_postmaster.c +++ /dev/null @@ -1,1471 +0,0 @@ -/*-------------------------------------------------------------------- - * Symbols referenced in this file: - * - ClientAuthInProgress - *-------------------------------------------------------------------- - */ - -/*------------------------------------------------------------------------- - * - * postmaster.c - * This program acts as a clearing house for requests to the - * POSTGRES system. Frontend programs send a startup message - * to the Postmaster and the postmaster uses the info in the - * message to setup a backend process. - * - * The postmaster also manages system-wide operations such as - * startup and shutdown. The postmaster itself doesn't do those - * operations, mind you --- it just forks off a subprocess to do them - * at the right times. It also takes care of resetting the system - * if a backend crashes. - * - * The postmaster process creates the shared memory and semaphore - * pools during startup, but as a rule does not touch them itself. - * In particular, it is not a member of the PGPROC array of backends - * and so it cannot participate in lock-manager operations. Keeping - * the postmaster away from shared memory operations makes it simpler - * and more reliable. The postmaster is almost always able to recover - * from crashes of individual backends by resetting shared memory; - * if it did much with shared memory then it would be prone to crashing - * along with the backends. - * - * When a request message is received, we now fork() immediately. - * The child process performs authentication of the request, and - * then becomes a backend if successful. This allows the auth code - * to be written in a simple single-threaded style (as opposed to the - * crufty "poor man's multitasking" code that used to be needed). - * More importantly, it ensures that blockages in non-multithreaded - * libraries like SSL or PAM cannot cause denial of service to other - * clients. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/postmaster/postmaster.c - * - * NOTES - * - * Initialization: - * The Postmaster sets up shared memory data structures - * for the backends. - * - * Synchronization: - * The Postmaster shares memory with the backends but should avoid - * touching shared memory, so as not to become stuck if a crashing - * backend screws up locks or shared memory. Likewise, the Postmaster - * should never block on messages from frontend clients. - * - * Garbage Collection: - * The Postmaster cleans up after backends if they have an emergency - * exit and/or core dump. - * - * Error Reporting: - * Use write_stderr() only for reporting "interactive" errors - * (essentially, bogus arguments on the command line). Once the - * postmaster is launched, use ereport(). - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef USE_BONJOUR -#include -#endif - -#ifdef USE_SYSTEMD -#include -#endif - -#ifdef HAVE_PTHREAD_IS_THREADED_NP -#include -#endif - -#include "access/transam.h" -#include "access/xlog.h" -#include "access/xlogrecovery.h" -#include "catalog/pg_control.h" -#include "common/file_perm.h" -#include "common/ip.h" -#include "common/pg_prng.h" -#include "common/string.h" -#include "lib/ilist.h" -#include "libpq/auth.h" -#include "libpq/libpq.h" -#include "libpq/pqformat.h" -#include "libpq/pqsignal.h" -#include "nodes/queryjumble.h" -#include "pg_getopt.h" -#include "pgstat.h" -#include "port/pg_bswap.h" -#include "postmaster/autovacuum.h" -#include "postmaster/auxprocess.h" -#include "postmaster/bgworker_internals.h" -#include "postmaster/fork_process.h" -#include "postmaster/interrupt.h" -#include "postmaster/pgarch.h" -#include "postmaster/postmaster.h" -#include "postmaster/syslogger.h" -#include "replication/logicallauncher.h" -#include "replication/walsender.h" -#include "storage/fd.h" -#include "storage/ipc.h" -#include "storage/pg_shmem.h" -#include "storage/pmsignal.h" -#include "storage/proc.h" -#include "tcop/tcopprot.h" -#include "utils/builtins.h" -#include "utils/datetime.h" -#include "utils/memutils.h" -#include "utils/pidfile.h" -#include "utils/ps_status.h" -#include "utils/timeout.h" -#include "utils/timestamp.h" -#include "utils/varlena.h" - -#ifdef EXEC_BACKEND -#include "storage/spin.h" -#endif - - -/* - * Possible types of a backend. Beyond being the possible bkend_type values in - * struct bkend, these are OR-able request flag bits for SignalSomeChildren() - * and CountChildren(). - */ -#define BACKEND_TYPE_NORMAL 0x0001 /* normal backend */ -#define BACKEND_TYPE_AUTOVAC 0x0002 /* autovacuum worker process */ -#define BACKEND_TYPE_WALSND 0x0004 /* walsender process */ -#define BACKEND_TYPE_BGWORKER 0x0008 /* bgworker process */ -#define BACKEND_TYPE_ALL 0x000F /* OR of all the above */ - -/* - * List of active backends (or child processes anyway; we don't actually - * know whether a given child has become a backend or is still in the - * authorization phase). This is used mainly to keep track of how many - * children we have and send them appropriate signals when necessary. - * - * As shown in the above set of backend types, this list includes not only - * "normal" client sessions, but also autovacuum workers, walsenders, and - * background workers. (Note that at the time of launch, walsenders are - * labeled BACKEND_TYPE_NORMAL; we relabel them to BACKEND_TYPE_WALSND - * upon noticing they've changed their PMChildFlags entry. Hence that check - * must be done before any operation that needs to distinguish walsenders - * from normal backends.) - * - * Also, "dead_end" children are in it: these are children launched just for - * the purpose of sending a friendly rejection message to a would-be client. - * We must track them because they are attached to shared memory, but we know - * they will never become live backends. dead_end children are not assigned a - * PMChildSlot. dead_end children have bkend_type NORMAL. - * - * "Special" children such as the startup, bgwriter and autovacuum launcher - * tasks are not in this list. They are tracked via StartupPID and other - * pid_t variables below. (Thus, there can't be more than one of any given - * "special" child process type. We use BackendList entries for any child - * process there can be more than one of.) - */ -typedef struct bkend -{ - pid_t pid; /* process id of backend */ - int32 cancel_key; /* cancel key for cancels for this backend */ - int child_slot; /* PMChildSlot for this backend, if any */ - int bkend_type; /* child process flavor, see above */ - bool dead_end; /* is it going to send an error and quit? */ - bool bgworker_notify; /* gets bgworker start/stop notifications */ - dlist_node elem; /* list link in BackendList */ -} Backend; - - - -#ifdef EXEC_BACKEND - -#endif - - - - - -/* The socket number we are listening for connections on */ - - -/* The directory names for Unix socket(s) */ - - -/* The TCP listen address(es) */ - - -/* - * SuperuserReservedConnections is the number of backends reserved for - * superuser use, and ReservedConnections is the number of backends reserved - * for use by roles with privileges of the pg_use_reserved_connections - * predefined role. These are taken out of the pool of MaxConnections backend - * slots, so the number of backend slots available for roles that are neither - * superuser nor have privileges of pg_use_reserved_connections is - * (MaxConnections - SuperuserReservedConnections - ReservedConnections). - * - * If the number of remaining slots is less than or equal to - * SuperuserReservedConnections, only superusers can make new connections. If - * the number of remaining slots is greater than SuperuserReservedConnections - * but less than or equal to - * (SuperuserReservedConnections + ReservedConnections), only superusers and - * roles with privileges of pg_use_reserved_connections can make new - * connections. Note that pre-existing superuser and - * pg_use_reserved_connections connections don't count against the limits. - */ - - - -/* The socket(s) we're listening to. */ -#define MAXLISTEN 64 - - -/* still more option variables */ - - - - - - /* for ps display and logging */ - - - - - - - - - - -/* PIDs of special child processes; 0 when not running */ - - - - - - - - - -/* Startup process's status */ -typedef enum -{ - STARTUP_NOT_RUNNING, - STARTUP_RUNNING, - STARTUP_SIGNALED, /* we sent it a SIGQUIT or SIGKILL */ - STARTUP_CRASHED -} StartupStatusEnum; - - - -/* Startup/shutdown state */ -#define NoShutdown 0 -#define SmartShutdown 1 -#define FastShutdown 2 -#define ImmediateShutdown 3 - - - - /* T if recovering from backend crash */ - -/* - * We use a simple state machine to control startup, shutdown, and - * crash recovery (which is rather like shutdown followed by startup). - * - * After doing all the postmaster initialization work, we enter PM_STARTUP - * state and the startup process is launched. The startup process begins by - * reading the control file and other preliminary initialization steps. - * In a normal startup, or after crash recovery, the startup process exits - * with exit code 0 and we switch to PM_RUN state. However, archive recovery - * is handled specially since it takes much longer and we would like to support - * hot standby during archive recovery. - * - * When the startup process is ready to start archive recovery, it signals the - * postmaster, and we switch to PM_RECOVERY state. The background writer and - * checkpointer are launched, while the startup process continues applying WAL. - * If Hot Standby is enabled, then, after reaching a consistent point in WAL - * redo, startup process signals us again, and we switch to PM_HOT_STANDBY - * state and begin accepting connections to perform read-only queries. When - * archive recovery is finished, the startup process exits with exit code 0 - * and we switch to PM_RUN state. - * - * Normal child backends can only be launched when we are in PM_RUN or - * PM_HOT_STANDBY state. (connsAllowed can also restrict launching.) - * In other states we handle connection requests by launching "dead_end" - * child processes, which will simply send the client an error message and - * quit. (We track these in the BackendList so that we can know when they - * are all gone; this is important because they're still connected to shared - * memory, and would interfere with an attempt to destroy the shmem segment, - * possibly leading to SHMALL failure when we try to make a new one.) - * In PM_WAIT_DEAD_END state we are waiting for all the dead_end children - * to drain out of the system, and therefore stop accepting connection - * requests at all until the last existing child has quit (which hopefully - * will not be very long). - * - * Notice that this state variable does not distinguish *why* we entered - * states later than PM_RUN --- Shutdown and FatalError must be consulted - * to find that out. FatalError is never true in PM_RECOVERY, PM_HOT_STANDBY, - * or PM_RUN states, nor in PM_SHUTDOWN states (because we don't enter those - * states when trying to recover from a crash). It can be true in PM_STARTUP - * state, because we don't clear it until we've successfully started WAL redo. - */ -typedef enum -{ - PM_INIT, /* postmaster starting */ - PM_STARTUP, /* waiting for startup subprocess */ - PM_RECOVERY, /* in archive recovery mode */ - PM_HOT_STANDBY, /* in hot standby mode */ - PM_RUN, /* normal "database is alive" state */ - PM_STOP_BACKENDS, /* need to stop remaining backends */ - PM_WAIT_BACKENDS, /* waiting for live backends to exit */ - PM_SHUTDOWN, /* waiting for checkpointer to do shutdown - * ckpt */ - PM_SHUTDOWN_2, /* waiting for archiver and walsenders to - * finish */ - PM_WAIT_DEAD_END, /* waiting for dead_end children to exit */ - PM_NO_CHILDREN /* all important children have exited */ -} PMState; - - - -/* - * While performing a "smart shutdown", we restrict new connections but stay - * in PM_RUN or PM_HOT_STANDBY state until all the client backends are gone. - * connsAllowed is a sub-state indicator showing the active restriction. - * It is of no interest unless pmState is PM_RUN or PM_HOT_STANDBY. - */ - - -/* Start time of SIGKILL timeout during immediate shutdown or child crash */ -/* Zero means timeout is not running */ - - -/* Length of said timeout */ -#define SIGKILL_CHILDREN_AFTER_SECS 5 - - /* T if we've reached PM_RUN */ - -__thread bool ClientAuthInProgress = false; - /* T during new-client - * authentication */ - - /* stderr redirected for syslogger? */ - -/* received START_AUTOVAC_LAUNCHER signal */ - - -/* the launcher needs to be signaled to communicate some condition */ - - -/* received START_WALRECEIVER signal */ - - -/* set when there's a worker that needs to be started up */ - - - -/* set when signals arrive */ - - - - - - - -/* event multiplexing object */ - - -#ifdef USE_SSL -/* Set when and if SSL has been initialized properly */ -static bool LoadedSSL = false; -#endif - -#ifdef USE_BONJOUR -static DNSServiceRef bonjour_sdref = NULL; -#endif - -/* - * postmaster.c - function prototypes - */ -static void CloseServerPorts(int status, Datum arg); -static void unlink_external_pid_file(int status, Datum arg); -static void getInstallationPaths(const char *argv0); -static void checkControlFile(void); -static Port *ConnCreate(int serverFd); -static void ConnFree(Port *port); -static void handle_pm_pmsignal_signal(SIGNAL_ARGS); -static void handle_pm_child_exit_signal(SIGNAL_ARGS); -static void handle_pm_reload_request_signal(SIGNAL_ARGS); -static void handle_pm_shutdown_request_signal(SIGNAL_ARGS); -static void process_pm_pmsignal(void); -static void process_pm_child_exit(void); -static void process_pm_reload_request(void); -static void process_pm_shutdown_request(void); -static void process_startup_packet_die(SIGNAL_ARGS); -static void dummy_handler(SIGNAL_ARGS); -static void StartupPacketTimeoutHandler(void); -static void CleanupBackend(int pid, int exitstatus); -static bool CleanupBackgroundWorker(int pid, int exitstatus); -static void HandleChildCrash(int pid, int exitstatus, const char *procname); -static void LogChildExit(int lev, const char *procname, - int pid, int exitstatus); -static void PostmasterStateMachine(void); -static void BackendInitialize(Port *port); -static void BackendRun(Port *port) pg_attribute_noreturn(); -static void ExitPostmaster(int status) pg_attribute_noreturn(); -static int ServerLoop(void); -static int BackendStartup(Port *port); -static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done); -static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options); -static void processCancelRequest(Port *port, void *pkt); -static void report_fork_failure_to_client(Port *port, int errnum); -static CAC_state canAcceptConnections(int backend_type); -static bool RandomCancelKey(int32 *cancel_key); -static void signal_child(pid_t pid, int signal); -static void sigquit_child(pid_t pid); -static bool SignalSomeChildren(int signal, int target); -static void TerminateChildren(int signal); - -#define SignalChildren(sig) SignalSomeChildren(sig, BACKEND_TYPE_ALL) - -static int CountChildren(int target); -static bool assign_backendlist_entry(RegisteredBgWorker *rw); -static void maybe_start_bgworkers(void); -static bool CreateOptsFile(int argc, char *argv[], char *fullprogname); -static pid_t StartChildProcess(AuxProcType type); -static void StartAutovacuumWorker(void); -static void MaybeStartWalReceiver(void); -static void InitPostmasterDeathWatchHandle(void); - -/* - * Archiver is allowed to start up at the current postmaster state? - * - * If WAL archiving is enabled always, we are allowed to start archiver - * even during recovery. - */ -#define PgArchStartupAllowed() \ - (((XLogArchivingActive() && pmState == PM_RUN) || \ - (XLogArchivingAlways() && \ - (pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY))) && \ - PgArchCanRestart()) - -#ifdef EXEC_BACKEND - -#ifdef WIN32 -#define WNOHANG 0 /* ignored, so any integer value will do */ - -static pid_t waitpid(pid_t pid, int *exitstatus, int options); -static void WINAPI pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired); - -static HANDLE win32ChildQueue; - -typedef struct -{ - HANDLE waitHandle; - HANDLE procHandle; - DWORD procId; -} win32_deadchild_waitinfo; -#endif /* WIN32 */ - -static pid_t backend_forkexec(Port *port); -static pid_t internal_forkexec(int argc, char *argv[], Port *port); - -/* Type for a socket that can be inherited to a client process */ -#ifdef WIN32 -typedef struct -{ - SOCKET origsocket; /* Original socket value, or PGINVALID_SOCKET - * if not a socket */ - WSAPROTOCOL_INFO wsainfo; -} InheritableSocket; -#else -typedef int InheritableSocket; -#endif - -/* - * Structure contains all variables passed to exec:ed backends - */ -typedef struct -{ - Port port; - InheritableSocket portsocket; - char DataDir[MAXPGPATH]; - pgsocket ListenSocket[MAXLISTEN]; - int32 MyCancelKey; - int MyPMChildSlot; -#ifndef WIN32 - unsigned long UsedShmemSegID; -#else - void *ShmemProtectiveRegion; - HANDLE UsedShmemSegID; -#endif - void *UsedShmemSegAddr; - slock_t *ShmemLock; - VariableCache ShmemVariableCache; - Backend *ShmemBackendArray; -#ifndef HAVE_SPINLOCKS - PGSemaphore *SpinlockSemaArray; -#endif - int NamedLWLockTrancheRequests; - NamedLWLockTranche *NamedLWLockTrancheArray; - LWLockPadded *MainLWLockArray; - slock_t *ProcStructLock; - PROC_HDR *ProcGlobal; - PGPROC *AuxiliaryProcs; - PGPROC *PreparedXactProcs; - PMSignalData *PMSignalState; - pid_t PostmasterPid; - TimestampTz PgStartTime; - TimestampTz PgReloadTime; - pg_time_t first_syslogger_file_time; - bool redirection_done; - bool IsBinaryUpgrade; - bool query_id_enabled; - int max_safe_fds; - int MaxBackends; -#ifdef WIN32 - HANDLE PostmasterHandle; - HANDLE initial_signal_pipe; - HANDLE syslogPipe[2]; -#else - int postmaster_alive_fds[2]; - int syslogPipe[2]; -#endif - char my_exec_path[MAXPGPATH]; - char pkglib_path[MAXPGPATH]; -} BackendParameters; - -static void read_backend_variables(char *id, Port *port); -static void restore_backend_variables(BackendParameters *param, Port *port); - -#ifndef WIN32 -static bool save_backend_variables(BackendParameters *param, Port *port); -#else -static bool save_backend_variables(BackendParameters *param, Port *port, - HANDLE childProcess, pid_t childPid); -#endif - -static void ShmemBackendArrayAdd(Backend *bn); -static void ShmemBackendArrayRemove(Backend *bn); -#endif /* EXEC_BACKEND */ - -#define StartupDataBase() StartChildProcess(StartupProcess) -#define StartArchiver() StartChildProcess(ArchiverProcess) -#define StartBackgroundWriter() StartChildProcess(BgWriterProcess) -#define StartCheckpointer() StartChildProcess(CheckpointerProcess) -#define StartWalWriter() StartChildProcess(WalWriterProcess) -#define StartWalReceiver() StartChildProcess(WalReceiverProcess) - -/* Macros to check exit status of a child process */ -#define EXIT_STATUS_0(st) ((st) == 0) -#define EXIT_STATUS_1(st) (WIFEXITED(st) && WEXITSTATUS(st) == 1) -#define EXIT_STATUS_3(st) (WIFEXITED(st) && WEXITSTATUS(st) == 3) - -#ifndef WIN32 -/* - * File descriptors for pipe used to monitor if postmaster is alive. - * First is POSTMASTER_FD_WATCH, second is POSTMASTER_FD_OWN. - */ - -#else -/* Process handle of postmaster used for the same purpose on Windows */ -HANDLE PostmasterHandle; -#endif - -/* - * Postmaster main entry point - */ -#ifdef WIN32 -#endif -#ifdef SIGTTIN -#endif -#ifdef SIGTTOU -#endif -#ifdef SIGXFSZ -#endif -#ifdef HAVE_INT_OPTRESET -#endif -#ifdef USE_SSL -#endif -#ifdef WIN32 -#endif -#ifdef EXEC_BACKEND -#endif -#ifdef USE_BONJOUR -#endif -#ifdef HAVE_PTHREAD_IS_THREADED_NP -#endif - - -/* - * on_proc_exit callback to close server's listen sockets - */ - - -/* - * on_proc_exit callback to delete external_pid_file - */ - - - -/* - * Compute and check the directory paths to files that are part of the - * installation (as deduced from the postgres executable's own location) - */ -#ifdef EXEC_BACKEND -#endif - -/* - * Check that pg_control exists in the correct location in the data directory. - * - * No attempt is made to validate the contents of pg_control here. This is - * just a sanity check to see if we are looking at a real data directory. - */ - - -/* - * Determine how long should we let ServerLoop sleep, in milliseconds. - * - * In normal conditions we wait at most one minute, to ensure that the other - * background tasks handled by ServerLoop get done even when no requests are - * arriving. However, if there are background workers waiting to be started, - * we don't actually sleep so that they are quickly serviced. Other exception - * cases are as shown in the code. - */ - - -/* - * Activate or deactivate notifications of server socket events. Since we - * don't currently have a way to remove events from an existing WaitEventSet, - * we'll just destroy and recreate the whole thing. This is called during - * shutdown so we can wait for backends to exit without accepting new - * connections, and during crash reinitialization when we need to start - * listening for new connections again. The WaitEventSet will be freed in fork - * children by ClosePostmasterPorts(). - */ - - -/* - * Main idle loop of postmaster - */ -#ifdef HAVE_PTHREAD_IS_THREADED_NP -#endif - -/* - * Read a client's startup packet and do something according to it. - * - * Returns STATUS_OK or STATUS_ERROR, or might call ereport(FATAL) and - * not return at all. - * - * (Note that ereport(FATAL) stuff is sent to the client, so only use it - * if that's what you want. Return STATUS_ERROR if you don't want to - * send anything to the client, which would typically be appropriate - * if we detect a communications failure.) - * - * Set ssl_done and/or gss_done when negotiation of an encrypted layer - * (currently, TLS or GSSAPI) is completed. A successful negotiation of either - * encryption layer sets both flags, but a rejected negotiation sets only the - * flag for that layer, since the client may wish to try the other one. We - * should make no assumption here about the order in which the client may make - * requests. - */ -#ifdef USE_SSL -#else -#endif -#ifdef USE_SSL -#endif -#ifdef ENABLE_GSS -#endif -#ifdef ENABLE_GSS -#endif - -/* - * Send a NegotiateProtocolVersion to the client. This lets the client know - * that they have requested a newer minor protocol version than we are able - * to speak. We'll speak the highest version we know about; the client can, - * of course, abandon the connection if that's a problem. - * - * We also include in the response a list of protocol options we didn't - * understand. This allows clients to include optional parameters that might - * be present either in newer protocol versions or third-party protocol - * extensions without fear of having to reconnect if those options are not - * understood, while at the same time making certain that the client is aware - * of which options were actually accepted. - */ - - -/* - * The client has sent a cancel request packet, not a normal - * start-a-new-connection packet. Perform the necessary processing. - * Nothing is sent back to the client. - */ -#ifndef EXEC_BACKEND -#else -#endif -#ifndef EXEC_BACKEND -#else -#endif -#ifndef EXEC_BACKEND /* make GNU Emacs 26.1 see brace balance */ -#else -#endif - -/* - * canAcceptConnections --- check to see if database state allows connections - * of the specified type. backend_type can be BACKEND_TYPE_NORMAL, - * BACKEND_TYPE_AUTOVAC, or BACKEND_TYPE_BGWORKER. (Note that we don't yet - * know whether a NORMAL connection might turn into a walsender.) - */ - - - -/* - * ConnCreate -- create a local connection data structure - * - * Returns NULL on failure, other than out-of-memory which is fatal. - */ - - - -/* - * ConnFree -- free a local connection data structure - * - * Caller has already closed the socket if any, so there's not much - * to do here. - */ - - - -/* - * ClosePostmasterPorts -- close all the postmaster's open sockets - * - * This is called during child process startup to release file descriptors - * that are not needed by that child process. The postmaster still has - * them open, of course. - * - * Note: we pass am_syslogger as a boolean because we don't want to set - * the global variable yet when this is called. - */ -#ifndef WIN32 -#endif -#ifndef WIN32 -#else -#endif -#ifdef USE_BONJOUR -#endif - - -/* - * InitProcessGlobals -- set MyProcPid, MyStartTime[stamp], random seeds - * - * Called early in the postmaster and every backend. - */ -#ifndef WIN32 -#endif - -/* - * Child processes use SIGUSR1 to notify us of 'pmsignals'. pg_ctl uses - * SIGUSR1 to ask postmaster to check for logrotate and promote files. - */ - - -/* - * pg_ctl uses SIGHUP to request a reload of the configuration files. - */ - - -/* - * Re-read config files, and tell children to do same. - */ -#ifdef USE_SSL -#endif -#ifdef EXEC_BACKEND -#endif - -/* - * pg_ctl uses SIGTERM, SIGINT and SIGQUIT to request different types of - * shutdown. - */ - - -/* - * Process shutdown request. - */ -#ifdef USE_SYSTEMD -#endif -#ifdef USE_SYSTEMD -#endif -#ifdef USE_SYSTEMD -#endif - - - -/* - * Cleanup after a child process dies. - */ -#ifdef USE_SYSTEMD -#endif - -/* - * Scan the bgworkers list and see if the given PID (which has just stopped - * or crashed) is in it. Handle its shutdown if so, and return true. If not a - * bgworker, return false. - * - * This is heavily based on CleanupBackend. One important difference is that - * we don't know yet that the dying process is a bgworker, so we must be silent - * until we're sure it is. - */ -#ifdef WIN32 -#endif -#ifdef EXEC_BACKEND -#endif - -/* - * CleanupBackend -- cleanup after terminated backend. - * - * Remove all local state associated with backend. - * - * If you change this, see also CleanupBackgroundWorker. - */ -#ifdef WIN32 -#endif -#ifdef EXEC_BACKEND -#endif - -/* - * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer, - * walwriter, autovacuum, archiver or background worker. - * - * The objectives here are to clean up our local state about the child - * process, and to signal all other remaining children to quickdie. - */ -#ifdef EXEC_BACKEND -#endif -#ifdef EXEC_BACKEND -#endif - -/* - * Log the death of a child process. - */ -#if defined(WIN32) -#else -#endif - -/* - * Advance the postmaster's state machine and take actions as appropriate - * - * This is common code for process_pm_shutdown_request(), - * process_pm_child_exit() and process_pm_pmsignal(), which process the signals - * that might mean we need to change state. - */ - - - -/* - * Send a signal to a postmaster child process - * - * On systems that have setsid(), each child process sets itself up as a - * process group leader. For signals that are generally interpreted in the - * appropriate fashion, we signal the entire process group not just the - * direct child process. This allows us to, for example, SIGQUIT a blocked - * archive_recovery script, or SIGINT a script being run by a backend via - * system(). - * - * There is a race condition for recently-forked children: they might not - * have executed setsid() yet. So we signal the child directly as well as - * the group. We assume such a child will handle the signal before trying - * to spawn any grandchild processes. We also assume that signaling the - * child twice will not cause any problems. - */ -#ifdef HAVE_SETSID -#endif - -/* - * Convenience function for killing a child process after a crash of some - * other child process. We log the action at a higher level than we would - * otherwise do, and we apply send_abort_for_crash to decide which signal - * to send. Normally it's SIGQUIT -- and most other comments in this file - * are written on the assumption that it is -- but developers might prefer - * to use SIGABRT to collect per-child core dumps. - */ - - -/* - * Send a signal to the targeted children (but NOT special children; - * dead_end children are never signaled, either). - */ - - -/* - * Send a termination signal to children. This considers all of our children - * processes, except syslogger and dead_end backends. - */ - - -/* - * BackendStartup -- start backend process - * - * returns: STATUS_ERROR if the fork failed, STATUS_OK otherwise. - * - * Note: if you change this code, also consider StartAutovacuumWorker. - */ -#ifdef EXEC_BACKEND -#else /* !EXEC_BACKEND */ -#endif /* EXEC_BACKEND */ -#ifdef EXEC_BACKEND -#endif - -/* - * Try to report backend fork() failure to client before we close the - * connection. Since we do not care to risk blocking the postmaster on - * this connection, we set the connection to non-blocking and try only once. - * - * This is grungy special-purpose code; we cannot use backend libpq since - * it's not up and running. - */ - - - -/* - * BackendInitialize -- initialize an interactive (postmaster-child) - * backend process, and collect the client's startup packet. - * - * returns: nothing. Will not return at all if there's any failure. - * - * Note: this code does not depend on having any access to shared memory. - * Indeed, our approach to SIGTERM/timeout handling *requires* that - * shared memory not have been touched yet; see comments within. - * In the EXEC_BACKEND case, we are physically attached to shared memory - * but have not yet set up most of our local pointers to shmem structures. - */ - - - -/* - * BackendRun -- set up the backend's argument list and invoke PostgresMain() - * - * returns: - * Doesn't return at all. - */ - - - -#ifdef EXEC_BACKEND - -/* - * postmaster_forkexec -- fork and exec a postmaster subprocess - * - * The caller must have set up the argv array already, except for argv[2] - * which will be filled with the name of the temp variable file. - * - * Returns the child process PID, or -1 on fork failure (a suitable error - * message has been logged on failure). - * - * All uses of this routine will dispatch to SubPostmasterMain in the - * child process. - */ - - -/* - * backend_forkexec -- fork/exec off a backend process - * - * Some operating systems (WIN32) don't have fork() so we have to simulate - * it by storing parameters that need to be passed to the child and - * then create a new child process. - * - * returns the pid of the fork/exec'd process, or -1 on failure - */ - - -#ifndef WIN32 - -/* - * internal_forkexec non-win32 implementation - * - * - writes out backend variables to the parameter file - * - fork():s, and then exec():s the child process - */ - -#else /* WIN32 */ - -// FIXME: How can we remove this code here always? - -#endif /* WIN32 */ - - -/* - * SubPostmasterMain -- Get the fork/exec'd process into a state equivalent - * to what it would be if we'd simply forked on Unix, and then - * dispatch to the appropriate place. - * - * The first two command line arguments are expected to be "--forkFOO" - * (where FOO indicates which postmaster child we are to become), and - * the name of a variables file that we can read to load data that would - * have been inherited by fork() on Unix. Remaining arguments go to the - * subprocess FooMain() routine. - */ -#ifdef USE_SSL -#endif -#endif /* EXEC_BACKEND */ - - -/* - * ExitPostmaster -- cleanup - * - * Do NOT call exit() directly --- always go through here! - */ -#ifdef HAVE_PTHREAD_IS_THREADED_NP -#endif - -/* - * Handle pmsignal conditions representing requests from backends, - * and check for promote and logrotate requests from pg_ctl. - */ -#ifdef USE_SYSTEMD -#endif -#ifdef USE_SYSTEMD -#endif - -/* - * SIGTERM while processing startup packet. - * - * Running proc_exit() from a signal handler would be quite unsafe. - * However, since we have not yet touched shared memory, we can just - * pull the plug and exit without running any atexit handlers. - * - * One might be tempted to try to send a message, or log one, indicating - * why we are disconnecting. However, that would be quite unsafe in itself. - * Also, it seems undesirable to provide clues about the database's state - * to a client that has not yet completed authentication, or even sent us - * a startup packet. - */ - - -/* - * Dummy signal handler - * - * We use this for signals that we don't actually use in the postmaster, - * but we do use in backends. If we were to SIG_IGN such signals in the - * postmaster, then a newly started backend might drop a signal that arrives - * before it's able to reconfigure its signal processing. (See notes in - * tcop/postgres.c.) - */ - - -/* - * Timeout while processing startup packet. - * As for process_startup_packet_die(), we exit via _exit(1). - */ - - - -/* - * Generate a random cancel key. - */ - - -/* - * Count up number of child processes of specified types (dead_end children - * are always excluded). - */ - - - -/* - * StartChildProcess -- start an auxiliary process for the postmaster - * - * "type" determines what kind of child will be started. All child types - * initially go to AuxiliaryProcessMain, which will handle common setup. - * - * Return value of StartChildProcess is subprocess' PID, or 0 if failed - * to start subprocess. - */ -#ifdef EXEC_BACKEND -#else /* !EXEC_BACKEND */ -#endif /* EXEC_BACKEND */ - -/* - * StartAutovacuumWorker - * Start an autovac worker process. - * - * This function is here because it enters the resulting PID into the - * postmaster's private backends list. - * - * NB -- this code very roughly matches BackendStartup. - */ -#ifdef EXEC_BACKEND -#endif - -/* - * MaybeStartWalReceiver - * Start the WAL receiver process, if not running and our state allows. - * - * Note: if WalReceiverPID is already nonzero, it might seem that we should - * clear WalReceiverRequested. However, there's a race condition if the - * walreceiver terminates and the startup process immediately requests a new - * one: it's quite possible to get the signal for the request before reaping - * the dead walreceiver process. Better to risk launching an extra - * walreceiver than to miss launching one we need. (The walreceiver code - * has logic to recognize that it should go away if not needed.) - */ - - - -/* - * Create the opts file - */ -#define OPTS_FILE "postmaster.opts" - - -/* - * MaxLivePostmasterChildren - * - * This reports the number of entries needed in per-child-process arrays - * (the PMChildFlags array, and if EXEC_BACKEND the ShmemBackendArray). - * These arrays include regular backends, autovac workers, walsenders - * and background workers, but not special children nor dead_end children. - * This allows the arrays to have a fixed maximum size, to wit the same - * too-many-children limit enforced by canAcceptConnections(). The exact value - * isn't too critical as long as it's more than MaxBackends. - */ - - -/* - * Connect background worker to a database. - */ - - -/* - * Connect background worker to a database using OIDs. - */ - - -/* - * Block/unblock signals in a background worker - */ - - - - -#ifdef EXEC_BACKEND - -#endif - -/* - * Start a new bgworker. - * Starting time conditions must have been checked already. - * - * Returns true on success, false on failure. - * In either case, update the RegisteredBgWorker's state appropriately. - * - * This code is heavily based on autovacuum.c, q.v. - */ -#ifdef EXEC_BACKEND -#else -#endif -#ifndef EXEC_BACKEND -#endif -#ifdef EXEC_BACKEND -#endif - -/* - * Does the current postmaster state require starting a worker with the - * specified start_time? - */ - - -/* - * Allocate the Backend struct for a connected background worker, but don't - * add it to the list of backends just yet. - * - * On failure, return false without changing any worker state. - * - * Some info from the Backend is copied into the passed rw. - */ - - -/* - * If the time is right, start background worker(s). - * - * As a side effect, the bgworker control variables are set or reset - * depending on whether more workers may need to be started. - * - * We limit the number of workers started per call, to avoid consuming the - * postmaster's attention for too long when many such requests are pending. - * As long as StartWorkerNeeded is true, ServerLoop will not block and will - * call this function again after dealing with any other issues. - */ -#define MAX_BGWORKERS_TO_LAUNCH 100 - -/* - * When a backend asks to be notified about worker state changes, we - * set a flag in its backend entry. The background worker machinery needs - * to know when such backends exit. - */ - - -#ifdef EXEC_BACKEND - -/* - * The following need to be available to the save/restore_backend_variables - * functions. They are marked NON_EXEC_STATIC in their home modules. - */ -extern slock_t *ShmemLock; -extern slock_t *ProcStructLock; -extern PGPROC *AuxiliaryProcs; -extern PMSignalData *PMSignalState; -extern pg_time_t first_syslogger_file_time; - -#ifndef WIN32 -#define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true) -#define read_inheritable_socket(dest, src) (*(dest) = *(src)) -#else -static bool write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE child); -static bool write_inheritable_socket(InheritableSocket *dest, SOCKET src, - pid_t childPid); -static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src); -#endif - - -/* Save critical backend variables into the BackendParameters struct */ -#ifndef WIN32 -#else -#endif -#ifdef WIN32 -#endif -#ifndef HAVE_SPINLOCKS -#endif -#ifdef WIN32 -#else -#endif - - -#ifdef WIN32 -/* - * Duplicate a handle for usage in a child process, and write the child - * process instance of the handle to the parameter file. - */ -static bool -write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE childProcess) -{ - HANDLE hChild = INVALID_HANDLE_VALUE; - - if (!DuplicateHandle(GetCurrentProcess(), - src, - childProcess, - &hChild, - 0, - TRUE, - DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) - { - ereport(LOG, - (errmsg_internal("could not duplicate handle to be written to backend parameter file: error code %lu", - GetLastError()))); - return false; - } - - *dest = hChild; - return true; -} - -/* - * Duplicate a socket for usage in a child process, and write the resulting - * structure to the parameter file. - * This is required because a number of LSPs (Layered Service Providers) very - * common on Windows (antivirus, firewalls, download managers etc) break - * straight socket inheritance. - */ -static bool -write_inheritable_socket(InheritableSocket *dest, SOCKET src, pid_t childpid) -{ - dest->origsocket = src; - if (src != 0 && src != PGINVALID_SOCKET) - { - /* Actual socket */ - if (WSADuplicateSocket(src, childpid, &dest->wsainfo) != 0) - { - ereport(LOG, - (errmsg("could not duplicate socket %d for use in backend: error code %d", - (int) src, WSAGetLastError()))); - return false; - } - } - return true; -} - -/* - * Read a duplicate socket structure back, and get the socket descriptor. - */ -static void -read_inheritable_socket(SOCKET *dest, InheritableSocket *src) -{ - SOCKET s; - - if (src->origsocket == PGINVALID_SOCKET || src->origsocket == 0) - { - /* Not a real socket! */ - *dest = src->origsocket; - } - else - { - /* Actual socket, so create from structure */ - s = WSASocket(FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &src->wsainfo, - 0, - 0); - if (s == INVALID_SOCKET) - { - write_stderr("could not create inherited socket: error code %d\n", - WSAGetLastError()); - exit(1); - } - *dest = s; - - /* - * To make sure we don't get two references to the same socket, close - * the original one. (This would happen when inheritance actually - * works.. - */ - closesocket(src->origsocket); - } -} -#endif - -#ifndef WIN32 -#else -#ifdef _WIN64 -#else -#endif -#endif - -/* Restore critical backend variables from the BackendParameters struct */ -#ifdef WIN32 -#endif -#ifndef HAVE_SPINLOCKS -#endif -#ifdef WIN32 -#else -#endif -#ifndef WIN32 -#endif - - - - - - - - - -#endif /* EXEC_BACKEND */ - - -#ifdef WIN32 - -/* - * Subset implementation of waitpid() for Windows. We assume pid is -1 - * (that is, check all child processes) and options is WNOHANG (don't wait). - */ -static pid_t -waitpid(pid_t pid, int *exitstatus, int options) -{ - win32_deadchild_waitinfo *childinfo; - DWORD exitcode; - DWORD dwd; - ULONG_PTR key; - OVERLAPPED *ovl; - - /* Try to consume one win32_deadchild_waitinfo from the queue. */ - if (!GetQueuedCompletionStatus(win32ChildQueue, &dwd, &key, &ovl, 0)) - { - errno = EAGAIN; - return -1; - } - - childinfo = (win32_deadchild_waitinfo *) key; - pid = childinfo->procId; - - /* - * Remove handle from wait - required even though it's set to wait only - * once - */ - UnregisterWaitEx(childinfo->waitHandle, NULL); - - if (!GetExitCodeProcess(childinfo->procHandle, &exitcode)) - { - /* - * Should never happen. Inform user and set a fixed exitcode. - */ - write_stderr("could not read exit code for process\n"); - exitcode = 255; - } - *exitstatus = exitcode; - - /* - * Close the process handle. Only after this point can the PID can be - * recycled by the kernel. - */ - CloseHandle(childinfo->procHandle); - - /* - * Free struct that was allocated before the call to - * RegisterWaitForSingleObject() - */ - pfree(childinfo); - - return pid; -} - -/* - * Note! Code below executes on a thread pool! All operations must - * be thread safe! Note that elog() and friends must *not* be used. - */ -static void WINAPI -pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) -{ - /* Should never happen, since we use INFINITE as timeout value. */ - if (TimerOrWaitFired) - return; - - /* - * Post the win32_deadchild_waitinfo object for waitpid() to deal with. If - * that fails, we leak the object, but we also leak a whole process and - * get into an unrecoverable state, so there's not much point in worrying - * about that. We'd like to panic, but we can't use that infrastructure - * from this thread. - */ - if (!PostQueuedCompletionStatus(win32ChildQueue, - 0, - (ULONG_PTR) lpParameter, - NULL)) - write_stderr("could not post child completion status\n"); - - /* Queue SIGCHLD signal. */ - pg_queue_signal(SIGCHLD); -} -#endif /* WIN32 */ - -/* - * Initialize one and only handle for monitoring postmaster death. - * - * Called once in the postmaster, so that child processes can subsequently - * monitor if their parent is dead. - */ -#ifndef WIN32 -#else -#endif /* WIN32 */ diff --git a/src/postgres/src_backend_utils_error_elog.c b/src/postgres/src_backend_utils_error_elog.c index 2c12c1c0..48ef40a0 100644 --- a/src/postgres/src_backend_utils_error_elog.c +++ b/src/postgres/src_backend_utils_error_elog.c @@ -4,7 +4,6 @@ * - errstart * - PG_exception_stack * - write_stderr - * - err_gettext * - in_error_recursion_trouble * - error_context_stack * - errordata_stack_depth @@ -302,24 +301,8 @@ should_output_to_server(int elevel) /* * should_output_to_client --- should message of given elevel go to the client? */ -static inline bool -should_output_to_client(int elevel) -{ - if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY) - { - /* - * client_min_messages is honored only after we complete the - * authentication handshake. This is required both for security - * reasons and because many clients can't handle NOTICE messages - * during authentication. - */ - if (ClientAuthInProgress) - return (elevel >= ERROR); - else - return (elevel >= client_min_messages || elevel == INFO); - } - return false; -} +static inline bool should_output_to_client(int elevel) { return false; } + /* @@ -352,18 +335,9 @@ in_error_recursion_trouble(void) * message, since there's a significant probability that that's exactly * what's causing the recursion. */ -static inline const char * -err_gettext(const char *str) -{ #ifdef ENABLE_NLS - if (in_error_recursion_trouble()) - return str; - else - return gettext(str); #else - return str; #endif -} /* * errstart_cold @@ -1766,24 +1740,12 @@ pg_re_throw(void) * interfaces (e.g. CreateFileA()) expect string arguments in this encoding. * Every process in a given system will find the same value at all times. */ -static int -GetACPEncoding(void) -{ - static int encoding = -2; - if (encoding == -2) - encoding = pg_codepage_to_encoding(GetACP()); - - return encoding; -} /* * Write a message line to the windows event log */ -static void -write_eventlog(int level, const char *line, int len) -{ -} + #endif /* WIN32 */ #ifdef WIN32 @@ -1928,44 +1890,20 @@ static void send_message_to_frontend(ErrorData *edata) {} * not available). Used before ereport/elog can be used * safely (memory context, GUC load etc) */ + void write_stderr(const char *fmt,...) { - va_list ap; - -#ifdef WIN32 - char errbuf[2048]; /* Arbitrary size? */ -#endif - - fmt = _(fmt); - + va_list ap; va_start(ap, fmt); -#ifndef WIN32 - /* On Unix, we just fprintf to stderr */ vfprintf(stderr, fmt, ap); fflush(stderr); -#else - vsnprintf(errbuf, sizeof(errbuf), fmt, ap); - - /* - * On Win32, we print to stderr if running on a console, or write to - * eventlog if running as a service - */ - if (pgwin32_is_service()) /* Running as a service */ - { - write_eventlog(ERROR, errbuf, strlen(errbuf)); - } - else - { - /* Not running as service, write to stderr */ - write_console(errbuf, strlen(errbuf)); - fflush(stderr); - } -#endif va_end(ap); } + + /* * Write a message to STDERR using only async-signal-safe functions. This can * be used to safely emit a message from a signal handler. @@ -1992,14 +1930,3 @@ write_stderr(const char *fmt,...) * hard-to-explain kluge. */ -static void write_console(const char *line, int len) {} - -#ifdef WIN32 -int pgwin32_is_service(void) { return 0; } - -// These are technically owned by signal.c, but we skip over that whole file -volatile int pg_signal_queue; -int pg_signal_mask; -void pgwin32_dispatch_queued_signals(void) {} - -#endif \ No newline at end of file diff --git a/src/postgres/src_backend_utils_mb_mbutils.c b/src/postgres/src_backend_utils_mb_mbutils.c index 066bae66..dc863298 100644 --- a/src/postgres/src_backend_utils_mb_mbutils.c +++ b/src/postgres/src_backend_utils_mb_mbutils.c @@ -17,6 +17,8 @@ * - pg_mbstrlen_with_len * - pg_mblen * - SetDatabaseEncoding + * - GetMessageEncoding + * - MessageEncoding *-------------------------------------------------------------------- */ @@ -108,7 +110,6 @@ static __thread const pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_AS static __thread const pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII]; - /* * During backend startup we can't set client encoding because we (a) * can't look up the conversion functions, and (b) may not know the database @@ -776,58 +777,6 @@ report_invalid_encoding(int encoding, const char *mbstr, int len) * null. Returns NULL iff failed. Before MessageEncoding initialization, "str" * should be ASCII-only; this will function as though MessageEncoding is UTF8. */ -WCHAR * -pgwin32_message_to_UTF16(const char *str, int len, int *utf16len) -{ - int msgenc = GetMessageEncoding(); - WCHAR *utf16; - int dstlen; - UINT codepage; - - if (msgenc == PG_SQL_ASCII) - /* No conversion is possible, and SQL_ASCII is never utf16. */ - return NULL; - - codepage = pg_enc2name_tbl[msgenc].codepage; - - /* - * Use MultiByteToWideChar directly if there is a corresponding codepage, - * or double conversion through UTF8 if not. Double conversion is needed, - * for example, in an ENCODING=LATIN8, LC_CTYPE=C database. - */ - if (codepage != 0) - { - utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1)); - dstlen = MultiByteToWideChar(codepage, 0, str, len, utf16, len); - utf16[dstlen] = (WCHAR) 0; - } - else - { - char *utf8; - - /* - * XXX pg_do_encoding_conversion() requires a transaction. In the - * absence of one, hope for the input to be valid UTF8. - */ - utf8 = (char *) str; - - utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1)); - dstlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len); - utf16[dstlen] = (WCHAR) 0; - - if (utf8 != str) - pfree(utf8); - } - if (dstlen == 0 && len > 0) - { - pfree(utf16); - return NULL; /* error */ - } - - if (utf16len) - *utf16len = dstlen; - return utf16; -} #endif /* WIN32 */ diff --git a/src/postgres/src_backend_utils_misc_guc_tables.c b/src/postgres/src_backend_utils_misc_guc_tables.c index 7188a5a8..60b1e577 100644 --- a/src/postgres/src_backend_utils_misc_guc_tables.c +++ b/src/postgres/src_backend_utils_misc_guc_tables.c @@ -1,7 +1,6 @@ /*-------------------------------------------------------------------- * Symbols referenced in this file: * - log_min_messages - * - client_min_messages * - backtrace_functions * - check_function_bodies *-------------------------------------------------------------------- @@ -285,7 +284,6 @@ __thread bool check_function_bodies = true; __thread int log_min_messages = WARNING; -__thread int client_min_messages = NOTICE; diff --git a/src/postgres/src_port_pg_bitutils.c b/src/postgres/src_port_pg_bitutils.c index 1a3fef03..a9b8e0d0 100644 --- a/src/postgres/src_port_pg_bitutils.c +++ b/src/postgres/src_port_pg_bitutils.c @@ -4,6 +4,9 @@ * - pg_popcount64_slow * - pg_popcount32 * - pg_popcount32_slow + * - pg_leftmost_one_pos + * - pg_rightmost_one_pos + * - pg_number_of_ones *-------------------------------------------------------------------- */ diff --git a/src/postgres/src_port_snprintf.c b/src/postgres/src_port_snprintf.c index d119ca05..1764554b 100644 --- a/src/postgres/src_port_snprintf.c +++ b/src/postgres/src_port_snprintf.c @@ -1,11 +1,11 @@ /*-------------------------------------------------------------------- * Symbols referenced in this file: - * - pg_vfprintf + * - pg_vsnprintf * - dopr * - pg_snprintf - * - pg_vsnprintf * - strchrnul * - dostr + * - flushbuffer * - find_arguments * - fmtint * - adjust_sign @@ -18,8 +18,8 @@ * - fmtptr * - fmtfloat * - dopr_outch - * - flushbuffer * - pg_fprintf + * - pg_vfprintf * - pg_sprintf * - pg_vsprintf * - pg_printf diff --git a/src/postgres/src_port_strerror.c b/src/postgres/src_port_strerror.c index 5ce298f3..9c49f758 100644 --- a/src/postgres/src_port_strerror.c +++ b/src/postgres/src_port_strerror.c @@ -1,6 +1,7 @@ /*-------------------------------------------------------------------- * Symbols referenced in this file: * - pg_strerror_r + * - win32_socket_strerror * - gnuish_strerror_r * - get_errno_symbol *-------------------------------------------------------------------- diff --git a/src/postgres/src_port_strlcpy.c b/src/postgres/src_port_strlcpy.c index 6b5efd35..30367e73 100644 --- a/src/postgres/src_port_strlcpy.c +++ b/src/postgres/src_port_strlcpy.c @@ -1,3 +1,9 @@ +/*-------------------------------------------------------------------- + * Symbols referenced in this file: + * - __builtin___strlcpy_chk + *-------------------------------------------------------------------- + */ + /*------------------------------------------------------------------------- * * strlcpy.c @@ -33,8 +39,8 @@ */ #include "c.h" +#if HAVE_DECL_STRLCPY == 0 -#ifdef WIN32 /* * Copy src to string dst of size siz. At most siz-1 characters @@ -70,5 +76,4 @@ strlcpy(char *dst, const char *src, size_t siz) return (s - src - 1); /* count does not include NUL */ } - -#endif +#endif // HAVE_DECL_STRLCPY == 0