From 8396447cdbdff0b62914748de2fec04281dc9114 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Tue, 12 Feb 2013 10:33:40 -0300 Subject: [PATCH] Create libpgcommon, and move pg_malloc et al to it MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit libpgcommon is a new static library to allow sharing code among the various frontend programs and backend; this lets us eliminate duplicate implementations of common routines. We avoid libpgport, because that's intended as a place for porting issues; per discussion, it seems better to keep them separate. The first use case, and the only implemented by this patch, is pg_malloc and friends, which many frontend programs were already using. At the same time, we can use this to provide palloc emulation functions for the frontend; this way, some palloc-using files in the backend can also be used by the frontend cleanly. To do this, we change palloc() in the backend to be a function instead of a macro on top of MemoryContextAlloc(). This was previously believed to cause loss of performance, but this implementation has been tweaked by Tom and Andres so that on modern compilers it provides a slight improvement over the previous one. This lets us clean up some places that were already with localized hacks. Most of the pg_malloc/palloc changes in this patch were authored by Andres Freund. Zoltán Böszörményi also independently provided a form of that. libpgcommon infrastructure was authored by Álvaro. --- contrib/oid2name/oid2name.c | 50 ---------- contrib/pg_upgrade/check.c | 2 +- contrib/pg_upgrade/controldata.c | 2 +- contrib/pg_upgrade/dump.c | 2 +- contrib/pg_upgrade/exec.c | 2 +- contrib/pg_upgrade/file.c | 2 +- contrib/pg_upgrade/function.c | 2 +- contrib/pg_upgrade/info.c | 2 +- contrib/pg_upgrade/option.c | 2 +- contrib/pg_upgrade/page.c | 2 +- contrib/pg_upgrade/parallel.c | 2 +- contrib/pg_upgrade/pg_upgrade.c | 2 +- contrib/pg_upgrade/pg_upgrade.h | 4 - contrib/pg_upgrade/relfilenode.c | 2 +- contrib/pg_upgrade/server.c | 2 +- contrib/pg_upgrade/tablespace.c | 2 +- contrib/pg_upgrade/util.c | 51 +--------- contrib/pg_upgrade/version.c | 2 +- contrib/pg_upgrade/version_old_8_3.c | 2 +- contrib/pgbench/pgbench.c | 53 ----------- src/Makefile | 1 + src/Makefile.global.in | 25 ++--- src/backend/storage/file/copydir.c | 11 --- src/backend/utils/mmgr/mcxt.c | 78 ++++++++-------- src/bin/initdb/initdb.c | 39 -------- src/bin/pg_basebackup/streamutil.c | 37 -------- src/bin/pg_basebackup/streamutil.h | 4 - src/bin/pg_ctl/pg_ctl.c | 38 -------- src/bin/pg_dump/Makefile | 6 +- src/bin/pg_dump/common.c | 2 - src/bin/pg_dump/compress_io.c | 1 - src/bin/pg_dump/dumpmem.c | 76 --------------- src/bin/pg_dump/dumpmem.h | 22 ----- src/bin/pg_dump/dumputils.c | 1 - src/bin/pg_dump/nls.mk | 2 +- src/bin/pg_dump/pg_backup_archiver.c | 1 - src/bin/pg_dump/pg_backup_custom.c | 1 - src/bin/pg_dump/pg_backup_db.c | 1 - src/bin/pg_dump/pg_backup_directory.c | 1 - src/bin/pg_dump/pg_backup_null.c | 1 - src/bin/pg_dump/pg_backup_tar.c | 1 - src/bin/pg_dump/pg_dump.c | 1 - src/bin/pg_dump/pg_dump_sort.c | 1 - src/bin/pg_dump/pg_dumpall.c | 1 - src/bin/pg_dump/pg_restore.c | 1 - src/bin/pg_resetxlog/pg_resetxlog.c | 5 +- src/bin/psql/common.c | 50 ---------- src/bin/psql/common.h | 9 -- src/bin/scripts/common.c | 49 ---------- src/bin/scripts/common.h | 4 - src/common/Makefile | 64 +++++++++++++ src/common/fe_memutils.c | 128 ++++++++++++++++++++++++++ src/include/common/fe_memutils.h | 20 ++++ src/include/postgres_fe.h | 2 + src/include/utils/palloc.h | 30 ++---- src/port/dirmod.c | 74 --------------- src/tools/msvc/Install.pm | 1 + src/tools/msvc/Mkvcbuild.pm | 35 +++++-- src/tools/msvc/Project.pm | 2 +- 59 files changed, 332 insertions(+), 684 deletions(-) delete mode 100644 src/bin/pg_dump/dumpmem.c delete mode 100644 src/bin/pg_dump/dumpmem.h create mode 100644 src/common/Makefile create mode 100644 src/common/fe_memutils.c create mode 100644 src/include/common/fe_memutils.h diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c index a666731e72..d8ed06f420 100644 --- a/contrib/oid2name/oid2name.c +++ b/contrib/oid2name/oid2name.c @@ -50,9 +50,6 @@ struct options /* function prototypes */ static void help(const char *progname); void get_opts(int, char **, struct options *); -void *pg_malloc(size_t size); -void *pg_realloc(void *ptr, size_t size); -char *pg_strdup(const char *str); void add_one_elt(char *eltname, eary *eary); char *get_comma_elts(eary *eary); PGconn *sql_conn(struct options *); @@ -201,53 +198,6 @@ help(const char *progname) progname, progname); } -void * -pg_malloc(size_t size) -{ - void *ptr; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - ptr = malloc(size); - if (!ptr) - { - fprintf(stderr, "out of memory\n"); - exit(1); - } - return ptr; -} - -void * -pg_realloc(void *ptr, size_t size) -{ - void *result; - - /* Avoid unportable behavior of realloc(NULL, 0) */ - if (ptr == NULL && size == 0) - size = 1; - result = realloc(ptr, size); - if (!result) - { - fprintf(stderr, "out of memory\n"); - exit(1); - } - return result; -} - -char * -pg_strdup(const char *str) -{ - char *result = strdup(str); - - if (!result) - { - fprintf(stderr, "out of memory\n"); - exit(1); - } - return result; -} - /* * add_one_elt * diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c index 818864346e..a7d4a68ce3 100644 --- a/contrib/pg_upgrade/check.c +++ b/contrib/pg_upgrade/check.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/check.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/controldata.c b/contrib/pg_upgrade/controldata.c index 01c66776e4..0d9a64c967 100644 --- a/contrib/pg_upgrade/controldata.c +++ b/contrib/pg_upgrade/controldata.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/controldata.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/dump.c b/contrib/pg_upgrade/dump.c index 9c6c2773bb..66d4846eae 100644 --- a/contrib/pg_upgrade/dump.c +++ b/contrib/pg_upgrade/dump.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/dump.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c index 44dafc36a9..af752a66d0 100644 --- a/contrib/pg_upgrade/exec.c +++ b/contrib/pg_upgrade/exec.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/exec.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/file.c b/contrib/pg_upgrade/file.c index f76dcb6682..62e8deb69b 100644 --- a/contrib/pg_upgrade/file.c +++ b/contrib/pg_upgrade/file.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/file.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c index 7bb5f915f6..b24e43eeba 100644 --- a/contrib/pg_upgrade/function.c +++ b/contrib/pg_upgrade/function.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/function.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c index 7fd4584dff..1905c4399d 100644 --- a/contrib/pg_upgrade/info.c +++ b/contrib/pg_upgrade/info.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/info.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/option.c b/contrib/pg_upgrade/option.c index d5d94c7097..aee8d3d153 100644 --- a/contrib/pg_upgrade/option.c +++ b/contrib/pg_upgrade/option.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/option.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "miscadmin.h" diff --git a/contrib/pg_upgrade/page.c b/contrib/pg_upgrade/page.c index d11d227fa9..fb044d1b62 100644 --- a/contrib/pg_upgrade/page.c +++ b/contrib/pg_upgrade/page.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/page.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/parallel.c b/contrib/pg_upgrade/parallel.c index d157511781..688a53112c 100644 --- a/contrib/pg_upgrade/parallel.c +++ b/contrib/pg_upgrade/parallel.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/parallel.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c index 55155d22e2..3089a72fe5 100644 --- a/contrib/pg_upgrade/pg_upgrade.c +++ b/contrib/pg_upgrade/pg_upgrade.c @@ -35,7 +35,7 @@ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index 69b9c6030b..c110e45c36 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -451,10 +451,6 @@ void prep_status(const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); void check_ok(void); -char *pg_strdup(const char *s); -void *pg_malloc(size_t size); -void *pg_realloc(void *ptr, size_t size); -void pg_free(void *ptr); const char *getErrorText(int errNum); unsigned int str2uint(const char *str); void pg_putenv(const char *var, const char *val); diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c index 552f2033c2..56c702e258 100644 --- a/contrib/pg_upgrade/relfilenode.c +++ b/contrib/pg_upgrade/relfilenode.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/relfilenode.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c index d1a3f76eff..ed6775935b 100644 --- a/contrib/pg_upgrade/server.c +++ b/contrib/pg_upgrade/server.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/server.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/tablespace.c b/contrib/pg_upgrade/tablespace.c index 321738dabc..805e402d4a 100644 --- a/contrib/pg_upgrade/tablespace.c +++ b/contrib/pg_upgrade/tablespace.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/tablespace.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c index c91003a46d..4e51ed72e9 100644 --- a/contrib/pg_upgrade/util.c +++ b/contrib/pg_upgrade/util.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/util.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" @@ -213,55 +213,6 @@ get_user_info(char **user_name) } -void * -pg_malloc(size_t size) -{ - void *p; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - p = malloc(size); - if (p == NULL) - pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname); - return p; -} - -void * -pg_realloc(void *ptr, size_t size) -{ - void *p; - - /* Avoid unportable behavior of realloc(NULL, 0) */ - if (ptr == NULL && size == 0) - size = 1; - p = realloc(ptr, size); - if (p == NULL) - pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname); - return p; -} - - -void -pg_free(void *ptr) -{ - if (ptr != NULL) - free(ptr); -} - - -char * -pg_strdup(const char *s) -{ - char *result = strdup(s); - - if (result == NULL) - pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname); - - return result; -} - - /* * getErrorText() * diff --git a/contrib/pg_upgrade/version.c b/contrib/pg_upgrade/version.c index 80383cd1a6..5fe7ec4520 100644 --- a/contrib/pg_upgrade/version.c +++ b/contrib/pg_upgrade/version.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/version.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pg_upgrade/version_old_8_3.c b/contrib/pg_upgrade/version_old_8_3.c index a224be1ab8..4551d68ba4 100644 --- a/contrib/pg_upgrade/version_old_8_3.c +++ b/contrib/pg_upgrade/version_old_8_3.c @@ -7,7 +7,7 @@ * contrib/pg_upgrade/version_old_8_3.c */ -#include "postgres.h" +#include "postgres_fe.h" #include "pg_upgrade.h" diff --git a/contrib/pgbench/pgbench.c b/contrib/pgbench/pgbench.c index 11c006209f..d5f8f73190 100644 --- a/contrib/pgbench/pgbench.c +++ b/contrib/pgbench/pgbench.c @@ -320,59 +320,6 @@ static char *select_only = { static void setalarm(int seconds); static void *threadRun(void *arg); - -/* - * routines to check mem allocations and fail noisily. - */ -static void * -pg_malloc(size_t size) -{ - void *result; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - result = malloc(size); - if (!result) - { - fprintf(stderr, "out of memory\n"); - exit(1); - } - return result; -} - -static void * -pg_realloc(void *ptr, size_t size) -{ - void *result; - - /* Avoid unportable behavior of realloc(NULL, 0) */ - if (ptr == NULL && size == 0) - size = 1; - result = realloc(ptr, size); - if (!result) - { - fprintf(stderr, "out of memory\n"); - exit(1); - } - return result; -} - -static char * -pg_strdup(const char *s) -{ - char *result; - - result = strdup(s); - if (!result) - { - fprintf(stderr, "out of memory\n"); - exit(1); - } - return result; -} - - static void usage(void) { diff --git a/src/Makefile b/src/Makefile index a0460342e8..e859826dc4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,6 +13,7 @@ top_builddir = .. include Makefile.global SUBDIRS = \ + common \ port \ timezone \ backend \ diff --git a/src/Makefile.global.in b/src/Makefile.global.in index ecfb80147f..1077e0b98a 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -243,14 +243,15 @@ LD = @LD@ with_gnu_ld = @with_gnu_ld@ ld_R_works = @ld_R_works@ -# We want -L for libpgport.a to be first in LDFLAGS. We also need LDFLAGS -# to be a "recursively expanded" variable, else adjustments to rpathdir -# don't work right. So we must NOT do LDFLAGS := something, meaning this has -# to be done first and elsewhere we must only do LDFLAGS += something. +# We want -L for libpgport.a and libpgcommon.a to be first in LDFLAGS. We +# also need LDFLAGS to be a "recursively expanded" variable, else adjustments +# to rpathdir don't work right. So we must NOT do LDFLAGS := something, +# meaning this has to be done first and elsewhere we must only do LDFLAGS += +# something. ifdef PGXS LDFLAGS = -L$(libdir) else - LDFLAGS = -L$(top_builddir)/src/port + LDFLAGS = -L$(top_builddir)/src/port -L$(top_builddir)/src/common endif LDFLAGS += @LDFLAGS@ @@ -400,16 +401,17 @@ endif libpq = -L$(libpq_builddir) -lpq # This macro is for use by client executables (not libraries) that use libpq. -# We force clients to pull symbols from the non-shared library libpgport -# rather than pulling some libpgport symbols from libpq just because -# libpq uses those functions too. This makes applications less +# We force clients to pull symbols from the non-shared libraries libpgport +# and libpgcommon rather than pulling some libpgport symbols from libpq just +# because libpq uses those functions too. This makes applications less # dependent on changes in libpq's usage of pgport. To do this we link to # pgport before libpq. This does cause duplicate -lpgport's to appear # on client link lines. ifdef PGXS -libpq_pgport = -L$(libdir) -lpgport $(libpq) +libpq_pgport = -L$(libdir) -lpgport -lpgcommon $(libpq) else -libpq_pgport = -L$(top_builddir)/src/port -lpgport $(libpq) +libpq_pgport = -L$(top_builddir)/src/port -lpgport \ + -L$(top_builddir)/src/common -lpgcommon $(libpq) endif @@ -418,6 +420,7 @@ submake-libpq: submake-libpgport: $(MAKE) -C $(top_builddir)/src/port all + $(MAKE) -C $(top_builddir)/src/common all .PHONY: submake-libpq submake-libpgport @@ -496,7 +499,7 @@ endif LIBOBJS = @LIBOBJS@ -LIBS := -lpgport $(LIBS) +LIBS := -lpgport -lpgcommon $(LIBS) # to make ws2_32.lib the last library, and always link with shfolder, # so SHGetFolderName isn't picked up from shell32.dll diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c index 017f862dc0..391359cdd9 100644 --- a/src/backend/storage/file/copydir.c +++ b/src/backend/storage/file/copydir.c @@ -26,17 +26,6 @@ #include "storage/fd.h" #include "miscadmin.h" -/* - * On Windows, call non-macro versions of palloc; we can't reference - * CurrentMemoryContext in this file because of PGDLLIMPORT conflict. - */ -#if defined(WIN32) || defined(__CYGWIN__) -#undef palloc -#undef pstrdup -#define palloc(sz) pgport_palloc(sz) -#define pstrdup(str) pgport_pstrdup(str) -#endif - static void fsync_fname(char *fname, bool isdir); diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index d71f206dee..8dd3cf4889 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -634,6 +634,42 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size) return ret; } +void * +palloc(Size size) +{ + /* duplicates MemoryContextAlloc to avoid increased overhead */ + AssertArg(MemoryContextIsValid(CurrentMemoryContext)); + + if (!AllocSizeIsValid(size)) + elog(ERROR, "invalid memory alloc request size %lu", + (unsigned long) size); + + CurrentMemoryContext->isReset = false; + + return (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); +} + +void * +palloc0(Size size) +{ + /* duplicates MemoryContextAllocZero to avoid increased overhead */ + void *ret; + + AssertArg(MemoryContextIsValid(CurrentMemoryContext)); + + if (!AllocSizeIsValid(size)) + elog(ERROR, "invalid memory alloc request size %lu", + (unsigned long) size); + + CurrentMemoryContext->isReset = false; + + ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size); + + MemSetAligned(ret, 0, size); + + return ret; +} + /* * pfree * Release an allocated chunk. @@ -715,6 +751,12 @@ MemoryContextStrdup(MemoryContext context, const char *string) return nstr; } +char * +pstrdup(const char *in) +{ + return MemoryContextStrdup(CurrentMemoryContext, in); +} + /* * pnstrdup * Like pstrdup(), but append null byte to a @@ -729,39 +771,3 @@ pnstrdup(const char *in, Size len) out[len] = '\0'; return out; } - - -#if defined(WIN32) || defined(__CYGWIN__) -/* - * Memory support routines for libpgport on Win32 - * - * Win32 can't load a library that PGDLLIMPORTs a variable - * if the link object files also PGDLLIMPORT the same variable. - * For this reason, libpgport can't reference CurrentMemoryContext - * in the palloc macro calls. - * - * To fix this, we create several functions here that allow us to - * manage memory without doing the inline in libpgport. - */ -void * -pgport_palloc(Size sz) -{ - return palloc(sz); -} - - -char * -pgport_pstrdup(const char *str) -{ - return pstrdup(str); -} - - -/* Doesn't reference a PGDLLIMPORT variable, but here for completeness. */ -void -pgport_pfree(void *pointer) -{ - pfree(pointer); -} - -#endif diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index b75d976856..2ea3f6ed02 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -200,8 +200,6 @@ const char *subdirs[] = { static char bin_path[MAXPGPATH]; static char backend_exec[MAXPGPATH]; -static void *pg_malloc(size_t size); -static char *pg_strdup(const char *s); static char **replace_token(char **lines, const char *token, const char *replacement); @@ -317,43 +315,6 @@ do { \ #define DIR_SEP "\\" #endif -/* - * routines to check mem allocations and fail noisily. - * - * Note that we can't call exit_nicely() on a memory failure, as it calls - * rmtree() which needs memory allocation. So we just exit with a bang. - */ -static void * -pg_malloc(size_t size) -{ - void *result; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - result = malloc(size); - if (!result) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - exit(1); - } - return result; -} - -static char * -pg_strdup(const char *s) -{ - char *result; - - result = strdup(s); - if (!result) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - exit(1); - } - return result; -} - static char * escape_quotes(const char *src) { diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 71abbfa9de..8a43c4bad1 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -25,43 +25,6 @@ int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */ static char *dbpassword = NULL; PGconn *conn = NULL; -/* - * strdup() and malloc() replacements that print an error and exit - * if something goes wrong. Can never return NULL. - */ -char * -pg_strdup(const char *s) -{ - char *result; - - result = strdup(s); - if (!result) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - exit(1); - } - return result; -} - -void * -pg_malloc0(size_t size) -{ - void *result; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - result = malloc(size); - if (!result) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - exit(1); - } - MemSet(result, 0, size); - return result; -} - - /* * Connect to the server. Returns a valid PGconn pointer if connected, * or NULL on non-permanent error. On permanent error, the function will diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h index fdf3641861..4f5ff914e2 100644 --- a/src/bin/pg_basebackup/streamutil.h +++ b/src/bin/pg_basebackup/streamutil.h @@ -15,8 +15,4 @@ extern PGconn *conn; exit(code); \ } - -extern char *pg_strdup(const char *s); -extern void *pg_malloc0(size_t size); - extern PGconn *GetConnection(void); diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index e086b1244c..04de977e3f 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -118,8 +118,6 @@ write_stderr(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); -static void *pg_malloc(size_t size); -static char *pg_strdup(const char *s); static void do_advice(void); static void do_help(void); static void set_mode(char *modeopt); @@ -225,42 +223,6 @@ write_stderr(const char *fmt,...) va_end(ap); } -/* - * routines to check memory allocations and fail noisily. - */ - -static void * -pg_malloc(size_t size) -{ - void *result; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - result = malloc(size); - if (!result) - { - write_stderr(_("%s: out of memory\n"), progname); - exit(1); - } - return result; -} - - -static char * -pg_strdup(const char *s) -{ - char *result; - - result = strdup(s); - if (!result) - { - write_stderr(_("%s: out of memory\n"), progname); - exit(1); - } - return result; -} - /* * Given an already-localized string, print it to stdout unless the * user has specified that no messages should be printed. diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile index 57aea6f813..a6ab39d347 100644 --- a/src/bin/pg_dump/Makefile +++ b/src/bin/pg_dump/Makefile @@ -20,7 +20,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \ pg_backup_null.o pg_backup_tar.o \ - pg_backup_directory.o dumpmem.o dumputils.o compress_io.o $(WIN32RES) + pg_backup_directory.o dumputils.o compress_io.o $(WIN32RES) KEYWRDOBJS = keywords.o kwlookup.o @@ -35,8 +35,8 @@ pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport $(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) -pg_dumpall: pg_dumpall.o dumputils.o dumpmem.o $(KEYWRDOBJS) | submake-libpq submake-libpgport - $(CC) $(CFLAGS) pg_dumpall.o dumputils.o dumpmem.o $(KEYWRDOBJS) $(WIN32RES) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) +pg_dumpall: pg_dumpall.o dumputils.o $(KEYWRDOBJS) | submake-libpq submake-libpgport + $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(KEYWRDOBJS) $(WIN32RES) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) install: all installdirs $(INSTALL_PROGRAM) pg_dump$(X) '$(DESTDIR)$(bindir)'/pg_dump$(X) diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index 706b9a75e3..01739ab717 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -18,8 +18,6 @@ #include #include "catalog/pg_class.h" -#include "dumpmem.h" -#include "dumputils.h" /* diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c index aac991bd10..768b923ae5 100644 --- a/src/bin/pg_dump/compress_io.c +++ b/src/bin/pg_dump/compress_io.c @@ -53,7 +53,6 @@ */ #include "compress_io.h" -#include "dumpmem.h" #include "dumputils.h" /*---------------------- diff --git a/src/bin/pg_dump/dumpmem.c b/src/bin/pg_dump/dumpmem.c deleted file mode 100644 index d96655e7f4..0000000000 --- a/src/bin/pg_dump/dumpmem.c +++ /dev/null @@ -1,76 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dumpmem.c - * Memory allocation routines used by pg_dump, pg_dumpall, and pg_restore - * - * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/bin/pg_dump/dumpmem.c - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include "dumputils.h" -#include "dumpmem.h" - - -/* - * Safer versions of some standard C library functions. If an - * out-of-memory condition occurs, these functions will bail out via exit(); - *therefore, their return value is guaranteed to be non-NULL. - */ - -char * -pg_strdup(const char *string) -{ - char *tmp; - - if (!string) - exit_horribly(NULL, "cannot duplicate null pointer\n"); - tmp = strdup(string); - if (!tmp) - exit_horribly(NULL, "out of memory\n"); - return tmp; -} - -void * -pg_malloc(size_t size) -{ - void *tmp; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - tmp = malloc(size); - if (!tmp) - exit_horribly(NULL, "out of memory\n"); - return tmp; -} - -void * -pg_malloc0(size_t size) -{ - void *tmp; - - tmp = pg_malloc(size); - MemSet(tmp, 0, size); - return tmp; -} - -void * -pg_realloc(void *ptr, size_t size) -{ - void *tmp; - - /* Avoid unportable behavior of realloc(NULL, 0) */ - if (ptr == NULL && size == 0) - size = 1; - tmp = realloc(ptr, size); - if (!tmp) - exit_horribly(NULL, "out of memory\n"); - return tmp; -} diff --git a/src/bin/pg_dump/dumpmem.h b/src/bin/pg_dump/dumpmem.h deleted file mode 100644 index 0a4ab1bed3..0000000000 --- a/src/bin/pg_dump/dumpmem.h +++ /dev/null @@ -1,22 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dumpmem.h - * Memory allocation routines used by pg_dump, pg_dumpall, and pg_restore - * - * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/bin/pg_dump/dumpmem.h - * - *------------------------------------------------------------------------- - */ - -#ifndef DUMPMEM_H -#define DUMPMEM_H - -extern char *pg_strdup(const char *string); -extern void *pg_malloc(size_t size); -extern void *pg_malloc0(size_t size); -extern void *pg_realloc(void *ptr, size_t size); - -#endif /* DUMPMEM_H */ diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 7ca0c60f3e..0a09882f5d 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -17,7 +17,6 @@ #include #include "dumputils.h" -#include "dumpmem.h" #include "parser/keywords.h" diff --git a/src/bin/pg_dump/nls.mk b/src/bin/pg_dump/nls.mk index 8bf6ec9b5e..84486003d0 100644 --- a/src/bin/pg_dump/nls.mk +++ b/src/bin/pg_dump/nls.mk @@ -3,7 +3,7 @@ CATALOG_NAME = pg_dump AVAIL_LANGUAGES = de es fr it ja ko pt_BR sv tr zh_CN zh_TW GETTEXT_FILES = pg_backup_archiver.c pg_backup_db.c pg_backup_custom.c \ pg_backup_null.c pg_backup_tar.c \ - pg_backup_directory.c dumpmem.c dumputils.c compress_io.c \ + pg_backup_directory.c dumputils.c compress_io.c \ pg_dump.c common.c pg_dump_sort.c \ pg_restore.c pg_dumpall.c \ ../../port/exec.c diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index a810efd3bb..1c663cd14f 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -21,7 +21,6 @@ */ #include "pg_backup_db.h" -#include "dumpmem.h" #include "dumputils.h" #include diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c index c9adc6f82f..7081598baa 100644 --- a/src/bin/pg_dump/pg_backup_custom.c +++ b/src/bin/pg_dump/pg_backup_custom.c @@ -26,7 +26,6 @@ #include "compress_io.h" #include "dumputils.h" -#include "dumpmem.h" /*-------- * Routines in the format interface diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index c295fc5ddd..21c203e8e7 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -11,7 +11,6 @@ */ #include "pg_backup_db.h" -#include "dumpmem.h" #include "dumputils.h" #include diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index 2dcf7be80d..5b71ebaeeb 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -34,7 +34,6 @@ */ #include "compress_io.h" -#include "dumpmem.h" #include "dumputils.h" #include diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c index ba1e461af4..6ac81982b8 100644 --- a/src/bin/pg_dump/pg_backup_null.c +++ b/src/bin/pg_dump/pg_backup_null.c @@ -23,7 +23,6 @@ */ #include "pg_backup_archiver.h" -#include "dumpmem.h" #include "dumputils.h" #include /* for dup */ diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index d090612d0f..03ae4f82bc 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -31,7 +31,6 @@ #include "pg_backup.h" #include "pg_backup_archiver.h" #include "pg_backup_tar.h" -#include "dumpmem.h" #include "dumputils.h" #include "pgtar.h" diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 9f1ef32b15..43d571ca5b 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -59,7 +59,6 @@ #include "pg_backup_archiver.h" #include "pg_backup_db.h" -#include "dumpmem.h" #include "dumputils.h" extern char *optarg; diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index f828a45800..955c231b1a 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -15,7 +15,6 @@ */ #include "pg_backup_archiver.h" #include "dumputils.h" -#include "dumpmem.h" /* translator: this is a module name */ static const char *modulename = gettext_noop("sorter"); diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 0662bc2069..9afbab4b07 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -25,7 +25,6 @@ #include "getopt_long.h" #include "dumputils.h" -#include "dumpmem.h" #include "pg_backup.h" /* version string we expect back from pg_dump */ diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 45b8b587e4..5dbe98f714 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -41,7 +41,6 @@ #include "pg_backup_archiver.h" -#include "dumpmem.h" #include "dumputils.h" #include diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c index 317d8606a0..f075b6e932 100644 --- a/src/bin/pg_resetxlog/pg_resetxlog.c +++ b/src/bin/pg_resetxlog/pg_resetxlog.c @@ -54,6 +54,7 @@ #include "access/xlog_internal.h" #include "catalog/catversion.h" #include "catalog/pg_control.h" +#include "common/fe_memutils.h" extern int optind; extern char *optarg; @@ -420,7 +421,7 @@ ReadControlFile(void) } /* Use malloc to ensure we have a maxaligned buffer */ - buffer = (char *) malloc(PG_CONTROL_SIZE); + buffer = (char *) pg_malloc(PG_CONTROL_SIZE); len = read(fd, buffer, PG_CONTROL_SIZE); if (len < 0) @@ -942,7 +943,7 @@ WriteEmptyXLOG(void) int nbytes; /* Use malloc() to ensure buffer is MAXALIGNED */ - buffer = (char *) malloc(XLOG_BLCKSZ); + buffer = (char *) pg_malloc(XLOG_BLCKSZ); page = (XLogPageHeader) buffer; memset(buffer, 0, XLOG_BLCKSZ); diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index a8aa1a2df1..dd183cacc1 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -32,56 +32,6 @@ static bool ExecQueryUsingCursor(const char *query, double *elapsed_msec); static bool command_no_begin(const char *query); static bool is_select_command(const char *query); -/* - * "Safe" wrapper around strdup() - */ -char * -pg_strdup(const char *string) -{ - char *tmp; - - if (!string) - { - psql_error("%s: pg_strdup: cannot duplicate null pointer (internal error)\n", - pset.progname); - exit(EXIT_FAILURE); - } - tmp = strdup(string); - if (!tmp) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - return tmp; -} - -void * -pg_malloc(size_t size) -{ - void *tmp; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - tmp = malloc(size); - if (!tmp) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - return tmp; -} - -void * -pg_malloc0(size_t size) -{ - void *tmp; - - tmp = pg_malloc(size); - MemSet(tmp, 0, size); - return tmp; -} - /* * setQFout * -- handler for -o command line option and \o command diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index f9f3b1f3c8..d8bb0930b4 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -14,15 +14,6 @@ #define atooid(x) ((Oid) strtoul((x), NULL, 10)) -/* - * Safer versions of some standard C library functions. If an - * out-of-memory condition occurs, these functions will bail out - * safely; therefore, their return value is guaranteed to be non-NULL. - */ -extern char *pg_strdup(const char *string); -extern void *pg_malloc(size_t size); -extern void *pg_malloc0(size_t size); - extern bool setQFout(const char *fname); extern void diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c index c7cc04aea4..03193b6fcd 100644 --- a/src/bin/scripts/common.c +++ b/src/bin/scripts/common.c @@ -277,55 +277,6 @@ executeMaintenanceCommand(PGconn *conn, const char *query, bool echo) return r; } -/* - * "Safe" wrapper around strdup(). Pulled from psql/common.c - */ -char * -pg_strdup(const char *string) -{ - char *tmp; - - if (!string) - { - fprintf(stderr, _("pg_strdup: cannot duplicate null pointer (internal error)\n")); - exit(EXIT_FAILURE); - } - tmp = strdup(string); - if (!tmp) - { - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); - } - return tmp; -} - -void * -pg_malloc(size_t size) -{ - void *tmp; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - tmp = malloc(size); - if (!tmp) - { - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); - } - return tmp; -} - -void * -pg_malloc0(size_t size) -{ - void *tmp; - - tmp = pg_malloc(size); - MemSet(tmp, 0, size); - return tmp; -} - /* * Check yes/no answer in a localized way. 1=yes, 0=no, -1=neither. */ diff --git a/src/bin/scripts/common.h b/src/bin/scripts/common.h index a174da79b0..6cf490f748 100644 --- a/src/bin/scripts/common.h +++ b/src/bin/scripts/common.h @@ -50,8 +50,4 @@ extern bool yesno_prompt(const char *question); extern void setup_cancel_handler(void); -extern char *pg_strdup(const char *string); -extern void *pg_malloc(size_t size); -extern void *pg_malloc0(size_t size); - #endif /* COMMON_H */ diff --git a/src/common/Makefile b/src/common/Makefile new file mode 100644 index 0000000000..3aa6e70322 --- /dev/null +++ b/src/common/Makefile @@ -0,0 +1,64 @@ +#------------------------------------------------------------------------- +# +# Makefile +# Makefile for src/common +# +# This makefile generates two outputs: +# +# libpgcommon.a - contains object files with FRONTEND defined, +# for use by client application and libraries +# +# libpgcommon_srv.a - contains object files without FRONTEND defined, +# for use only by the backend binaries +# +# IDENTIFICATION +# src/common/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/common +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global + +override CPPFLAGS := -DFRONTEND $(CPPFLAGS) +LIBS += $(PTHREAD_LIBS) + +OBJS_COMMON = + +OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o + +OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o) + +all: libpgcommon.a libpgcommon_srv.a + +# libpgcommon is needed by some contrib +install: all installdirs + $(INSTALL_STLIB) libpgcommon.a '$(DESTDIR)$(libdir)/libpgcommon.a' + +installdirs: + $(MKDIR_P) '$(DESTDIR)$(libdir)' + +uninstall: + rm -f '$(DESTDIR)$(libdir)/libpgcommon.a' + +libpgcommon.a: $(OBJS_FRONTEND) + $(AR) $(AROPT) $@ $^ + +# +# Server versions of object files +# + +libpgcommon_srv.a: $(OBJS_SRV) + $(AR) $(AROPT) $@ $^ + +# Because this uses its own compilation rule, it doesn't use the +# dependency tracking logic from Makefile.global. To make sure that +# dependency tracking works anyway for the *_srv.o files, depend on +# their *.o siblings as well, which do have proper dependencies. It's +# a hack that might fail someday if there is a *_srv.o without a +# corresponding *.o, but it works for now. +%_srv.o: %.c %.o + $(CC) $(CFLAGS) $(subst -DFRONTEND,, $(CPPFLAGS)) -c $< -o $@ + +clean distclean maintainer-clean: + rm -f libpgcommon.a libpgcommon_srv.a $(OBJS_FRONTEND) $(OBJS_SRV) diff --git a/src/common/fe_memutils.c b/src/common/fe_memutils.c new file mode 100644 index 0000000000..7d4d99eefd --- /dev/null +++ b/src/common/fe_memutils.c @@ -0,0 +1,128 @@ +/*------------------------------------------------------------------------- + * + * fe_memutils.c + * memory management support for frontend code + * + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/common/fe_memutils.c + * + *------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#error "This file is not expected to be compiled for backend code" +#endif + +#include "postgres_fe.h" + +void * +pg_malloc(size_t size) +{ + void *tmp; + + /* Avoid unportable behavior of malloc(0) */ + if (size == 0) + size = 1; + tmp = malloc(size); + if (!tmp) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return tmp; +} + +void * +pg_malloc0(size_t size) +{ + void *tmp; + + tmp = pg_malloc(size); + MemSet(tmp, 0, size); + return tmp; +} + +void * +pg_realloc(void *ptr, size_t size) +{ + void *tmp; + + /* Avoid unportable behavior of realloc(NULL, 0) */ + if (ptr == NULL && size == 0) + size = 1; + tmp = realloc(ptr, size); + if (!tmp) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return tmp; +} + +/* + * "Safe" wrapper around strdup(). + */ +char * +pg_strdup(const char *string) +{ + char *tmp; + + if (!string) + { + fprintf(stderr, + _("cannot duplicate null pointer (internal error)\n")); + exit(EXIT_FAILURE); + } + tmp = strdup(string); + if (!tmp) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return tmp; +} + +void +pg_free(void *ptr) +{ + if (ptr != NULL) + free(ptr); +} + +/* + * Frontend emulation of backend memory management functions. Useful for + * programs that compile backend files. + */ +void * +palloc(Size size) +{ + return pg_malloc(size); +} + +void * +palloc0(Size size) +{ + return pg_malloc0(size); +} + +void +pfree(void *pointer) +{ + pg_free(pointer); +} + +char * +pstrdup(const char *string) +{ + return pg_strdup(string); +} + +void * +repalloc(void *pointer, Size size) +{ + return pg_realloc(pointer, size); +} diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h new file mode 100644 index 0000000000..cefa7ecedc --- /dev/null +++ b/src/include/common/fe_memutils.h @@ -0,0 +1,20 @@ +/* + * fe_memutils.h + * memory management support for frontend code + * + * Copyright (c) 2003-2013, PostgreSQL Global Development Group + * + * src/include/common/fe_memutils.h + */ +#ifndef FE_MEMUTILS_H +#define FE_MEMUTILS_H + +extern char *pg_strdup(const char *string); +extern void *pg_malloc(size_t size); +extern void *pg_malloc0(size_t size); +extern void *pg_realloc(void *pointer, size_t size); +extern void pg_free(void *pointer); + +#include "utils/palloc.h" + +#endif /* FE_MEMUTILS_H */ diff --git a/src/include/postgres_fe.h b/src/include/postgres_fe.h index 0f35eccc74..6798b4c05c 100644 --- a/src/include/postgres_fe.h +++ b/src/include/postgres_fe.h @@ -24,4 +24,6 @@ #include "c.h" +#include "common/fe_memutils.h" + #endif /* POSTGRES_FE_H */ diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index d86558e417..7fc7ccc3b5 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -28,6 +28,8 @@ #ifndef PALLOC_H #define PALLOC_H +#ifndef FRONTEND + /* * Type MemoryContextData is declared in nodes/memnodes.h. Most users * of memory allocation should just treat it as an abstract type, so we @@ -49,10 +51,6 @@ extern void *MemoryContextAlloc(MemoryContext context, Size size); extern void *MemoryContextAllocZero(MemoryContext context, Size size); extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); -#define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz)) - -#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz)) - /* * The result of palloc() is always word-aligned, so we can skip testing * alignment of the pointer when deciding which MemSet variant to use. @@ -66,20 +64,11 @@ extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \ MemoryContextAllocZero(CurrentMemoryContext, sz) ) -extern void pfree(void *pointer); - -extern void *repalloc(void *pointer, Size size); - /* * MemoryContextSwitchTo can't be a macro in standard C compilers. * But we can make it an inline function if the compiler supports it. * See STATIC_IF_INLINE in c.h. - * - * This file has to be includable by some non-backend code such as - * pg_resetxlog, so don't expose the CurrentMemoryContext reference - * if FRONTEND is defined. */ -#ifndef FRONTEND #ifndef PG_USE_INLINE extern MemoryContext MemoryContextSwitchTo(MemoryContext context); @@ -94,22 +83,19 @@ MemoryContextSwitchTo(MemoryContext context) return old; } #endif /* PG_USE_INLINE || MCXT_INCLUDE_DEFINITIONS */ -#endif /* !FRONTEND */ /* * These are like standard strdup() except the copied string is * allocated in a context, not with malloc(). */ extern char *MemoryContextStrdup(MemoryContext context, const char *string); +#endif /* !FRONTEND */ -#define pstrdup(str) MemoryContextStrdup(CurrentMemoryContext, (str)) - +extern char *pstrdup(const char *in); extern char *pnstrdup(const char *in, Size len); - -#if defined(WIN32) || defined(__CYGWIN__) -extern void *pgport_palloc(Size sz); -extern char *pgport_pstrdup(const char *str); -extern void pgport_pfree(void *pointer); -#endif +extern void *palloc(Size size); +extern void *palloc0(Size size); +extern void pfree(void *pointer); +extern void *repalloc(void *pointer, Size size); #endif /* PALLOC_H */ diff --git a/src/port/dirmod.c b/src/port/dirmod.c index e7ff1f0d27..5dd0983a2d 100644 --- a/src/port/dirmod.c +++ b/src/port/dirmod.c @@ -40,80 +40,6 @@ #endif #endif - -#ifndef FRONTEND - -/* - * On Windows, call non-macro versions of palloc; we can't reference - * CurrentMemoryContext in this file because of PGDLLIMPORT conflict. - */ -#if defined(WIN32) || defined(__CYGWIN__) -#undef palloc -#undef pstrdup -#define palloc(sz) pgport_palloc(sz) -#define pstrdup(str) pgport_pstrdup(str) -#endif -#else /* FRONTEND */ - -/* - * In frontend, fake palloc behavior with these - */ -#undef palloc -#undef pstrdup -#define palloc(sz) fe_palloc(sz) -#define pstrdup(str) fe_pstrdup(str) -#define repalloc(pointer,sz) fe_repalloc(pointer,sz) -#define pfree(pointer) free(pointer) - -static void * -fe_palloc(Size size) -{ - void *res; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - res = malloc(size); - if (res == NULL) - { - fprintf(stderr, _("out of memory\n")); - exit(1); - } - return res; -} - -static char * -fe_pstrdup(const char *string) -{ - char *res; - - if ((res = strdup(string)) == NULL) - { - fprintf(stderr, _("out of memory\n")); - exit(1); - } - return res; -} - -static void * -fe_repalloc(void *pointer, Size size) -{ - void *res; - - /* Avoid unportable behavior of realloc(NULL, 0) */ - if (pointer == NULL && size == 0) - size = 1; - res = realloc(pointer, size); - if (res == NULL) - { - fprintf(stderr, _("out of memory\n")); - exit(1); - } - return res; -} -#endif /* FRONTEND */ - - #if defined(WIN32) || defined(__CYGWIN__) /* diff --git a/src/tools/msvc/Install.pm b/src/tools/msvc/Install.pm index e92354e621..0d0c46e18b 100644 --- a/src/tools/msvc/Install.pm +++ b/src/tools/msvc/Install.pm @@ -86,6 +86,7 @@ sub Install 'Import libraries', $target . '/lib/', "$conf\\", "postgres\\postgres.lib", "libpq\\libpq.lib", "libecpg\\libecpg.lib", + "libpgcommon\\libpgcommon.lib", "libpgport\\libpgport.lib", "libpgtypes\\libpgtypes.lib", "libecpg_compat\\libecpg_compat.lib"); CopySetOfFiles( diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index d587365437..75e7e4173f 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -24,6 +24,7 @@ our (@ISA, @EXPORT_OK); my $solution; my $libpgport; +my $libpgcommon; my $postgres; my $libpq; @@ -35,6 +36,11 @@ my @contrib_uselibpgport = ( 'pg_standby', 'pg_archivecleanup', 'pg_test_fsync', 'pg_test_timing', 'pg_upgrade', 'vacuumlo'); +my @contrib_uselibpgcommon = ( + 'oid2name', 'pgbench', + 'pg_standby', 'pg_archivecleanup', + 'pg_test_fsync', 'pg_test_timing', + 'pg_upgrade', 'vacuumlo'); my $contrib_extralibs = { 'pgbench' => ['wsock32.lib'] }; my $contrib_extraincludes = { 'tsearch2' => ['contrib/tsearch2'], 'dblink' => ['src/backend'] }; @@ -63,10 +69,19 @@ sub mkvcbuild sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c win32error.c win32setlocale.c); + our @pgcommonfiles = qw( + fe_memutils.c); + + our @pgcommonbkndfiles = qw(); + $libpgport = $solution->AddProject('libpgport', 'lib', 'misc'); $libpgport->AddDefine('FRONTEND'); $libpgport->AddFiles('src\port', @pgportfiles); + $libpgcommon = $solution->AddProject('libpgcommon', 'lib', 'misc'); + $libpgcommon->AddDefine('FRONTEND'); + $libpgcommon->AddFiles('src\common', @pgcommonfiles); + $postgres = $solution->AddProject('postgres', 'exe', '', 'src\backend'); $postgres->AddIncludeDir('src\backend'); $postgres->AddDir('src\backend\port\win32'); @@ -81,6 +96,7 @@ sub mkvcbuild $postgres->ReplaceFile('src\backend\port\pg_latch.c', 'src\backend\port\win32_latch.c'); $postgres->AddFiles('src\port', @pgportfiles); + $postgres->AddFiles('src\common', @pgcommonbkndfiles); $postgres->AddDir('src\timezone'); $postgres->AddFiles('src\backend\parser', 'scan.l', 'gram.y'); $postgres->AddFiles('src\backend\bootstrap', 'bootscanner.l', @@ -297,7 +313,7 @@ sub mkvcbuild $ecpg->AddDefine('MINOR_VERSION=9'); $ecpg->AddDefine('PATCHLEVEL=0'); $ecpg->AddDefine('ECPG_COMPILE'); - $ecpg->AddReference($libpgport); + $ecpg->AddReference($libpgport, $libpgcommon); my $pgregress_ecpg = $solution->AddProject('pg_regress_ecpg', 'exe', 'misc'); @@ -307,7 +323,7 @@ sub mkvcbuild $pgregress_ecpg->AddIncludeDir('src\test\regress'); $pgregress_ecpg->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); $pgregress_ecpg->AddDefine('FRONTEND'); - $pgregress_ecpg->AddReference($libpgport); + $pgregress_ecpg->AddReference($libpgport, $libpgcommon); my $isolation_tester = $solution->AddProject('isolationtester', 'exe', 'misc'); @@ -332,7 +348,7 @@ sub mkvcbuild $pgregress_isolation->AddIncludeDir('src\test\regress'); $pgregress_isolation->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); $pgregress_isolation->AddDefine('FRONTEND'); - $pgregress_isolation->AddReference($libpgport); + $pgregress_isolation->AddReference($libpgport, $libpgcommon); # src/bin my $initdb = AddSimpleFrontend('initdb'); @@ -393,7 +409,6 @@ sub mkvcbuild $pgdumpall->AddIncludeDir('src\backend'); $pgdumpall->AddFile('src\bin\pg_dump\pg_dumpall.c'); $pgdumpall->AddFile('src\bin\pg_dump\dumputils.c'); - $pgdumpall->AddFile('src\bin\pg_dump\dumpmem.c'); $pgdumpall->AddFile('src\bin\pg_dump\keywords.c'); $pgdumpall->AddFile('src\backend\parser\kwlookup.c'); @@ -407,7 +422,7 @@ sub mkvcbuild my $zic = $solution->AddProject('zic', 'exe', 'utils'); $zic->AddFiles('src\timezone', 'zic.c', 'ialloc.c', 'scheck.c', 'localtime.c'); - $zic->AddReference($libpgport); + $zic->AddReference($libpgport, $libpgcommon); if ($solution->{options}->{xml}) { @@ -547,7 +562,7 @@ sub mkvcbuild $proj->AddIncludeDir('src\interfaces\libpq'); $proj->AddIncludeDir('src\bin\pg_dump'); $proj->AddIncludeDir('src\bin\psql'); - $proj->AddReference($libpq, $libpgport); + $proj->AddReference($libpq, $libpgport, $libpgcommon); $proj->AddResourceFile('src\bin\scripts', 'PostgreSQL Utility'); } @@ -561,7 +576,7 @@ sub mkvcbuild $pgregress->AddFile('src\test\regress\pg_regress_main.c'); $pgregress->AddIncludeDir('src\port'); $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"'); - $pgregress->AddReference($libpgport); + $pgregress->AddReference($libpgport, $libpgcommon); $solution->Save(); return $solution->{vcver}; @@ -579,7 +594,7 @@ sub AddSimpleFrontend my $p = $solution->AddProject($n, 'exe', 'bin'); $p->AddDir('src\bin\\' . $n); - $p->AddReference($libpgport); + $p->AddReference($libpgport, $libpgcommon); if ($uselibpq) { $p->AddIncludeDir('src\interfaces\libpq'); @@ -730,6 +745,10 @@ sub AdjustContribProj { $proj->AddReference($libpgport); } + if (grep { /^$n$/ } @contrib_uselibpgcommon) + { + $proj->AddReference($libpgcommon); + } if ($contrib_extralibs->{$n}) { foreach my $l (@{ $contrib_extralibs->{$n} }) diff --git a/src/tools/msvc/Project.pm b/src/tools/msvc/Project.pm index 0a47e40942..4182871e88 100644 --- a/src/tools/msvc/Project.pm +++ b/src/tools/msvc/Project.pm @@ -225,7 +225,7 @@ sub AddDir if ($filter eq "LIBOBJS") { - if (grep(/$p/, @main::pgportfiles) == 1) + if (grep(/$p/, @main::pgportfiles, @main::pgcommonfiles) == 1) { $p =~ s/\.c/\.o/; $matches .= $p . " "; -- 2.30.2