codekingpro/portable-devtools
114k
1/*-------------------------------------------------------------------------2 *3 * port.h4 * Header for src/port/ compatibility functions.5 *6 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group7 * Portions Copyright (c) 1994, Regents of the University of California8 *9 * src/include/port.h10 *11 *-------------------------------------------------------------------------12 */13#ifndef PG_PORT_H14#define PG_PORT_H15 16#include <ctype.h>17 18/*19 * Windows has enough specialized port stuff that we push most of it off20 * into another file.21 * Note: Some CYGWIN includes might #define WIN32.22 */23#if defined(WIN32) && !defined(__CYGWIN__)24#include "port/win32_port.h"25#endif26 27/* socket has a different definition on WIN32 */28#ifndef WIN3229typedef int pgsocket;30 31#define PGINVALID_SOCKET (-1)32#else33typedef SOCKET pgsocket;34 35#define PGINVALID_SOCKET INVALID_SOCKET36#endif37 38/* if platform lacks socklen_t, we assume this will work */39#ifndef HAVE_SOCKLEN_T40typedef unsigned int socklen_t;41#endif42 43/* non-blocking */44extern bool pg_set_noblock(pgsocket sock);45extern bool pg_set_block(pgsocket sock);46 47/* Portable path handling for Unix/Win32 (in path.c) */48 49extern bool has_drive_prefix(const char *path);50extern char *first_dir_separator(const char *filename);51extern char *last_dir_separator(const char *filename);52extern char *first_path_var_separator(const char *pathlist);53extern void join_path_components(char *ret_path,54 const char *head, const char *tail);55extern void canonicalize_path(char *path);56extern void make_native_path(char *filename);57extern void cleanup_path(char *path);58extern bool path_contains_parent_reference(const char *path);59extern bool path_is_relative_and_below_cwd(const char *path);60extern bool path_is_prefix_of_path(const char *path1, const char *path2);61extern char *make_absolute_path(const char *path);62extern const char *get_progname(const char *argv0);63extern void get_share_path(const char *my_exec_path, char *ret_path);64extern void get_etc_path(const char *my_exec_path, char *ret_path);65extern void get_include_path(const char *my_exec_path, char *ret_path);66extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);67extern void get_includeserver_path(const char *my_exec_path, char *ret_path);68extern void get_lib_path(const char *my_exec_path, char *ret_path);69extern void get_pkglib_path(const char *my_exec_path, char *ret_path);70extern void get_locale_path(const char *my_exec_path, char *ret_path);71extern void get_doc_path(const char *my_exec_path, char *ret_path);72extern void get_html_path(const char *my_exec_path, char *ret_path);73extern void get_man_path(const char *my_exec_path, char *ret_path);74extern bool get_home_path(char *ret_path);75extern void get_parent_directory(char *path);76 77/* common/pgfnames.c */78extern char **pgfnames(const char *path);79extern void pgfnames_cleanup(char **filenames);80 81#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/')82#define is_nonwindows_absolute_path(filename) \83( \84 IS_NONWINDOWS_DIR_SEP((filename)[0]) \85)86 87#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')88/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */89#define is_windows_absolute_path(filename) \90( \91 IS_WINDOWS_DIR_SEP((filename)[0]) || \92 (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \93 IS_WINDOWS_DIR_SEP((filename)[2])) \94)95 96/*97 * is_absolute_path and IS_DIR_SEP98 *99 * By using macros here we avoid needing to include path.c in libpq.100 */101#ifndef WIN32102#define IS_DIR_SEP(ch) IS_NONWINDOWS_DIR_SEP(ch)103#define is_absolute_path(filename) is_nonwindows_absolute_path(filename)104#else105#define IS_DIR_SEP(ch) IS_WINDOWS_DIR_SEP(ch)106#define is_absolute_path(filename) is_windows_absolute_path(filename)107#endif108 109/*110 * This macro provides a centralized list of all errnos that identify111 * hard failure of a previously-established network connection.112 * The macro is intended to be used in a switch statement, in the form113 * "case ALL_CONNECTION_FAILURE_ERRNOS:".114 *115 * Note: this groups EPIPE and ECONNRESET, which we take to indicate a116 * probable server crash, with other errors that indicate loss of network117 * connectivity without proving much about the server's state. Places that118 * are actually reporting errors typically single out EPIPE and ECONNRESET,119 * while allowing the network failures to be reported generically.120 */121#define ALL_CONNECTION_FAILURE_ERRNOS \122 EPIPE: \123 case ECONNRESET: \124 case ECONNABORTED: \125 case EHOSTDOWN: \126 case EHOSTUNREACH: \127 case ENETDOWN: \128 case ENETRESET: \129 case ENETUNREACH: \130 case ETIMEDOUT131 132/* Portable locale initialization (in exec.c) */133extern void set_pglocale_pgservice(const char *argv0, const char *app);134 135/* Portable way to find and execute binaries (in exec.c) */136extern int validate_exec(const char *path);137extern int find_my_exec(const char *argv0, char *retpath);138extern int find_other_exec(const char *argv0, const char *target,139 const char *versionstr, char *retpath);140extern char *pipe_read_line(char *cmd, char *line, int maxsize);141 142/* Doesn't belong here, but this is used with find_other_exec(), so... */143#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"144 145#ifdef EXEC_BACKEND146/* Disable ASLR before exec, for developer builds only (in exec.c) */147extern int pg_disable_aslr(void);148#endif149 150 151#if defined(WIN32) || defined(__CYGWIN__)152#define EXE ".exe"153#else154#define EXE ""155#endif156 157#if defined(WIN32) && !defined(__CYGWIN__)158#define DEVNULL "nul"159#else160#define DEVNULL "/dev/null"161#endif162 163/* Portable delay handling */164extern void pg_usleep(long microsec);165 166/* Portable SQL-like case-independent comparisons and conversions */167extern int pg_strcasecmp(const char *s1, const char *s2);168extern int pg_strncasecmp(const char *s1, const char *s2, size_t n);169extern unsigned char pg_toupper(unsigned char ch);170extern unsigned char pg_tolower(unsigned char ch);171extern unsigned char pg_ascii_toupper(unsigned char ch);172extern unsigned char pg_ascii_tolower(unsigned char ch);173 174/*175 * Beginning in v12, we always replace snprintf() and friends with our own176 * implementation. This symbol is no longer consulted by the core code,177 * but keep it defined anyway in case any extensions are looking at it.178 */179#define USE_REPL_SNPRINTF 1180 181/*182 * Versions of libintl >= 0.13 try to replace printf() and friends with183 * macros to their own versions that understand the %$ format. We do the184 * same, so disable their macros, if they exist.185 */186#ifdef vsnprintf187#undef vsnprintf188#endif189#ifdef snprintf190#undef snprintf191#endif192#ifdef vsprintf193#undef vsprintf194#endif195#ifdef sprintf196#undef sprintf197#endif198#ifdef vfprintf199#undef vfprintf200#endif201#ifdef fprintf202#undef fprintf203#endif204#ifdef vprintf205#undef vprintf206#endif207#ifdef printf208#undef printf209#endif210 211extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) pg_attribute_printf(3, 0);212extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4);213extern int pg_vsprintf(char *str, const char *fmt, va_list args) pg_attribute_printf(2, 0);214extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3);215extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args) pg_attribute_printf(2, 0);216extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3);217extern int pg_vprintf(const char *fmt, va_list args) pg_attribute_printf(1, 0);218extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2);219 220#ifndef WIN32221/*222 * We add a pg_ prefix as a warning that the Windows implementations have the223 * non-standard side-effect of changing the current file position.224 */225#define pg_pread pread226#define pg_pwrite pwrite227#endif228 229/*230 * We use __VA_ARGS__ for printf to prevent replacing references to231 * the "printf" format archetype in format() attribute declarations.232 * That unfortunately means that taking a function pointer to printf233 * will not do what we'd wish. (If you need to do that, you must name234 * pg_printf explicitly.) For printf's sibling functions, use235 * parameterless macros so that function pointers will work unsurprisingly.236 */237#define vsnprintf pg_vsnprintf238#define snprintf pg_snprintf239#define vsprintf pg_vsprintf240#define sprintf pg_sprintf241#define vfprintf pg_vfprintf242#define fprintf pg_fprintf243#define vprintf pg_vprintf244#define printf(...) pg_printf(__VA_ARGS__)245 246/* This is also provided by snprintf.c */247extern int pg_strfromd(char *str, size_t count, int precision, double value);248 249/* Replace strerror() with our own, somewhat more robust wrapper */250extern char *pg_strerror(int errnum);251#define strerror pg_strerror252 253/* Likewise for strerror_r(); note we prefer the GNU API for that */254extern char *pg_strerror_r(int errnum, char *buf, size_t buflen);255#define strerror_r pg_strerror_r256#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */257 258/* Wrap strsignal(), or provide our own version if necessary */259extern const char *pg_strsignal(int signum);260 261extern int pclose_check(FILE *stream);262 263/* Global variable holding time zone information. */264#if defined(WIN32) || defined(__CYGWIN__)265#define TIMEZONE_GLOBAL _timezone266#define TZNAME_GLOBAL _tzname267#else268#define TIMEZONE_GLOBAL timezone269#define TZNAME_GLOBAL tzname270#endif271 272#if defined(WIN32) || defined(__CYGWIN__)273/*274 * Win32 doesn't have reliable rename/unlink during concurrent access.275 */276extern int pgrename(const char *from, const char *to);277extern int pgunlink(const char *path);278 279/* Include this first so later includes don't see these defines */280#ifdef _MSC_VER281#include <io.h>282#endif283 284#define rename(from, to) pgrename(from, to)285#define unlink(path) pgunlink(path)286#endif /* defined(WIN32) || defined(__CYGWIN__) */287 288/*289 * Win32 also doesn't have symlinks, but we can emulate them with290 * junction points on newer Win32 versions.291 *292 * Cygwin has its own symlinks which work on Win95/98/ME where293 * junction points don't, so use those instead. We have no way of294 * knowing what type of system Cygwin binaries will be run on.295 * Note: Some CYGWIN includes might #define WIN32.296 */297#if defined(WIN32) && !defined(__CYGWIN__)298extern int pgsymlink(const char *oldpath, const char *newpath);299extern int pgreadlink(const char *path, char *buf, size_t size);300 301#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)302#define readlink(path, buf, size) pgreadlink(path, buf, size)303#endif304 305extern bool rmtree(const char *path, bool rmtopdir);306 307#if defined(WIN32) && !defined(__CYGWIN__)308 309/*310 * open() and fopen() replacements to allow deletion of open files and311 * passing of other special options.312 */313#define O_DIRECT 0x80000000314extern HANDLE pgwin32_open_handle(const char *, int, bool);315extern int pgwin32_open(const char *, int,...);316extern FILE *pgwin32_fopen(const char *, const char *);317#define open(a,b,c) pgwin32_open(a,b,c)318#define fopen(a,b) pgwin32_fopen(a,b)319 320/*321 * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want322 * to use our popen wrapper, rather than plain _popen, so override that. For323 * consistency, use our version of pclose, too.324 */325#ifdef popen326#undef popen327#endif328#ifdef pclose329#undef pclose330#endif331 332/*333 * system() and popen() replacements to enclose the command in an extra334 * pair of quotes.335 */336extern int pgwin32_system(const char *command);337extern FILE *pgwin32_popen(const char *command, const char *type);338 339#define system(a) pgwin32_system(a)340#define popen(a,b) pgwin32_popen(a,b)341#define pclose(a) _pclose(a)342 343#else /* !WIN32 */344 345/*346 * Win32 requires a special close for sockets and pipes, while on Unix347 * close() does them all.348 */349#define closesocket close350#endif /* WIN32 */351 352/*353 * On Windows, setvbuf() does not support _IOLBF mode, and interprets that354 * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0)355 * crashes outright if "parameter validation" is enabled. Therefore, in356 * places where we'd like to select line-buffered mode, we fall back to357 * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF358 * directly in order to implement this behavior.359 */360#ifndef WIN32361#define PG_IOLBF _IOLBF362#else363#define PG_IOLBF _IONBF364#endif365 366/*367 * Default "extern" declarations or macro substitutes for library routines.368 * When necessary, these routines are provided by files in src/port/.369 */370 371/* Type to use with fseeko/ftello */372#ifndef WIN32 /* WIN32 is handled in port/win32_port.h */373#define pgoff_t off_t374#endif375 376#ifndef HAVE_GETPEEREID377/* On Windows, Perl might have incompatible definitions of uid_t and gid_t. */378#ifndef PLPERL_HAVE_UID_GID379extern int getpeereid(int sock, uid_t *uid, gid_t *gid);380#endif381#endif382 383/*384 * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version385 * newer than the gcc compatibility clang claims to have. This would cause a386 * *lot* of superfluous function calls, therefore revert when using clang. In387 * C++ there's issues with libc++ (not libstdc++), so disable as well.388 */389#if defined(__clang__) && !defined(__cplusplus)390/* needs to be separate to not confuse other compilers */391#if __has_builtin(__builtin_isinf)392/* need to include before, to avoid getting overwritten */393#include <math.h>394#undef isinf395#define isinf __builtin_isinf396#endif /* __has_builtin(isinf) */397#endif /* __clang__ && !__cplusplus */398 399#ifndef HAVE_EXPLICIT_BZERO400extern void explicit_bzero(void *buf, size_t len);401#endif402 403#ifdef HAVE_BUGGY_STRTOF404extern float pg_strtof(const char *nptr, char **endptr);405#define strtof(a,b) (pg_strtof((a),(b)))406#endif407 408#ifdef WIN32409/* src/port/win32link.c */410extern int link(const char *src, const char *dst);411#endif412 413#ifndef HAVE_MKDTEMP414extern char *mkdtemp(char *path);415#endif416 417#ifndef HAVE_INET_ATON418#include <netinet/in.h>419#include <arpa/inet.h>420extern int inet_aton(const char *cp, struct in_addr *addr);421#endif422 423#if !HAVE_DECL_STRLCAT424extern size_t strlcat(char *dst, const char *src, size_t siz);425#endif426 427#if !HAVE_DECL_STRLCPY428extern size_t strlcpy(char *dst, const char *src, size_t siz);429#endif430 431#if !HAVE_DECL_STRNLEN432extern size_t strnlen(const char *str, size_t maxlen);433#endif434 435/* thread.c */436#ifndef WIN32437extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen);438extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen);439#endif440 441extern void pg_qsort(void *base, size_t nel, size_t elsize,442 int (*cmp) (const void *, const void *));443extern int pg_qsort_strcmp(const void *a, const void *b);444 445#define qsort(a,b,c,d) pg_qsort(a,b,c,d)446 447typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg);448 449extern void qsort_arg(void *base, size_t nel, size_t elsize,450 qsort_arg_comparator cmp, void *arg);451 452extern void qsort_interruptible(void *base, size_t nel, size_t elsize,453 qsort_arg_comparator cmp, void *arg);454 455extern void *bsearch_arg(const void *key, const void *base0,456 size_t nmemb, size_t size,457 int (*compar) (const void *, const void *, void *),458 void *arg);459 460/* port/chklocale.c */461extern int pg_get_encoding_from_locale(const char *ctype, bool write_message);462 463#if defined(WIN32) && !defined(FRONTEND)464extern int pg_codepage_to_encoding(UINT cp);465#endif466 467/* port/inet_net_ntop.c */468extern char *pg_inet_net_ntop(int af, const void *src, int bits,469 char *dst, size_t size);470 471/* port/pg_strong_random.c */472extern void pg_strong_random_init(void);473extern bool pg_strong_random(void *buf, size_t len);474 475/*476 * pg_backend_random used to be a wrapper for pg_strong_random before477 * Postgres 12 for the backend code.478 */479#define pg_backend_random pg_strong_random480 481/* port/pgcheckdir.c */482extern int pg_check_dir(const char *dir);483 484/* port/pgmkdirp.c */485extern int pg_mkdir_p(char *path, int omode);486 487/* port/pqsignal.c */488typedef void (*pqsigfunc) (SIGNAL_ARGS);489extern pqsigfunc pqsignal(int signo, pqsigfunc func);490 491/* port/quotes.c */492extern char *escape_single_quotes_ascii(const char *src);493 494/* common/wait_error.c */495extern char *wait_result_to_str(int exitstatus);496extern bool wait_result_is_signal(int exit_status, int signum);497extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found);498extern int wait_result_to_exit_code(int exit_status);499 500/*501 * Interfaces that we assume all Unix system have. We retain individual macros502 * for better documentation.503 *504 * For symlink-related functions, there is often no need to test these macros,505 * because we provided basic support on Windows that can work with absolute506 * paths to directories. Code that wants to test for complete symlink support507 * (including relative paths and non-directories) should be conditional on508 * HAVE_READLINK or HAVE_SYMLINK.509 */510#ifndef WIN32511#define HAVE_GETRLIMIT 1512#define HAVE_POLL 1513#define HAVE_POLL_H 1514#define HAVE_READLINK 1515#define HAVE_SETSID 1516#define HAVE_SHM_OPEN 1517#define HAVE_SYMLINK 1518#endif519 520#endif /* PG_PORT_H */521 