2003-05-15 18:35:30 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* port.h
|
2004-11-06 02:16:22 +01:00
|
|
|
* Header for src/port/ compatibility functions.
|
2003-05-15 18:35:30 +02:00
|
|
|
*
|
2018-01-03 05:30:12 +01:00
|
|
|
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
2003-05-15 18:35:30 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/port.h
|
2003-05-15 18:35:30 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
2006-10-04 00:18:23 +02:00
|
|
|
#ifndef PG_PORT_H
|
|
|
|
#define PG_PORT_H
|
2003-05-15 18:35:30 +02:00
|
|
|
|
2004-05-20 03:47:01 +02:00
|
|
|
#include <ctype.h>
|
2006-09-11 22:10:30 +02:00
|
|
|
#include <netdb.h>
|
|
|
|
#include <pwd.h>
|
2003-06-14 16:35:42 +02:00
|
|
|
|
2017-11-16 16:36:18 +01:00
|
|
|
/*
|
|
|
|
* Windows has enough specialized port stuff that we push most of it off
|
|
|
|
* into another file.
|
|
|
|
* Note: Some CYGWIN includes might #define WIN32.
|
|
|
|
*/
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
#include "port/win32_port.h"
|
|
|
|
#endif
|
|
|
|
|
2010-01-10 15:16:08 +01:00
|
|
|
/* socket has a different definition on WIN32 */
|
|
|
|
#ifndef WIN32
|
|
|
|
typedef int pgsocket;
|
2010-02-26 03:01:40 +01:00
|
|
|
|
2010-01-31 18:35:46 +01:00
|
|
|
#define PGINVALID_SOCKET (-1)
|
2010-01-10 15:16:08 +01:00
|
|
|
#else
|
|
|
|
typedef SOCKET pgsocket;
|
2010-02-26 03:01:40 +01:00
|
|
|
|
2010-01-10 15:16:08 +01:00
|
|
|
#define PGINVALID_SOCKET INVALID_SOCKET
|
|
|
|
#endif
|
|
|
|
|
2004-03-10 22:12:49 +01:00
|
|
|
/* non-blocking */
|
2010-01-10 15:16:08 +01:00
|
|
|
extern bool pg_set_noblock(pgsocket sock);
|
|
|
|
extern bool pg_set_block(pgsocket sock);
|
2004-03-10 22:12:49 +01:00
|
|
|
|
2006-09-11 22:10:30 +02:00
|
|
|
/* Portable path handling for Unix/Win32 (in path.c) */
|
2004-06-11 00:26:24 +02:00
|
|
|
|
2011-07-06 17:45:13 +02:00
|
|
|
extern bool has_drive_prefix(const char *filename);
|
2004-06-11 00:26:24 +02:00
|
|
|
extern char *first_dir_separator(const char *filename);
|
|
|
|
extern char *last_dir_separator(const char *filename);
|
2011-02-03 04:49:54 +01:00
|
|
|
extern char *first_path_var_separator(const char *pathlist);
|
2004-11-06 02:16:22 +01:00
|
|
|
extern void join_path_components(char *ret_path,
|
2005-10-15 04:49:52 +02:00
|
|
|
const char *head, const char *tail);
|
2004-03-09 05:49:02 +01:00
|
|
|
extern void canonicalize_path(char *path);
|
2004-08-12 20:32:52 +02:00
|
|
|
extern void make_native_path(char *path);
|
2016-02-17 18:12:06 +01:00
|
|
|
extern void cleanup_path(char *path);
|
2005-08-12 23:07:53 +02:00
|
|
|
extern bool path_contains_parent_reference(const char *path);
|
2011-02-12 15:47:51 +01:00
|
|
|
extern bool path_is_relative_and_below_cwd(const char *path);
|
2005-08-29 21:39:39 +02:00
|
|
|
extern bool path_is_prefix_of_path(const char *path1, const char *path2);
|
2014-04-05 00:42:13 +02:00
|
|
|
extern char *make_absolute_path(const char *path);
|
2004-05-12 15:38:49 +02:00
|
|
|
extern const char *get_progname(const char *argv0);
|
2004-05-17 16:35:34 +02:00
|
|
|
extern void get_share_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_etc_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_include_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
|
2004-08-01 08:56:39 +02:00
|
|
|
extern void get_includeserver_path(const char *my_exec_path, char *ret_path);
|
|
|
|
extern void get_lib_path(const char *my_exec_path, char *ret_path);
|
2004-05-17 16:35:34 +02:00
|
|
|
extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
|
2004-05-25 03:00:30 +02:00
|
|
|
extern void get_locale_path(const char *my_exec_path, char *ret_path);
|
2005-09-27 19:39:35 +02:00
|
|
|
extern void get_doc_path(const char *my_exec_path, char *ret_path);
|
2008-02-18 15:51:48 +01:00
|
|
|
extern void get_html_path(const char *my_exec_path, char *ret_path);
|
2005-09-27 19:39:35 +02:00
|
|
|
extern void get_man_path(const char *my_exec_path, char *ret_path);
|
2004-08-18 04:59:12 +02:00
|
|
|
extern bool get_home_path(char *ret_path);
|
2004-08-29 23:08:48 +02:00
|
|
|
extern void get_parent_directory(char *path);
|
2004-05-17 16:35:34 +02:00
|
|
|
|
2015-03-14 19:08:45 +01:00
|
|
|
/* common/pgfnames.c */
|
2008-04-18 19:05:45 +02:00
|
|
|
extern char **pgfnames(const char *path);
|
2007-01-19 17:42:24 +01:00
|
|
|
extern void pgfnames_cleanup(char **filenames);
|
|
|
|
|
2004-05-19 06:21:49 +02:00
|
|
|
/*
|
|
|
|
* is_absolute_path
|
|
|
|
*
|
2006-09-11 22:10:30 +02:00
|
|
|
* By making this a macro we avoid needing to include path.c in libpq.
|
2004-05-19 06:21:49 +02:00
|
|
|
*/
|
|
|
|
#ifndef WIN32
|
2011-02-03 16:46:31 +01:00
|
|
|
#define IS_DIR_SEP(ch) ((ch) == '/')
|
|
|
|
|
2004-05-19 06:21:49 +02:00
|
|
|
#define is_absolute_path(filename) \
|
|
|
|
( \
|
2011-02-03 16:46:31 +01:00
|
|
|
IS_DIR_SEP((filename)[0]) \
|
2004-05-19 06:21:49 +02:00
|
|
|
)
|
|
|
|
#else
|
2011-02-03 16:46:31 +01:00
|
|
|
#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\')
|
|
|
|
|
2011-02-12 15:47:51 +01:00
|
|
|
/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */
|
2004-05-19 06:21:49 +02:00
|
|
|
#define is_absolute_path(filename) \
|
|
|
|
( \
|
2011-02-03 16:46:31 +01:00
|
|
|
IS_DIR_SEP((filename)[0]) || \
|
2006-09-22 23:39:58 +02:00
|
|
|
(isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \
|
2011-02-03 16:46:31 +01:00
|
|
|
IS_DIR_SEP((filename)[2])) \
|
2004-05-19 06:21:49 +02:00
|
|
|
)
|
|
|
|
#endif
|
|
|
|
|
2006-09-11 22:10:30 +02:00
|
|
|
/* Portable locale initialization (in exec.c) */
|
|
|
|
extern void set_pglocale_pgservice(const char *argv0, const char *app);
|
2004-05-19 06:21:49 +02:00
|
|
|
|
2006-09-11 22:10:30 +02:00
|
|
|
/* Portable way to find binaries (in exec.c) */
|
2004-08-29 07:07:03 +02:00
|
|
|
extern int find_my_exec(const char *argv0, char *retpath);
|
2004-05-21 18:06:23 +02:00
|
|
|
extern int find_other_exec(const char *argv0, const char *target,
|
2004-08-29 07:07:03 +02:00
|
|
|
const char *versionstr, char *retpath);
|
|
|
|
|
Change pg_ctl to detect server-ready by watching status in postmaster.pid.
Traditionally, "pg_ctl start -w" has waited for the server to become
ready to accept connections by attempting a connection once per second.
That has the major problem that connection issues (for instance, a
kernel packet filter blocking traffic) can't be reliably told apart
from server startup issues, and the minor problem that if server startup
isn't quick, we accumulate "the database system is starting up" spam
in the server log. We've hacked around many of the possible connection
issues, but it resulted in ugly and complicated code in pg_ctl.c.
In commit c61559ec3, I changed the probe rate to every tenth of a second.
That prompted Jeff Janes to complain that the log-spam problem had become
much worse. In the ensuing discussion, Andres Freund pointed out that
we could dispense with connection attempts altogether if the postmaster
were changed to report its status in postmaster.pid, which "pg_ctl start"
already relies on being able to read. This patch implements that, teaching
postmaster.c to report a status string into the pidfile at the same
state-change points already identified as being of interest for systemd
status reporting (cf commit 7d17e683f). pg_ctl no longer needs to link
with libpq at all; all its functions now depend on reading server files.
In support of this, teach AddToDataDirLockFile() to allow addition of
postmaster.pid lines in not-necessarily-sequential order. This is needed
on Windows where the SHMEM_KEY line will never be written at all. We still
have the restriction that we don't want to truncate the pidfile; document
the reasons for that a bit better.
Also, fix the pg_ctl TAP tests so they'll notice if "start -w" mode
is broken --- before, they'd just wait out the sixty seconds until
the loop gives up, and then report success anyway. (Yes, I found that
out the hard way.)
While at it, arrange for pg_ctl to not need to #include miscadmin.h;
as a rather low-level backend header, requiring that to be compilable
client-side is pretty dubious. This requires moving the #define's
associated with the pidfile into a new header file, and moving
PG_BACKEND_VERSIONSTR someplace else. For lack of a clearly better
"someplace else", I put it into port.h, beside the declaration of
find_other_exec(), since most users of that macro are passing the value to
find_other_exec(). (initdb still depends on miscadmin.h, but at least
pg_ctl and pg_upgrade no longer do.)
In passing, fix main.c so that PG_BACKEND_VERSIONSTR actually defines the
output of "postgres -V", which remarkably it had never done before.
Discussion: https://postgr.es/m/CAMkU=1xJW8e+CTotojOMBd-yzUvD0e_JZu2xHo=MnuZ4__m7Pg@mail.gmail.com
2017-06-28 23:31:24 +02:00
|
|
|
/* Doesn't belong here, but this is used with find_other_exec(), so... */
|
|
|
|
#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
|
|
|
|
|
2008-02-29 16:31:33 +01:00
|
|
|
|
2004-08-07 23:48:09 +02:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2004-05-11 23:57:15 +02:00
|
|
|
#define EXE ".exe"
|
|
|
|
#else
|
|
|
|
#define EXE ""
|
2004-11-17 18:46:24 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
|
|
|
#define DEVNULL "nul"
|
|
|
|
#else
|
2004-05-11 23:57:15 +02:00
|
|
|
#define DEVNULL "/dev/null"
|
|
|
|
#endif
|
|
|
|
|
2004-02-10 04:42:45 +01:00
|
|
|
/* Portable delay handling */
|
|
|
|
extern void pg_usleep(long microsec);
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
/* Portable SQL-like case-independent comparisons and conversions */
|
|
|
|
extern int pg_strcasecmp(const char *s1, const char *s2);
|
|
|
|
extern int pg_strncasecmp(const char *s1, const char *s2, size_t n);
|
|
|
|
extern unsigned char pg_toupper(unsigned char ch);
|
|
|
|
extern unsigned char pg_tolower(unsigned char ch);
|
2011-03-20 17:43:39 +01:00
|
|
|
extern unsigned char pg_ascii_toupper(unsigned char ch);
|
|
|
|
extern unsigned char pg_ascii_tolower(unsigned char ch);
|
2004-05-07 02:24:59 +02:00
|
|
|
|
2018-09-26 19:13:57 +02:00
|
|
|
/*
|
|
|
|
* Beginning in v12, we always replace snprintf() and friends with our own
|
|
|
|
* implementation. This symbol is no longer consulted by the core code,
|
|
|
|
* but keep it defined anyway in case any extensions are looking at it.
|
|
|
|
*/
|
|
|
|
#define USE_REPL_SNPRINTF 1
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
|
2005-12-06 03:29:04 +01:00
|
|
|
/*
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
* Versions of libintl >= 0.13 try to replace printf() and friends with
|
|
|
|
* macros to their own versions that understand the %$ format. We do the
|
|
|
|
* same, so disable their macros, if they exist.
|
2005-12-06 03:29:04 +01:00
|
|
|
*/
|
|
|
|
#ifdef vsnprintf
|
|
|
|
#undef vsnprintf
|
|
|
|
#endif
|
|
|
|
#ifdef snprintf
|
|
|
|
#undef snprintf
|
|
|
|
#endif
|
2018-10-09 01:15:55 +02:00
|
|
|
#ifdef vsprintf
|
|
|
|
#undef vsprintf
|
|
|
|
#endif
|
2005-12-06 03:29:04 +01:00
|
|
|
#ifdef sprintf
|
|
|
|
#undef sprintf
|
|
|
|
#endif
|
2006-11-28 02:12:34 +01:00
|
|
|
#ifdef vfprintf
|
|
|
|
#undef vfprintf
|
|
|
|
#endif
|
2005-12-06 03:29:04 +01:00
|
|
|
#ifdef fprintf
|
|
|
|
#undef fprintf
|
|
|
|
#endif
|
2018-10-09 01:15:55 +02:00
|
|
|
#ifdef vprintf
|
|
|
|
#undef vprintf
|
|
|
|
#endif
|
2005-12-06 03:29:04 +01:00
|
|
|
#ifdef printf
|
|
|
|
#undef printf
|
|
|
|
#endif
|
|
|
|
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
|
|
|
|
extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4);
|
2018-10-09 01:15:55 +02:00
|
|
|
extern int pg_vsprintf(char *str, const char *fmt, va_list args);
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3);
|
|
|
|
extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args);
|
|
|
|
extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3);
|
2018-10-09 01:15:55 +02:00
|
|
|
extern int pg_vprintf(const char *fmt, va_list args);
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2);
|
2005-12-06 06:13:46 +01:00
|
|
|
|
2005-03-11 20:13:43 +01:00
|
|
|
/*
|
2018-09-26 23:35:01 +02:00
|
|
|
* We use __VA_ARGS__ for printf to prevent replacing references to
|
|
|
|
* the "printf" format archetype in format() attribute declarations.
|
|
|
|
* That unfortunately means that taking a function pointer to printf
|
|
|
|
* will not do what we'd wish. (If you need to do that, you must name
|
|
|
|
* pg_printf explicitly.) For printf's sibling functions, use
|
|
|
|
* parameterless macros so that function pointers will work unsurprisingly.
|
2005-03-11 20:13:43 +01:00
|
|
|
*/
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
#define vsnprintf pg_vsnprintf
|
|
|
|
#define snprintf pg_snprintf
|
2018-10-09 01:15:55 +02:00
|
|
|
#define vsprintf pg_vsprintf
|
Revert error-throwing wrappers for the printf family of functions.
This reverts commit 16304a013432931e61e623c8d85e9fe24709d9ba, except
for its changes in src/port/snprintf.c; as well as commit
cac18a76bb6b08f1ecc2a85e46c9d2ab82dd9d23 which is no longer needed.
Fujii Masao reported that the previous commit caused failures in psql on
OS X, since if one exits the pager program early while viewing a query
result, psql sees an EPIPE error from fprintf --- and the wrapper function
thought that was reason to panic. (It's a bit surprising that the same
does not happen on Linux.) Further discussion among the security list
concluded that the risk of other such failures was far too great, and
that the one-size-fits-all approach to error handling embodied in the
previous patch is unlikely to be workable.
This leaves us again exposed to the possibility of the type of failure
envisioned in CVE-2015-3166. However, that failure mode is strictly
hypothetical at this point: there is no concrete reason to believe that
an attacker could trigger information disclosure through the supposed
mechanism. In the first place, the attack surface is fairly limited,
since so much of what the backend does with format strings goes through
stringinfo.c or psprintf(), and those already had adequate defenses.
In the second place, even granting that an unprivileged attacker could
control the occurrence of ENOMEM with some precision, it's a stretch to
believe that he could induce it just where the target buffer contains some
valuable information. So we concluded that the risk of non-hypothetical
problems induced by the patch greatly outweighs the security risks.
We will therefore revert, and instead undertake closer analysis to
identify specific calls that may need hardening, rather than attempt a
universal solution.
We have kept the portion of the previous patch that improved snprintf.c's
handling of errors when it calls the platform's sprintf(). That seems to
be an unalloyed improvement.
Security: CVE-2015-3166
2015-05-20 00:14:52 +02:00
|
|
|
#define sprintf pg_sprintf
|
|
|
|
#define vfprintf pg_vfprintf
|
|
|
|
#define fprintf pg_fprintf
|
2018-10-09 01:15:55 +02:00
|
|
|
#define vprintf pg_vprintf
|
2018-09-26 23:35:01 +02:00
|
|
|
#define printf(...) pg_printf(__VA_ARGS__)
|
2005-03-11 18:20:35 +01:00
|
|
|
|
Improve snprintf.c's handling of NaN, Infinity, and minus zero.
Up to now, float4out/float8out handled NaN and Infinity cases explicitly,
and invoked psprintf only for ordinary float values. This was done because
platform implementations of snprintf produce varying representations of
these special cases. But now that we use snprintf.c always, it's better
to give it the responsibility to produce a uniform representation of
these cases, so that we have uniformity across the board not only in
float4out/float8out. Hence, move that work into fmtfloat().
Also, teach fmtfloat() to recognize IEEE minus zero and handle it
correctly. The previous coding worked only accidentally, and would
fail for e.g. "%+f" format (it'd print "+-0.00000"). Now that we're
using snprintf.c everywhere, it's not acceptable for it to do weird
things in corner cases. (This incidentally avoids a portability
problem we've seen on some really ancient platforms, that native
sprintf does the wrong thing with minus zero.)
Also, introduce a new entry point in snprintf.c to allow float[48]out
to bypass the work of interpreting a well-known format spec, as well
as bypassing the overhead of the psprintf layer. I modeled this API
loosely on strfromd(). In my testing, this brings float[48]out back
to approximately the same speed they had when using native snprintf,
fixing one of the main performance issues caused by using snprintf.c.
(There is some talk of more aggressive work to improve the speed of
floating-point output conversion, but these changes seem to provide
a better starting point for such work anyway.)
Getting rid of the previous ad-hoc hack for Infinity/NaN in fmtfloat()
allows removing <ctype.h> from snprintf.c's #includes. I also removed
a few other #includes that I think are historical, though the buildfarm
may expose that as wrong.
Discussion: https://postgr.es/m/13178.1538794717@sss.pgh.pa.us
2018-10-08 18:19:20 +02:00
|
|
|
/* This is also provided by snprintf.c */
|
|
|
|
extern int pg_strfromd(char *str, size_t count, int precision, double value);
|
|
|
|
|
Convert elog.c's useful_strerror() into a globally-used strerror wrapper.
elog.c has long had a private strerror wrapper that handles assorted
possible failures or deficiencies of the platform's strerror. On Windows,
it also knows how to translate Winsock error codes, which the native
strerror does not. Move all this code into src/port/strerror.c and
define strerror() as a macro that invokes it, so that both our frontend
and backend code will have all of this behavior.
I believe this constitutes an actual bug fix on Windows, since AFAICS
our frontend code did not report Winsock error codes properly before this.
However, the main point is to lay the groundwork for implementing %m
in src/port/snprintf.c: the behavior we want %m to have is this one,
not the native strerror's.
Note that this throws away the prior use of src/port/strerror.c,
which was to implement strerror() on platforms lacking it. That's
been dead code for nigh twenty years now, since strerror() was
already required by C89.
We should likewise cause strerror_r to use this behavior, but
I'll tackle that separately.
Patch by me, reviewed by Michael Paquier
Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
2018-09-26 17:06:42 +02:00
|
|
|
/* Replace strerror() with our own, somewhat more robust wrapper */
|
|
|
|
extern char *pg_strerror(int errnum);
|
|
|
|
#define strerror pg_strerror
|
|
|
|
|
2018-09-26 18:35:57 +02:00
|
|
|
/* Likewise for strerror_r(); note we prefer the GNU API for that */
|
|
|
|
extern char *pg_strerror_r(int errnum, char *buf, size_t buflen);
|
|
|
|
#define strerror_r pg_strerror_r
|
|
|
|
#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */
|
|
|
|
|
2004-02-10 04:42:45 +01:00
|
|
|
/* Portable prompt handling */
|
Simplify correct use of simple_prompt().
The previous API for this function had it returning a malloc'd string.
That meant that callers had to check for NULL return, which few of them
were doing, and it also meant that callers had to remember to free()
the string later, which required extra logic in most cases.
Instead, make simple_prompt() write into a buffer supplied by the caller.
Anywhere that the maximum required input length is reasonably small,
which is almost all of the callers, we can just use a local or static
array as the buffer instead of dealing with malloc/free.
A fair number of callers used "pointer == NULL" as a proxy for "haven't
requested the password yet". Maintaining the same behavior requires
adding a separate boolean flag for that, which adds back some of the
complexity we save by removing free()s. Nonetheless, this nets out
at a small reduction in overall code size, and considerably less code
than we would have had if we'd added the missing NULL-return checks
everywhere they were needed.
In passing, clean up the API comment for simple_prompt() and get rid
of a very-unnecessary malloc/free in its Windows code path.
This is nominally a bug fix, but it does not seem worth back-patching,
because the actual risk of an OOM failure in any of these places seems
pretty tiny, and all of them are client-side not server-side anyway.
This patch is by me, but it owes a great deal to Michael Paquier
who identified the problem and drafted a patch for fixing it the
other way.
Discussion: <CAB7nPqRu07Ot6iht9i9KRfYLpDaF2ZuUv5y_+72uP23ZAGysRg@mail.gmail.com>
2016-08-30 23:02:02 +02:00
|
|
|
extern void simple_prompt(const char *prompt, char *destination, size_t destlen,
|
|
|
|
bool echo);
|
2003-05-15 18:35:30 +02:00
|
|
|
|
2004-08-29 07:07:03 +02:00
|
|
|
extern int pclose_check(FILE *stream);
|
2004-04-05 05:16:21 +02:00
|
|
|
|
2004-09-09 16:18:20 +02:00
|
|
|
/* Global variable holding time zone information. */
|
2016-03-29 02:59:25 +02:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2004-09-09 16:18:20 +02:00
|
|
|
#define TIMEZONE_GLOBAL _timezone
|
|
|
|
#define TZNAME_GLOBAL _tzname
|
2016-03-29 02:59:25 +02:00
|
|
|
#else
|
|
|
|
#define TIMEZONE_GLOBAL timezone
|
|
|
|
#define TZNAME_GLOBAL tzname
|
2004-09-09 16:18:20 +02:00
|
|
|
#endif
|
|
|
|
|
2005-07-06 23:40:09 +02:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2003-05-15 18:35:30 +02:00
|
|
|
/*
|
2007-07-13 01:28:49 +02:00
|
|
|
* Win32 doesn't have reliable rename/unlink during concurrent access.
|
2003-05-15 18:35:30 +02:00
|
|
|
*/
|
2003-08-08 23:42:59 +02:00
|
|
|
extern int pgrename(const char *from, const char *to);
|
|
|
|
extern int pgunlink(const char *path);
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-09-27 22:37:20 +02:00
|
|
|
/* Include this first so later includes don't see these defines */
|
2017-04-11 15:21:25 +02:00
|
|
|
#ifdef _MSC_VER
|
2004-09-27 22:37:20 +02:00
|
|
|
#include <io.h>
|
|
|
|
#endif
|
|
|
|
|
2004-08-07 23:48:09 +02:00
|
|
|
#define rename(from, to) pgrename(from, to)
|
|
|
|
#define unlink(path) pgunlink(path)
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* defined(WIN32) || defined(__CYGWIN__) */
|
2007-07-13 01:28:49 +02:00
|
|
|
|
2004-10-12 00:50:48 +02:00
|
|
|
/*
|
2007-07-13 01:28:49 +02:00
|
|
|
* Win32 also doesn't have symlinks, but we can emulate them with
|
|
|
|
* junction points on newer Win32 versions.
|
|
|
|
*
|
2004-10-12 00:50:48 +02:00
|
|
|
* Cygwin has its own symlinks which work on Win95/98/ME where
|
2007-07-13 01:28:49 +02:00
|
|
|
* junction points don't, so use those instead. We have no way of
|
2004-10-12 00:50:48 +02:00
|
|
|
* knowing what type of system Cygwin binaries will be run on.
|
2005-10-15 04:49:52 +02:00
|
|
|
* Note: Some CYGWIN includes might #define WIN32.
|
2004-10-12 00:50:48 +02:00
|
|
|
*/
|
2004-11-17 18:46:24 +01:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2004-10-12 00:50:48 +02:00
|
|
|
extern int pgsymlink(const char *oldpath, const char *newpath);
|
2011-01-09 15:06:55 +01:00
|
|
|
extern int pgreadlink(const char *path, char *buf, size_t size);
|
2016-11-05 16:14:10 +01:00
|
|
|
extern bool pgwin32_is_junction(const char *path);
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2004-08-07 23:48:09 +02:00
|
|
|
#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)
|
2011-01-09 15:06:55 +01:00
|
|
|
#define readlink(path, buf, size) pgreadlink(path, buf, size)
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
2004-10-12 00:50:48 +02:00
|
|
|
|
2008-04-18 19:05:45 +02:00
|
|
|
extern bool rmtree(const char *path, bool rmtopdir);
|
2004-08-01 08:19:26 +02:00
|
|
|
|
2005-07-06 23:40:09 +02:00
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
2004-03-24 04:54:16 +01:00
|
|
|
|
2008-04-12 01:53:00 +02:00
|
|
|
/*
|
|
|
|
* open() and fopen() replacements to allow deletion of open files and
|
2006-08-30 20:06:27 +02:00
|
|
|
* passing of other special options.
|
|
|
|
*/
|
2007-04-13 12:30:30 +02:00
|
|
|
#define O_DIRECT 0x80000000
|
2006-06-25 02:18:24 +02:00
|
|
|
extern int pgwin32_open(const char *, int,...);
|
2006-08-30 20:06:27 +02:00
|
|
|
extern FILE *pgwin32_fopen(const char *, const char *);
|
2006-10-04 02:30:14 +02:00
|
|
|
#define open(a,b,c) pgwin32_open(a,b,c)
|
2006-08-30 20:06:27 +02:00
|
|
|
#define fopen(a,b) pgwin32_fopen(a,b)
|
2004-03-24 04:54:16 +01:00
|
|
|
|
2014-05-15 11:18:49 +02:00
|
|
|
/*
|
|
|
|
* Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want
|
|
|
|
* to use our popen wrapper, rather than plain _popen, so override that. For
|
|
|
|
* consistency, use our version of pclose, too.
|
|
|
|
*/
|
|
|
|
#ifdef popen
|
|
|
|
#undef popen
|
|
|
|
#endif
|
|
|
|
#ifdef pclose
|
|
|
|
#undef pclose
|
|
|
|
#endif
|
|
|
|
|
Replace SYSTEMQUOTEs with Windows-specific wrapper functions.
It's easy to forget using SYSTEMQUOTEs when constructing command strings
for system() or popen(). Even if we fix all the places missing it now, it is
bound to be forgotten again in the future. Introduce wrapper functions that
do the the extra quoting for you, and get rid of SYSTEMQUOTEs in all the
callers.
We previosly used SYSTEMQUOTEs in all the hard-coded command strings, and
this doesn't change the behavior of those. But user-supplied commands, like
archive_command, restore_command, COPY TO/FROM PROGRAM calls, as well as
pgbench's \shell, will now gain an extra pair of quotes. That is desirable,
but if you have existing scripts or config files that include an extra
pair of quotes, those might need to be adjusted.
Reviewed by Amit Kapila and Tom Lane
2014-05-05 15:07:40 +02:00
|
|
|
/*
|
|
|
|
* system() and popen() replacements to enclose the command in an extra
|
|
|
|
* pair of quotes.
|
|
|
|
*/
|
2014-05-06 18:12:18 +02:00
|
|
|
extern int pgwin32_system(const char *command);
|
Replace SYSTEMQUOTEs with Windows-specific wrapper functions.
It's easy to forget using SYSTEMQUOTEs when constructing command strings
for system() or popen(). Even if we fix all the places missing it now, it is
bound to be forgotten again in the future. Introduce wrapper functions that
do the the extra quoting for you, and get rid of SYSTEMQUOTEs in all the
callers.
We previosly used SYSTEMQUOTEs in all the hard-coded command strings, and
this doesn't change the behavior of those. But user-supplied commands, like
archive_command, restore_command, COPY TO/FROM PROGRAM calls, as well as
pgbench's \shell, will now gain an extra pair of quotes. That is desirable,
but if you have existing scripts or config files that include an extra
pair of quotes, those might need to be adjusted.
Reviewed by Amit Kapila and Tom Lane
2014-05-05 15:07:40 +02:00
|
|
|
extern FILE *pgwin32_popen(const char *command, const char *type);
|
|
|
|
|
|
|
|
#define system(a) pgwin32_system(a)
|
|
|
|
#define popen(a,b) pgwin32_popen(a,b)
|
2004-04-19 19:42:59 +02:00
|
|
|
#define pclose(a) _pclose(a)
|
|
|
|
|
2007-10-29 12:25:42 +01:00
|
|
|
/* New versions of MingW have gettimeofday, old mingw and msvc don't */
|
|
|
|
#ifndef HAVE_GETTIMEOFDAY
|
2003-05-16 06:59:24 +02:00
|
|
|
/* Last parameter not used */
|
2017-06-21 20:39:04 +02:00
|
|
|
extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
|
2007-10-29 12:25:42 +01:00
|
|
|
#endif
|
2005-10-15 04:49:52 +02:00
|
|
|
#else /* !WIN32 */
|
2003-05-16 03:57:52 +02:00
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
/*
|
|
|
|
* Win32 requires a special close for sockets and pipes, while on Unix
|
|
|
|
* close() does them all.
|
|
|
|
*/
|
2003-08-04 02:43:34 +02:00
|
|
|
#define closesocket close
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* WIN32 */
|
2003-08-04 02:43:34 +02:00
|
|
|
|
2014-05-15 21:57:54 +02:00
|
|
|
/*
|
|
|
|
* On Windows, setvbuf() does not support _IOLBF mode, and interprets that
|
|
|
|
* as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0)
|
|
|
|
* crashes outright if "parameter validation" is enabled. Therefore, in
|
|
|
|
* places where we'd like to select line-buffered mode, we fall back to
|
|
|
|
* unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF
|
|
|
|
* directly in order to implement this behavior.
|
|
|
|
*/
|
|
|
|
#ifndef WIN32
|
|
|
|
#define PG_IOLBF _IOLBF
|
|
|
|
#else
|
|
|
|
#define PG_IOLBF _IONBF
|
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
/*
|
|
|
|
* Default "extern" declarations or macro substitutes for library routines.
|
|
|
|
* When necessary, these routines are provided by files in src/port/.
|
|
|
|
*/
|
|
|
|
#ifndef HAVE_CRYPT
|
2003-05-16 03:57:52 +02:00
|
|
|
extern char *crypt(const char *key, const char *setting);
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
|
|
|
|
2017-11-16 16:36:18 +01:00
|
|
|
/* WIN32 handled in port/win32_port.h */
|
2009-01-07 04:39:33 +01:00
|
|
|
#ifndef WIN32
|
|
|
|
#define pgoff_t off_t
|
2012-05-03 16:58:44 +02:00
|
|
|
#ifdef __NetBSD__
|
2004-11-06 02:16:22 +01:00
|
|
|
extern int fseeko(FILE *stream, off_t offset, int whence);
|
|
|
|
extern off_t ftello(FILE *stream);
|
|
|
|
#endif
|
2009-01-07 04:39:33 +01:00
|
|
|
#endif
|
2004-11-06 02:16:22 +01:00
|
|
|
|
2011-08-03 22:26:40 +02:00
|
|
|
extern double pg_erand48(unsigned short xseed[3]);
|
|
|
|
extern long pg_lrand48(void);
|
Replace PostmasterRandom() with a stronger source, second attempt.
This adds a new routine, pg_strong_random() for generating random bytes,
for use in both frontend and backend. At the moment, it's only used in
the backend, but the upcoming SCRAM authentication patches need strong
random numbers in libpq as well.
pg_strong_random() is based on, and replaces, the existing implementation
in pgcrypto. It can acquire strong random numbers from a number of sources,
depending on what's available:
- OpenSSL RAND_bytes(), if built with OpenSSL
- On Windows, the native cryptographic functions are used
- /dev/urandom
Unlike the current pgcrypto function, the source is chosen by configure.
That makes it easier to test different implementations, and ensures that
we don't accidentally fall back to a less secure implementation, if the
primary source fails. All of those methods are quite reliable, it would be
pretty surprising for them to fail, so we'd rather find out by failing
hard.
If no strong random source is available, we fall back to using erand48(),
seeded from current timestamp, like PostmasterRandom() was. That isn't
cryptographically secure, but allows us to still work on platforms that
don't have any of the above stronger sources. Because it's not very secure,
the built-in implementation is only used if explicitly requested with
--disable-strong-random.
This replaces the more complicated Fortuna algorithm we used to have in
pgcrypto, which is unfortunate, but all modern platforms have /dev/urandom,
so it doesn't seem worth the maintenance effort to keep that. pgcrypto
functions that require strong random numbers will be disabled with
--disable-strong-random.
Original patch by Magnus Hagander, tons of further work by Michael Paquier
and me.
Discussion: https://www.postgresql.org/message-id/CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAB7nPqRWkNYRRPJA7-cF+LfroYV10pvjdz6GNvxk-Eee9FypKA@mail.gmail.com
2016-12-05 12:42:59 +01:00
|
|
|
extern long pg_jrand48(unsigned short xseed[3]);
|
2011-08-03 22:26:40 +02:00
|
|
|
extern void pg_srand48(long seed);
|
2009-07-16 19:43:52 +02:00
|
|
|
|
2012-02-07 19:45:46 +01:00
|
|
|
#ifndef HAVE_FLS
|
2012-06-10 21:20:04 +02:00
|
|
|
extern int fls(int mask);
|
2012-02-07 19:45:46 +01:00
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
#ifndef HAVE_FSEEKO
|
2005-05-25 23:40:43 +02:00
|
|
|
#define fseeko(a, b, c) fseek(a, b, c)
|
|
|
|
#define ftello(a) ftell(a)
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
|
|
|
|
2011-06-02 23:27:30 +02:00
|
|
|
#if !defined(HAVE_GETPEEREID) && !defined(WIN32)
|
2011-06-02 19:05:01 +02:00
|
|
|
extern int getpeereid(int sock, uid_t *uid, gid_t *gid);
|
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
#ifndef HAVE_ISINF
|
2003-08-04 02:43:34 +02:00
|
|
|
extern int isinf(double x);
|
2018-03-28 21:45:32 +02:00
|
|
|
#else
|
|
|
|
/*
|
|
|
|
* Glibc doesn't use the builtin for clang due to a *gcc* bug in a version
|
|
|
|
* newer than the gcc compatibility clang claims to have. This would cause a
|
2018-09-01 01:56:11 +02:00
|
|
|
* *lot* of superfluous function calls, therefore revert when using clang. In
|
|
|
|
* C++ there's issues with libc++ (not libstdc++), so disable as well.
|
2018-03-28 21:45:32 +02:00
|
|
|
*/
|
2018-09-01 01:56:11 +02:00
|
|
|
#if defined(__clang__) && !defined(__cplusplus)
|
2018-03-28 21:45:32 +02:00
|
|
|
/* needs to be separate to not confuse other compilers */
|
|
|
|
#if __has_builtin(__builtin_isinf)
|
2018-09-01 01:56:11 +02:00
|
|
|
/* need to include before, to avoid getting overwritten */
|
|
|
|
#include <math.h>
|
2018-03-28 21:45:32 +02:00
|
|
|
#undef isinf
|
|
|
|
#define isinf __builtin_isinf
|
|
|
|
#endif /* __has_builtin(isinf) */
|
Convert elog.c's useful_strerror() into a globally-used strerror wrapper.
elog.c has long had a private strerror wrapper that handles assorted
possible failures or deficiencies of the platform's strerror. On Windows,
it also knows how to translate Winsock error codes, which the native
strerror does not. Move all this code into src/port/strerror.c and
define strerror() as a macro that invokes it, so that both our frontend
and backend code will have all of this behavior.
I believe this constitutes an actual bug fix on Windows, since AFAICS
our frontend code did not report Winsock error codes properly before this.
However, the main point is to lay the groundwork for implementing %m
in src/port/snprintf.c: the behavior we want %m to have is this one,
not the native strerror's.
Note that this throws away the prior use of src/port/strerror.c,
which was to implement strerror() on platforms lacking it. That's
been dead code for nigh twenty years now, since strerror() was
already required by C89.
We should likewise cause strerror_r to use this behavior, but
I'll tackle that separately.
Patch by me, reviewed by Michael Paquier
Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
2018-09-26 17:06:42 +02:00
|
|
|
#endif /* __clang__ && !__cplusplus */
|
2018-03-28 21:45:32 +02:00
|
|
|
#endif /* !HAVE_ISINF */
|
2003-05-15 18:35:30 +02:00
|
|
|
|
2014-10-18 04:55:20 +02:00
|
|
|
#ifndef HAVE_MKDTEMP
|
|
|
|
extern char *mkdtemp(char *path);
|
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
#ifndef HAVE_RINT
|
|
|
|
extern double rint(double x);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_INET_ATON
|
2003-08-04 02:43:34 +02:00
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
2017-06-21 20:39:04 +02:00
|
|
|
extern int inet_aton(const char *cp, struct in_addr *addr);
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
|
|
|
|
2018-11-06 21:50:01 +01:00
|
|
|
/*
|
|
|
|
* Windows and older Unix don't have pread(2) and pwrite(2). We have
|
|
|
|
* replacement functions, but they have slightly different semantics so we'll
|
|
|
|
* use a name with a pg_ prefix to avoid confusion.
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_PREAD
|
|
|
|
#define pg_pread pread
|
|
|
|
#else
|
|
|
|
extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_PWRITE
|
|
|
|
#define pg_pwrite pwrite
|
|
|
|
#else
|
|
|
|
extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset);
|
|
|
|
#endif
|
|
|
|
|
2007-02-07 01:28:55 +01:00
|
|
|
#if !HAVE_DECL_STRLCAT
|
|
|
|
extern size_t strlcat(char *dst, const char *src, size_t siz);
|
|
|
|
#endif
|
|
|
|
|
2006-10-02 02:06:18 +02:00
|
|
|
#if !HAVE_DECL_STRLCPY
|
2006-09-27 18:29:46 +02:00
|
|
|
extern size_t strlcpy(char *dst, const char *src, size_t siz);
|
2003-05-15 18:35:30 +02:00
|
|
|
#endif
|
|
|
|
|
2017-10-10 23:42:16 +02:00
|
|
|
#if !HAVE_DECL_STRNLEN
|
|
|
|
extern size_t strnlen(const char *str, size_t maxlen);
|
|
|
|
#endif
|
|
|
|
|
2017-04-11 15:14:26 +02:00
|
|
|
#if !defined(HAVE_RANDOM)
|
2003-05-15 18:35:30 +02:00
|
|
|
extern long random(void);
|
|
|
|
#endif
|
|
|
|
|
2004-05-07 02:24:59 +02:00
|
|
|
#ifndef HAVE_UNSETENV
|
|
|
|
extern void unsetenv(const char *name);
|
|
|
|
#endif
|
|
|
|
|
2003-05-15 18:35:30 +02:00
|
|
|
#ifndef HAVE_SRANDOM
|
|
|
|
extern void srandom(unsigned int seed);
|
|
|
|
#endif
|
2003-06-14 16:35:42 +02:00
|
|
|
|
2014-07-15 18:04:43 +02:00
|
|
|
#ifndef HAVE_SSL_GET_CURRENT_COMPRESSION
|
|
|
|
#define SSL_get_current_compression(x) 0
|
|
|
|
#endif
|
|
|
|
|
2018-09-06 10:07:24 +02:00
|
|
|
#ifndef HAVE_DLOPEN
|
|
|
|
extern void *dlopen(const char *file, int mode);
|
|
|
|
extern void *dlsym(void *handle, const char *symbol);
|
Convert elog.c's useful_strerror() into a globally-used strerror wrapper.
elog.c has long had a private strerror wrapper that handles assorted
possible failures or deficiencies of the platform's strerror. On Windows,
it also knows how to translate Winsock error codes, which the native
strerror does not. Move all this code into src/port/strerror.c and
define strerror() as a macro that invokes it, so that both our frontend
and backend code will have all of this behavior.
I believe this constitutes an actual bug fix on Windows, since AFAICS
our frontend code did not report Winsock error codes properly before this.
However, the main point is to lay the groundwork for implementing %m
in src/port/snprintf.c: the behavior we want %m to have is this one,
not the native strerror's.
Note that this throws away the prior use of src/port/strerror.c,
which was to implement strerror() on platforms lacking it. That's
been dead code for nigh twenty years now, since strerror() was
already required by C89.
We should likewise cause strerror_r to use this behavior, but
I'll tackle that separately.
Patch by me, reviewed by Michael Paquier
Discussion: https://postgr.es/m/2975.1526862605@sss.pgh.pa.us
2018-09-26 17:06:42 +02:00
|
|
|
extern int dlclose(void *handle);
|
2018-09-06 10:07:24 +02:00
|
|
|
extern char *dlerror(void);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In some older systems, the RTLD_NOW flag isn't defined and the mode
|
|
|
|
* argument to dlopen must always be 1.
|
|
|
|
*/
|
|
|
|
#if !HAVE_DECL_RTLD_NOW
|
|
|
|
#define RTLD_NOW 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The RTLD_GLOBAL flag is wanted if available, but it doesn't exist
|
|
|
|
* everywhere. If it doesn't exist, set it to 0 so it has no effect.
|
|
|
|
*/
|
|
|
|
#if !HAVE_DECL_RTLD_GLOBAL
|
|
|
|
#define RTLD_GLOBAL 0
|
|
|
|
#endif
|
|
|
|
|
2003-06-14 16:35:42 +02:00
|
|
|
/* thread.h */
|
Fix libpq's behavior when /etc/passwd isn't readable.
Some users run their applications in chroot environments that lack an
/etc/passwd file. This means that the current UID's user name and home
directory are not obtainable. libpq used to be all right with that,
so long as the database role name to use was specified explicitly.
But commit a4c8f14364c27508233f8a31ac4b10a4c90235a9 broke such cases by
causing any failure of pg_fe_getauthname() to be treated as a hard error.
In any case it did little to advance its nominal goal of causing errors
in pg_fe_getauthname() to be reported better. So revert that and instead
put some real error-reporting code in place. This requires changes to the
APIs of pg_fe_getauthname() and pqGetpwuid(), since the latter had
departed from the POSIX-specified API of getpwuid_r() in a way that made
it impossible to distinguish actual lookup errors from "no such user".
To allow such failures to be reported, while not failing if the caller
supplies a role name, add a second call of pg_fe_getauthname() in
connectOptions2(). This is a tad ugly, and could perhaps be avoided with
some refactoring of PQsetdbLogin(), but I'll leave that idea for later.
(Note that the complained-of misbehavior only occurs in PQsetdbLogin,
not when using the PQconnect functions, because in the latter we will
never bother to call pg_fe_getauthname() if the user gives a role name.)
In passing also clean up the Windows-side usage of GetUserName(): the
recommended buffer size is 257 bytes, the passed buffer length should
be the buffer size not buffer size less 1, and any error is reported
by GetLastError() not errno.
Per report from Christoph Berg. Back-patch to 9.4 where the chroot
failure case was introduced. The generally poor reporting of errors
here is of very long standing, of course, but given the lack of field
complaints about it we won't risk changing these APIs further back
(even though they're theoretically internal to libpq).
2015-01-11 18:35:44 +01:00
|
|
|
#ifndef WIN32
|
2017-06-21 20:39:04 +02:00
|
|
|
extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
|
|
|
|
size_t buflen, struct passwd **result);
|
2003-09-05 19:43:40 +02:00
|
|
|
#endif
|
2003-06-14 16:35:42 +02:00
|
|
|
|
|
|
|
extern int pqGethostbyname(const char *name,
|
2017-06-21 20:39:04 +02:00
|
|
|
struct hostent *resultbuf,
|
2003-09-13 16:49:51 +02:00
|
|
|
char *buffer, size_t buflen,
|
2017-06-21 20:39:04 +02:00
|
|
|
struct hostent **result,
|
2003-08-04 02:43:34 +02:00
|
|
|
int *herrno);
|
2006-10-04 00:18:23 +02:00
|
|
|
|
2006-10-19 22:56:22 +02:00
|
|
|
extern void pg_qsort(void *base, size_t nel, size_t elsize,
|
2007-11-15 22:14:46 +01:00
|
|
|
int (*cmp) (const void *, const void *));
|
2013-05-29 22:58:43 +02:00
|
|
|
extern int pg_qsort_strcmp(const void *a, const void *b);
|
2006-10-19 22:56:22 +02:00
|
|
|
|
|
|
|
#define qsort(a,b,c,d) pg_qsort(a,b,c,d)
|
|
|
|
|
2006-10-04 00:18:23 +02:00
|
|
|
typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg);
|
|
|
|
|
|
|
|
extern void qsort_arg(void *base, size_t nel, size_t elsize,
|
2006-10-04 02:30:14 +02:00
|
|
|
qsort_arg_comparator cmp, void *arg);
|
2006-10-04 00:18:23 +02:00
|
|
|
|
2007-09-29 00:25:49 +02:00
|
|
|
/* port/chklocale.c */
|
2011-02-08 22:04:18 +01:00
|
|
|
extern int pg_get_encoding_from_locale(const char *ctype, bool write_message);
|
2007-09-29 00:25:49 +02:00
|
|
|
|
Renovate display of non-ASCII messages on Windows.
GNU gettext selects a default encoding for the messages it emits in a
platform-specific manner; it uses the Windows ANSI code page on Windows
and follows LC_CTYPE on other platforms. This is inconvenient for
PostgreSQL server processes, so realize consistent cross-platform
behavior by calling bind_textdomain_codeset() on Windows each time we
permanently change LC_CTYPE. This primarily affects SQL_ASCII databases
and processes like the postmaster that do not attach to a database,
making their behavior consistent with PostgreSQL on non-Windows
platforms. Messages from SQL_ASCII databases use the encoding implied
by the database LC_CTYPE, and messages from non-database processes use
LC_CTYPE from the postmaster system environment. PlatformEncoding
becomes unused, so remove it.
Make write_console() prefer WriteConsoleW() to write() regardless of the
encodings in use. In this situation, write() will invariably mishandle
non-ASCII characters.
elog.c has assumed that messages conform to the database encoding.
While usually true, this does not hold for SQL_ASCII and MULE_INTERNAL.
Introduce MessageEncoding to track the actual encoding of message text.
The present consumers are Windows-specific code for converting messages
to UTF16 for use in system interfaces. This fixes the appearance in
Windows event logs and consoles of translated messages from SQL_ASCII
processes like the postmaster. Note that SQL_ASCII inherently disclaims
a strong notion of encoding, so non-ASCII byte sequences interpolated
into messages by %s may yet yield a nonsensical message. MULE_INTERNAL
has similar problems at present, albeit for a different reason: its lack
of libiconv support or a conversion to UTF8.
Consequently, one need no longer restart Windows with a different
Windows ANSI code page to broadly test backend logging under a given
language. Changing the user's locale ("Format") is enough. Several
accounts can simultaneously run postmasters under different locales, all
correctly logging localized messages to Windows event logs and consoles.
Alexander Law and Noah Misch
2013-06-26 17:17:33 +02:00
|
|
|
#if defined(WIN32) && !defined(FRONTEND)
|
|
|
|
extern int pg_codepage_to_encoding(UINT cp);
|
|
|
|
#endif
|
|
|
|
|
2010-11-24 23:04:19 +01:00
|
|
|
/* port/inet_net_ntop.c */
|
|
|
|
extern char *inet_net_ntop(int af, const void *src, int bits,
|
|
|
|
char *dst, size_t size);
|
|
|
|
|
Replace PostmasterRandom() with a stronger source, second attempt.
This adds a new routine, pg_strong_random() for generating random bytes,
for use in both frontend and backend. At the moment, it's only used in
the backend, but the upcoming SCRAM authentication patches need strong
random numbers in libpq as well.
pg_strong_random() is based on, and replaces, the existing implementation
in pgcrypto. It can acquire strong random numbers from a number of sources,
depending on what's available:
- OpenSSL RAND_bytes(), if built with OpenSSL
- On Windows, the native cryptographic functions are used
- /dev/urandom
Unlike the current pgcrypto function, the source is chosen by configure.
That makes it easier to test different implementations, and ensures that
we don't accidentally fall back to a less secure implementation, if the
primary source fails. All of those methods are quite reliable, it would be
pretty surprising for them to fail, so we'd rather find out by failing
hard.
If no strong random source is available, we fall back to using erand48(),
seeded from current timestamp, like PostmasterRandom() was. That isn't
cryptographically secure, but allows us to still work on platforms that
don't have any of the above stronger sources. Because it's not very secure,
the built-in implementation is only used if explicitly requested with
--disable-strong-random.
This replaces the more complicated Fortuna algorithm we used to have in
pgcrypto, which is unfortunate, but all modern platforms have /dev/urandom,
so it doesn't seem worth the maintenance effort to keep that. pgcrypto
functions that require strong random numbers will be disabled with
--disable-strong-random.
Original patch by Magnus Hagander, tons of further work by Michael Paquier
and me.
Discussion: https://www.postgresql.org/message-id/CAB7nPqRy3krN8quR9XujMVVHYtXJ0_60nqgVc6oUk8ygyVkZsA@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAB7nPqRWkNYRRPJA7-cF+LfroYV10pvjdz6GNvxk-Eee9FypKA@mail.gmail.com
2016-12-05 12:42:59 +01:00
|
|
|
/* port/pg_strong_random.c */
|
|
|
|
#ifdef HAVE_STRONG_RANDOM
|
|
|
|
extern bool pg_strong_random(void *buf, size_t len);
|
|
|
|
#endif
|
|
|
|
|
2010-12-11 01:42:44 +01:00
|
|
|
/* port/pgcheckdir.c */
|
|
|
|
extern int pg_check_dir(const char *dir);
|
|
|
|
|
|
|
|
/* port/pgmkdirp.c */
|
|
|
|
extern int pg_mkdir_p(char *path, int omode);
|
|
|
|
|
2013-03-17 17:06:42 +01:00
|
|
|
/* port/pqsignal.c */
|
|
|
|
typedef void (*pqsigfunc) (int signo);
|
|
|
|
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
|
Run the postmaster's signal handlers without SA_RESTART.
The postmaster keeps signals blocked everywhere except while waiting
for something to happen in ServerLoop(). The code expects that the
select(2) will be cancelled with EINTR if an interrupt occurs; without
that, followup actions that should be performed by ServerLoop() itself
will be delayed. However, some platforms interpret the SA_RESTART
signal flag as meaning that they should restart rather than cancel
the select(2). Worse yet, some of them restart it with the original
timeout delay, meaning that a steady stream of signal interrupts can
prevent ServerLoop() from iterating at all if there are no incoming
connection requests.
Observable symptoms of this, on an affected platform such as HPUX 10,
include extremely slow parallel query startup (possibly as much as
30 seconds) and failure to update timestamps on the postmaster's sockets
and lockfiles when no new connections arrive for a long time.
We can fix this by running the postmaster's signal handlers without
SA_RESTART. That would be quite a scary change if the range of code
where signals are accepted weren't so tiny, but as it is, it seems
safe enough. (Note that postmaster children do, and must, reset all
the handlers before unblocking signals; so this change should not
affect any child process.)
There is talk of rewriting the postmaster to use a WaitEventSet and
not do signal response work in signal handlers, at which point it might
be appropriate to revert this patch. But that's not happening before
v11 at the earliest.
Back-patch to 9.6. The problem exists much further back, but the
worst symptom arises only in connection with parallel query, so it
does not seem worth taking any portability risks in older branches.
Discussion: https://postgr.es/m/9205.1492833041@sss.pgh.pa.us
2017-04-24 19:00:23 +02:00
|
|
|
#ifndef WIN32
|
|
|
|
extern pqsigfunc pqsignal_no_restart(int signo, pqsigfunc func);
|
|
|
|
#else
|
|
|
|
#define pqsignal_no_restart(signo, func) pqsignal(signo, func)
|
|
|
|
#endif
|
2013-03-17 17:06:42 +01:00
|
|
|
|
2013-01-05 15:40:19 +01:00
|
|
|
/* port/quotes.c */
|
|
|
|
extern char *escape_single_quotes_ascii(const char *src);
|
|
|
|
|
Add support for piping COPY to/from an external program.
This includes backend "COPY TO/FROM PROGRAM '...'" syntax, and corresponding
psql \copy syntax. Like with reading/writing files, the backend version is
superuser-only, and in the psql version, the program is run in the client.
In the passing, the psql \copy STDIN/STDOUT syntax is subtly changed: if you
the stdin/stdout is quoted, it's now interpreted as a filename. For example,
"\copy foo from 'stdin'" now reads from a file called 'stdin', not from
standard input. Before this, there was no way to specify a filename called
stdin, stdout, pstdin or pstdout.
This creates a new function in pgport, wait_result_to_str(), which can
be used to convert the exit status of a process, as returned by wait(3),
to a human-readable string.
Etsuro Fujita, reviewed by Amit Kapila.
2013-02-27 17:17:21 +01:00
|
|
|
/* port/wait_error.c */
|
|
|
|
extern char *wait_result_to_str(int exit_status);
|
Improve detection of child-process SIGPIPE failures.
Commit ffa4cbd62 added logic to detect SIGPIPE failure of a COPY child
process, but it only worked correctly if the SIGPIPE occurred in the
immediate child process. Depending on the shell in use and the
complexity of the shell command string, we might instead get back
an exit code of 128 + SIGPIPE, representing a shell error exit
reporting SIGPIPE in the child process.
We could just hack up ClosePipeToProgram() to add the extra case,
but it seems like this is a fairly general issue deserving a more
general and better-documented solution. I chose to add a couple
of functions in src/common/wait_error.c, which is a natural place
to know about wait-result encodings, that will test for either a
specific child-process signal type or any child-process signal failure.
Then, adjust other places that were doing ad-hoc tests of this type
to use the common functions.
In RestoreArchivedFile, this fixes a race condition affecting whether
the process will report an error or just silently proc_exit(1): before,
that depended on whether the intermediate shell got SIGTERM'd itself
or reported a child process failing on SIGTERM.
Like the previous patch, back-patch to v10; we could go further
but there seems no real need to.
Per report from Erik Rijkers.
Discussion: https://postgr.es/m/f3683f87ab1701bea5d86a7742b22432@xs4all.nl
2018-12-16 20:32:14 +01:00
|
|
|
extern bool wait_result_is_signal(int exit_status, int signum);
|
|
|
|
extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found);
|
Add support for piping COPY to/from an external program.
This includes backend "COPY TO/FROM PROGRAM '...'" syntax, and corresponding
psql \copy syntax. Like with reading/writing files, the backend version is
superuser-only, and in the psql version, the program is run in the client.
In the passing, the psql \copy STDIN/STDOUT syntax is subtly changed: if you
the stdin/stdout is quoted, it's now interpreted as a filename. For example,
"\copy foo from 'stdin'" now reads from a file called 'stdin', not from
standard input. Before this, there was no way to specify a filename called
stdin, stdout, pstdin or pstdout.
This creates a new function in pgport, wait_result_to_str(), which can
be used to convert the exit status of a process, as returned by wait(3),
to a human-readable string.
Etsuro Fujita, reviewed by Amit Kapila.
2013-02-27 17:17:21 +01:00
|
|
|
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
#endif /* PG_PORT_H */
|