03-pg_malloc-unified-v2.patch
text/x-patch
Filename: 03-pg_malloc-unified-v2.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| contrib/oid2name/oid2name.c | 2 | 50 |
| contrib/pgbench/pgbench.c | 2 | 52 |
| contrib/pg_upgrade/pg_upgrade.c | 17 | 0 |
| contrib/pg_upgrade/pg_upgrade.h | 0 | 4 |
| contrib/pg_upgrade/util.c | 0 | 49 |
| src/bin/initdb/initdb.c | 18 | 39 |
| src/bin/pg_basebackup/pg_basebackup.c | 24 | 0 |
| src/bin/pg_basebackup/streamutil.c | 0 | 48 |
| src/bin/pg_basebackup/streamutil.h | 0 | 4 |
| src/bin/pg_ctl/pg_ctl.c | 18 | 38 |
| src/bin/pg_dump/common.c | 0 | 1 |
| src/bin/pg_dump/compress_io.c | 0 | 1 |
| src/bin/pg_dump/dumpmem.c | 0 | 76 |
| src/bin/pg_dump/dumpmem.h | 0 | 22 |
| src/bin/pg_dump/Makefile | 3 | 3 |
| src/bin/pg_dump/nls.mk | 1 | 1 |
| src/bin/pg_dump/pg_backup_archiver.c | 0 | 1 |
| src/bin/pg_dump/pg_backup_custom.c | 0 | 1 |
| src/bin/pg_dump/pg_backup_db.c | 0 | 1 |
| src/bin/pg_dump/pg_backup_directory.c | 0 | 1 |
| src/bin/pg_dump/pg_backup_null.c | 0 | 1 |
| src/bin/pg_dump/pg_backup_tar.c | 0 | 1 |
| src/bin/pg_dump/pg_dumpall.c | 0 | 1 |
| src/bin/pg_dump/pg_dump.c | 0 | 1 |
| src/bin/pg_dump/pg_dump_sort.c | 0 | 1 |
| src/bin/pg_dump/pg_restore.c | 0 | 1 |
| src/bin/psql/common.c | 0 | 50 |
| src/bin/psql/common.h | 0 | 9 |
| src/bin/psql/startup.c | 17 | 0 |
| src/bin/scripts/clusterdb.c | 2 | 0 |
| src/bin/scripts/common.c | 19 | 49 |
| src/bin/scripts/common.h | 2 | 4 |
| src/bin/scripts/createdb.c | 2 | 0 |
| src/bin/scripts/createlang.c | 2 | 0 |
| src/bin/scripts/createuser.c | 2 | 0 |
| src/bin/scripts/dropdb.c | 2 | 0 |
| src/bin/scripts/droplang.c | 2 | 0 |
| src/bin/scripts/dropuser.c | 2 | 0 |
| src/bin/scripts/reindexdb.c | 2 | 0 |
| src/bin/scripts/vacuumdb.c | 2 | 0 |
| src/include/port.h | 26 | 0 |
| src/port/init.c | 32 | 0 |
| src/port/Makefile | 4 | 3 |
| src/port/pgmalloc.c | 125 | 0 |
diff -durpN postgresql.2/contrib/oid2name/oid2name.c postgresql.3/contrib/oid2name/oid2name.c
--- postgresql.2/contrib/oid2name/oid2name.c 2012-10-03 10:40:48.241207023 +0200
+++ postgresql.3/contrib/oid2name/oid2name.c 2012-11-21 18:00:58.906546432 +0100
@@ -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
*
@@ -598,6 +548,8 @@ main(int argc, char **argv)
struct options *my_opts;
PGconn *pgconn;
+ InitPostgresFrontend(NULL);
+
my_opts = (struct options *) pg_malloc(sizeof(struct options));
my_opts->oids = (eary *) pg_malloc(sizeof(eary));
diff -durpN postgresql.2/contrib/pgbench/pgbench.c postgresql.3/contrib/pgbench/pgbench.c
--- postgresql.2/contrib/pgbench/pgbench.c 2012-10-21 10:56:15.358945296 +0200
+++ postgresql.3/contrib/pgbench/pgbench.c 2012-11-21 18:01:33.795785484 +0100
@@ -296,58 +296,6 @@ 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)
{
@@ -1956,6 +1904,8 @@ main(int argc, char **argv)
char val[64];
+ InitPostgresFrontend(NULL);
+
progname = get_progname(argv[0]);
if (argc > 1)
diff -durpN postgresql.2/contrib/pg_upgrade/pg_upgrade.c postgresql.3/contrib/pg_upgrade/pg_upgrade.c
--- postgresql.2/contrib/pg_upgrade/pg_upgrade.c 2012-09-04 11:02:05.935828363 +0200
+++ postgresql.3/contrib/pg_upgrade/pg_upgrade.c 2012-11-21 18:02:43.531265024 +0100
@@ -67,6 +67,21 @@ char *output_files[] = {
NULL
};
+static void
+pg_upgrade_malloc_oom(void)
+{
+ pg_log(PG_FATAL, "%s: out of memory\n", os_info.progname);
+}
+
+static void
+pg_upgrade_strdup_null(void)
+{
+ pg_log(PG_FATAL, "%s: pg_strdup: cannot duplicate null pointer (internal error)\n", os_info.progname);
+}
+
+static PostgresFrontendData pg_upgrade_fe_data = {
+ pg_upgrade_malloc_oom, pg_upgrade_strdup_null
+};
int
main(int argc, char **argv)
@@ -76,6 +91,8 @@ main(int argc, char **argv)
char *deletion_script_file_name = NULL;
bool live_check = false;
+ InitPostgresFrontend(&pg_upgrade_fe_data);
+
parseCommandLine(argc, argv);
adjust_data_dir(&old_cluster);
diff -durpN postgresql.2/contrib/pg_upgrade/pg_upgrade.h postgresql.3/contrib/pg_upgrade/pg_upgrade.h
--- postgresql.2/contrib/pg_upgrade/pg_upgrade.h 2012-11-15 13:39:47.132060180 +0100
+++ postgresql.3/contrib/pg_upgrade/pg_upgrade.h 2012-11-21 16:54:30.995832875 +0100
@@ -437,10 +437,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 -durpN postgresql.2/contrib/pg_upgrade/util.c postgresql.3/contrib/pg_upgrade/util.c
--- postgresql.2/contrib/pg_upgrade/util.c 2012-10-03 10:40:48.243207034 +0200
+++ postgresql.3/contrib/pg_upgrade/util.c 2012-11-21 16:52:54.636175667 +0100
@@ -191,55 +191,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 -durpN postgresql.2/src/bin/initdb/initdb.c postgresql.3/src/bin/initdb/initdb.c
--- postgresql.2/src/bin/initdb/initdb.c 2012-10-15 10:44:54.640429361 +0200
+++ postgresql.3/src/bin/initdb/initdb.c 2012-11-21 18:03:54.547749709 +0100
@@ -177,8 +177,6 @@ static const char *backend_options = "--
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);
@@ -284,43 +282,6 @@ do { \
#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;
-}
-
-/*
* make a copy of the array of lines, with token replaced by replacement
* the first time it occurs on each line.
*
@@ -2823,6 +2784,22 @@ check_need_password(const char *authmeth
}
}
+static void
+initdb_malloc_oom(void)
+{
+ fprintf(stderr, _("%s: out of memory\n"), progname);
+}
+
+static void
+initdb_strdup_null(void)
+{
+ fprintf(stderr, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"), progname);
+}
+
+static PostgresFrontendData initdb_fe_data = {
+ initdb_malloc_oom, initdb_strdup_null
+};
+
int
main(int argc, char *argv[])
{
@@ -2890,6 +2867,8 @@ main(int argc, char *argv[])
"pg_stat_tmp"
};
+ InitPostgresFrontend(&initdb_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb"));
diff -durpN postgresql.2/src/bin/pg_basebackup/pg_basebackup.c postgresql.3/src/bin/pg_basebackup/pg_basebackup.c
--- postgresql.2/src/bin/pg_basebackup/pg_basebackup.c 2012-11-21 15:14:27.364562199 +0100
+++ postgresql.3/src/bin/pg_basebackup/pg_basebackup.c 2012-11-21 18:05:17.308315854 +0100
@@ -1666,6 +1666,28 @@ BaseBackup(void)
}
+static void
+pgbb_malloc_oom(void)
+{
+ fprintf(stderr, _("%s: out of memory\n"), progname);
+}
+
+static void
+pgbb_strdup_null(void)
+{
+ fprintf(stderr, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"), progname);
+}
+
+static void
+pgbb_app_atexit(void)
+{
+ PQfinish(conn);
+}
+
+static PostgresFrontendData pgbb_fe_data = {
+ pgbb_malloc_oom, pgbb_strdup_null, pgbb_app_atexit
+};
+
int
main(int argc, char **argv)
{
@@ -1695,6 +1717,8 @@ main(int argc, char **argv)
int option_index;
+ InitPostgresFrontend(&pgbb_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
diff -durpN postgresql.2/src/bin/pg_basebackup/streamutil.c postgresql.3/src/bin/pg_basebackup/streamutil.c
--- postgresql.2/src/bin/pg_basebackup/streamutil.c 2012-11-21 15:14:27.365562205 +0100
+++ postgresql.3/src/bin/pg_basebackup/streamutil.c 2012-11-21 16:48:00.810168593 +0100
@@ -32,54 +32,6 @@ 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);
- disconnect_and_exit(1);
- }
- return result;
-}
-
-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);
- disconnect_and_exit(1);
- }
- MemSet(result, 0, size);
- return result;
-}
-
-
-void *
-pg_malloc0(size_t size)
-{
- void *tmp;
-
- tmp = pg_malloc(size);
- MemSet(tmp, 0, size);
- return tmp;
-}
-
-
-/*
* Connect to the server. Returns a valid PGconn pointer if connected,
* or NULL on non-permanent error. On permanent error, the function will
* call exit(1) directly.
diff -durpN postgresql.2/src/bin/pg_basebackup/streamutil.h postgresql.3/src/bin/pg_basebackup/streamutil.h
--- postgresql.2/src/bin/pg_basebackup/streamutil.h 2012-11-21 15:14:27.365562205 +0100
+++ postgresql.3/src/bin/pg_basebackup/streamutil.h 2012-11-21 16:55:31.796250379 +0100
@@ -16,8 +16,4 @@ extern PGconn *conn;
}
-extern char *pg_strdup(const char *s);
-extern void *pg_malloc(size_t size);
-extern void *pg_malloc0(size_t size);
-
extern PGconn *GetConnection(void);
diff -durpN postgresql.2/src/bin/pg_ctl/pg_ctl.c postgresql.3/src/bin/pg_ctl/pg_ctl.c
--- postgresql.2/src/bin/pg_ctl/pg_ctl.c 2012-10-19 19:12:00.307691010 +0200
+++ postgresql.3/src/bin/pg_ctl/pg_ctl.c 2012-11-21 18:06:04.997642034 +0100
@@ -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);
@@ -226,42 +224,6 @@ write_stderr(const char *fmt,...)
}
/*
- * 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.
*/
@@ -1994,6 +1956,22 @@ adjust_data_dir(void)
}
+static void
+pgctl_malloc_oom(void)
+{
+ write_stderr(_("%s: out of memory\n"), progname);
+}
+
+static void
+pgctl_strdup_null(void)
+{
+ write_stderr(_("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"), progname);
+}
+
+static PostgresFrontendData pgctl_fe_data = {
+ pgctl_malloc_oom, pgctl_strdup_null
+};
+
int
main(int argc, char **argv)
{
@@ -2013,6 +1991,8 @@ main(int argc, char **argv)
int c;
pgpid_t killproc = 0;
+ InitPostgresFrontend(&pgctl_fe_data);
+
#if defined(WIN32) || defined(__CYGWIN__)
setvbuf(stderr, NULL, _IONBF, 0);
#endif
diff -durpN postgresql.2/src/bin/pg_dump/common.c postgresql.3/src/bin/pg_dump/common.c
--- postgresql.2/src/bin/pg_dump/common.c 2012-07-22 16:48:48.536857822 +0200
+++ postgresql.3/src/bin/pg_dump/common.c 2012-11-21 16:58:49.782639540 +0100
@@ -18,7 +18,6 @@
#include <ctype.h>
#include "catalog/pg_class.h"
-#include "dumpmem.h"
#include "dumputils.h"
diff -durpN postgresql.2/src/bin/pg_dump/compress_io.c postgresql.3/src/bin/pg_dump/compress_io.c
--- postgresql.2/src/bin/pg_dump/compress_io.c 2012-10-03 10:40:48.301207415 +0200
+++ postgresql.3/src/bin/pg_dump/compress_io.c 2012-11-21 17:03:26.135545975 +0100
@@ -53,7 +53,6 @@
*/
#include "compress_io.h"
-#include "dumpmem.h"
#include "dumputils.h"
/*----------------------
diff -durpN postgresql.2/src/bin/pg_dump/dumpmem.c postgresql.3/src/bin/pg_dump/dumpmem.c
--- postgresql.2/src/bin/pg_dump/dumpmem.c 2012-10-03 10:40:48.301207415 +0200
+++ postgresql.3/src/bin/pg_dump/dumpmem.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,76 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * dumpmem.c
- * Memory allocation routines used by pg_dump, pg_dumpall, and pg_restore
- *
- * Portions Copyright (c) 1996-2012, 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 -durpN postgresql.2/src/bin/pg_dump/dumpmem.h postgresql.3/src/bin/pg_dump/dumpmem.h
--- postgresql.2/src/bin/pg_dump/dumpmem.h 2012-10-03 10:40:48.301207415 +0200
+++ postgresql.3/src/bin/pg_dump/dumpmem.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,22 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * dumpmem.h
- * Memory allocation routines used by pg_dump, pg_dumpall, and pg_restore
- *
- * Portions Copyright (c) 1996-2012, 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 -durpN postgresql.2/src/bin/pg_dump/Makefile postgresql.3/src/bin/pg_dump/Makefile
--- postgresql.2/src/bin/pg_dump/Makefile 2012-04-16 19:57:22.595917312 +0200
+++ postgresql.3/src/bin/pg_dump/Makefile 2012-11-21 17:07:12.746122542 +0100
@@ -20,7 +20,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $
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
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 -durpN postgresql.2/src/bin/pg_dump/nls.mk postgresql.3/src/bin/pg_dump/nls.mk
--- postgresql.2/src/bin/pg_dump/nls.mk 2012-04-16 19:57:22.596917323 +0200
+++ postgresql.3/src/bin/pg_dump/nls.mk 2012-11-21 17:07:46.449355315 +0100
@@ -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 -durpN postgresql.2/src/bin/pg_dump/pg_backup_archiver.c postgresql.3/src/bin/pg_dump/pg_backup_archiver.c
--- postgresql.2/src/bin/pg_dump/pg_backup_archiver.c 2012-10-21 10:56:15.398945610 +0200
+++ postgresql.3/src/bin/pg_dump/pg_backup_archiver.c 2012-11-21 17:02:24.913122881 +0100
@@ -21,7 +21,6 @@
*/
#include "pg_backup_db.h"
-#include "dumpmem.h"
#include "dumputils.h"
#include <ctype.h>
diff -durpN postgresql.2/src/bin/pg_dump/pg_backup_custom.c postgresql.3/src/bin/pg_dump/pg_backup_custom.c
--- postgresql.2/src/bin/pg_dump/pg_backup_custom.c 2012-10-03 10:40:48.303207429 +0200
+++ postgresql.3/src/bin/pg_dump/pg_backup_custom.c 2012-11-21 16:57:43.446182808 +0100
@@ -26,7 +26,6 @@
#include "compress_io.h"
#include "dumputils.h"
-#include "dumpmem.h"
/*--------
* Routines in the format interface
diff -durpN postgresql.2/src/bin/pg_dump/pg_backup_db.c postgresql.3/src/bin/pg_dump/pg_backup_db.c
--- postgresql.2/src/bin/pg_dump/pg_backup_db.c 2012-07-25 10:51:14.973507544 +0200
+++ postgresql.3/src/bin/pg_dump/pg_backup_db.c 2012-11-21 17:02:38.216215418 +0100
@@ -11,7 +11,6 @@
*/
#include "pg_backup_db.h"
-#include "dumpmem.h"
#include "dumputils.h"
#include <unistd.h>
diff -durpN postgresql.2/src/bin/pg_dump/pg_backup_directory.c postgresql.3/src/bin/pg_dump/pg_backup_directory.c
--- postgresql.2/src/bin/pg_dump/pg_backup_directory.c 2012-10-03 10:40:48.303207429 +0200
+++ postgresql.3/src/bin/pg_dump/pg_backup_directory.c 2012-11-21 16:59:26.446892844 +0100
@@ -34,7 +34,6 @@
*/
#include "compress_io.h"
-#include "dumpmem.h"
#include "dumputils.h"
#include <dirent.h>
diff -durpN postgresql.2/src/bin/pg_dump/pg_backup_null.c postgresql.3/src/bin/pg_dump/pg_backup_null.c
--- postgresql.2/src/bin/pg_dump/pg_backup_null.c 2012-04-16 19:57:22.598917347 +0200
+++ postgresql.3/src/bin/pg_dump/pg_backup_null.c 2012-11-21 17:00:16.119238575 +0100
@@ -23,7 +23,6 @@
*/
#include "pg_backup_archiver.h"
-#include "dumpmem.h"
#include "dumputils.h"
#include <unistd.h> /* for dup */
diff -durpN postgresql.2/src/bin/pg_dump/pg_backup_tar.c postgresql.3/src/bin/pg_dump/pg_backup_tar.c
--- postgresql.2/src/bin/pg_dump/pg_backup_tar.c 2012-10-03 10:40:48.304207436 +0200
+++ postgresql.3/src/bin/pg_dump/pg_backup_tar.c 2012-11-21 16:59:40.614991367 +0100
@@ -28,7 +28,6 @@
#include "pg_backup.h"
#include "pg_backup_archiver.h"
#include "pg_backup_tar.h"
-#include "dumpmem.h"
#include "dumputils.h"
#include <sys/stat.h>
diff -durpN postgresql.2/src/bin/pg_dump/pg_dumpall.c postgresql.3/src/bin/pg_dump/pg_dumpall.c
--- postgresql.2/src/bin/pg_dump/pg_dumpall.c 2012-10-14 11:09:08.143146185 +0200
+++ postgresql.3/src/bin/pg_dump/pg_dumpall.c 2012-11-21 17:03:45.879682211 +0100
@@ -23,7 +23,6 @@
#include "getopt_long.h"
#include "dumputils.h"
-#include "dumpmem.h"
#include "pg_backup.h"
/* version string we expect back from pg_dump */
diff -durpN postgresql.2/src/bin/pg_dump/pg_dump.c postgresql.3/src/bin/pg_dump/pg_dump.c
--- postgresql.2/src/bin/pg_dump/pg_dump.c 2012-10-28 07:41:12.051532033 +0100
+++ postgresql.3/src/bin/pg_dump/pg_dump.c 2012-11-21 16:58:32.384518598 +0100
@@ -59,7 +59,6 @@
#include "pg_backup_archiver.h"
#include "pg_backup_db.h"
-#include "dumpmem.h"
#include "dumputils.h"
extern char *optarg;
diff -durpN postgresql.2/src/bin/pg_dump/pg_dump_sort.c postgresql.3/src/bin/pg_dump/pg_dump_sort.c
--- postgresql.2/src/bin/pg_dump/pg_dump_sort.c 2012-10-19 19:12:00.334691199 +0200
+++ postgresql.3/src/bin/pg_dump/pg_dump_sort.c 2012-11-21 16:58:08.053352426 +0100
@@ -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 -durpN postgresql.2/src/bin/pg_dump/pg_restore.c postgresql.3/src/bin/pg_dump/pg_restore.c
--- postgresql.2/src/bin/pg_dump/pg_restore.c 2012-10-14 11:09:08.143146185 +0200
+++ postgresql.3/src/bin/pg_dump/pg_restore.c 2012-11-21 17:03:35.040607345 +0100
@@ -41,7 +41,6 @@
#include "pg_backup_archiver.h"
-#include "dumpmem.h"
#include "dumputils.h"
#include <ctype.h>
diff -durpN postgresql.2/src/bin/psql/common.c postgresql.3/src/bin/psql/common.c
--- postgresql.2/src/bin/psql/common.c 2012-10-03 10:40:48.322207553 +0200
+++ postgresql.3/src/bin/psql/common.c 2012-11-21 16:35:09.299927138 +0100
@@ -33,56 +33,6 @@ static bool command_no_begin(const char
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 -durpN postgresql.2/src/bin/psql/common.h postgresql.3/src/bin/psql/common.h
--- postgresql.2/src/bin/psql/common.h 2012-10-03 10:40:48.322207553 +0200
+++ postgresql.3/src/bin/psql/common.h 2012-11-21 16:55:06.557076835 +0100
@@ -21,15 +21,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 -durpN postgresql.2/src/bin/psql/startup.c postgresql.3/src/bin/psql/startup.c
--- postgresql.2/src/bin/psql/startup.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/psql/startup.c 2012-11-21 18:07:48.773361102 +0100
@@ -77,6 +77,21 @@ static void process_psqlrc_file(char *fi
static void showVersion(void);
static void EstablishVariableSpace(void);
+static void psql_malloc_oom(void)
+{
+ psql_error("out of memory\n");
+}
+
+static void psql_strdup_null(void)
+{
+ psql_error("%s: pg_strdup: cannot duplicate null pointer (internal error)\n",
+ pset.progname);
+}
+
+static PostgresFrontendData psql_fe_data = {
+ psql_malloc_oom, psql_strdup_null
+};
+
/*
*
* main
@@ -91,6 +106,8 @@ main(int argc, char *argv[])
char *password_prompt = NULL;
bool new_pass;
+ InitPostgresFrontend(&psql_fe_data);
+
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
if (argc > 1)
diff -durpN postgresql.2/src/bin/scripts/clusterdb.c postgresql.3/src/bin/scripts/clusterdb.c
--- postgresql.2/src/bin/scripts/clusterdb.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/clusterdb.c 2012-11-21 18:10:25.326438629 +0100
@@ -61,6 +61,8 @@ main(int argc, char *argv[])
char *table = NULL;
bool verbose = false;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/common.c postgresql.3/src/bin/scripts/common.c
--- postgresql.2/src/bin/scripts/common.c 2012-10-03 10:40:48.324207567 +0200
+++ postgresql.3/src/bin/scripts/common.c 2012-11-21 18:10:04.686298291 +0100
@@ -31,6 +31,25 @@ static CRITICAL_SECTION cancelConnLock;
#endif
/*
+ * Helper functions to report error in pg_malloc and pg_strdup
+ */
+static void
+common_malloc_oom(void)
+{
+ fprintf(stderr, _("out of memory\n"));
+}
+
+static void
+common_strdup_null(void)
+{
+ fprintf(stderr, _("pg_strdup: cannot duplicate null pointer (internal error)\n"));
+}
+
+PostgresFrontendData common_fe_data = {
+ common_malloc_oom, common_strdup_null
+};
+
+/*
* Returns the current user name.
*/
const char *
@@ -278,55 +297,6 @@ executeMaintenanceCommand(PGconn *conn,
}
/*
- * "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 -durpN postgresql.2/src/bin/scripts/common.h postgresql.3/src/bin/scripts/common.h
--- postgresql.2/src/bin/scripts/common.h 2012-10-03 10:40:48.324207567 +0200
+++ postgresql.3/src/bin/scripts/common.h 2012-11-21 18:09:57.334247576 +0100
@@ -22,6 +22,8 @@ enum trivalue
typedef void (*help_handler) (const char *progname);
+extern PostgresFrontendData common_fe_data;
+
extern const char *get_user_name(const char *progname);
extern void handle_help_version_opts(int argc, char *argv[],
@@ -50,8 +52,4 @@ extern bool yesno_prompt(const char *que
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 -durpN postgresql.2/src/bin/scripts/createdb.c postgresql.3/src/bin/scripts/createdb.c
--- postgresql.2/src/bin/scripts/createdb.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/createdb.c 2012-11-21 18:10:30.790475639 +0100
@@ -64,6 +64,8 @@ main(int argc, char *argv[])
PGconn *conn;
PGresult *result;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/createlang.c postgresql.3/src/bin/scripts/createlang.c
--- postgresql.2/src/bin/scripts/createlang.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/createlang.c 2012-11-21 18:10:34.070498052 +0100
@@ -52,6 +52,8 @@ main(int argc, char *argv[])
PGconn *conn;
PGresult *result;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/createuser.c postgresql.3/src/bin/scripts/createuser.c
--- postgresql.2/src/bin/scripts/createuser.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/createuser.c 2012-11-21 18:10:37.638522326 +0100
@@ -78,6 +78,8 @@ main(int argc, char *argv[])
PGconn *conn;
PGresult *result;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/dropdb.c postgresql.3/src/bin/scripts/dropdb.c
--- postgresql.2/src/bin/scripts/dropdb.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/dropdb.c 2012-11-21 18:10:41.590549265 +0100
@@ -54,6 +54,8 @@ main(int argc, char *argv[])
PGconn *conn;
PGresult *result;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/droplang.c postgresql.3/src/bin/scripts/droplang.c
--- postgresql.2/src/bin/scripts/droplang.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/droplang.c 2012-11-21 18:10:44.726570630 +0100
@@ -51,6 +51,8 @@ main(int argc, char *argv[])
PGconn *conn;
PGresult *result;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/dropuser.c postgresql.3/src/bin/scripts/dropuser.c
--- postgresql.2/src/bin/scripts/dropuser.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/dropuser.c 2012-11-21 18:10:48.110593633 +0100
@@ -52,6 +52,8 @@ main(int argc, char *argv[])
PGconn *conn;
PGresult *result;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/reindexdb.c postgresql.3/src/bin/scripts/reindexdb.c
--- postgresql.2/src/bin/scripts/reindexdb.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/reindexdb.c 2012-11-21 18:10:50.870612385 +0100
@@ -67,6 +67,8 @@ main(int argc, char *argv[])
const char *table = NULL;
const char *index = NULL;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/bin/scripts/vacuumdb.c postgresql.3/src/bin/scripts/vacuumdb.c
--- postgresql.2/src/bin/scripts/vacuumdb.c 2012-10-14 11:09:08.144146192 +0200
+++ postgresql.3/src/bin/scripts/vacuumdb.c 2012-11-21 18:10:54.166634846 +0100
@@ -72,6 +72,8 @@ main(int argc, char *argv[])
bool full = false;
bool verbose = false;
+ InitPostgresFrontend(&common_fe_data);
+
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
diff -durpN postgresql.2/src/include/port.h postgresql.3/src/include/port.h
--- postgresql.2/src/include/port.h 2012-07-22 16:48:48.548857900 +0200
+++ postgresql.3/src/include/port.h 2012-11-21 18:02:18.860095054 +0100
@@ -17,6 +17,19 @@
#include <netdb.h>
#include <pwd.h>
+/* port/init.c */
+typedef void (*fe_func)(void);
+
+typedef struct PostgresFrontendData
+{
+ fe_func pg_malloc_oom;
+ fe_func pg_strdup_null;
+ fe_func app_atexit;
+} PostgresFrontendData, *PostgresFrontend;
+extern PostgresFrontend pg_fedata;
+
+extern void InitPostgresFrontend(PostgresFrontend fe_data);
+
/* socket has a different definition on WIN32 */
#ifndef WIN32
typedef int pgsocket;
@@ -462,6 +475,19 @@ extern char *inet_net_ntop(int af, const
/* port/pgcheckdir.c */
extern int pg_check_dir(const char *dir);
+/* port/pgmalloc.c */
+extern void pgmalloc_atexit(void);
+
+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);
+
+extern void pg_free(void *ptr);
+
/* port/pgmkdirp.c */
extern int pg_mkdir_p(char *path, int omode);
diff -durpN postgresql.2/src/port/init.c postgresql.3/src/port/init.c
--- postgresql.2/src/port/init.c 1970-01-01 01:00:00.000000000 +0100
+++ postgresql.3/src/port/init.c 2012-11-21 16:31:50.370535889 +0100
@@ -0,0 +1,32 @@
+/*-------------------------------------------------------------------------
+ *
+ * init.c
+ * Functions for initializing frontend functions
+ *
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/port/init.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifdef FRONTEND
+#include "postgres_fe.h"
+
+PostgresFrontend pg_fedata = NULL;
+
+void InitPostgresFrontend(PostgresFrontend ptr)
+{
+ pg_fedata = ptr;
+
+ atexit(pgmalloc_atexit);
+
+ if (ptr && ptr->app_atexit)
+ atexit(ptr->app_atexit);
+}
+
+#endif
diff -durpN postgresql.2/src/port/Makefile postgresql.3/src/port/Makefile
--- postgresql.2/src/port/Makefile 2012-05-09 12:28:11.755496856 +0200
+++ postgresql.3/src/port/Makefile 2012-11-21 16:18:29.251969612 +0100
@@ -30,9 +30,10 @@ include $(top_builddir)/src/Makefile.glo
override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
LIBS += $(PTHREAD_LIBS)
-OBJS = $(LIBOBJS) chklocale.o dirmod.o erand48.o exec.o fls.o inet_net_ntop.o \
- noblock.o path.o pgcheckdir.o pg_crc.o pgmkdirp.o pgsleep.o \
- pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o
+OBJS = $(LIBOBJS) chklocale.o dirmod.o erand48.o exec.o fls.o init.o \
+ inet_net_ntop.o noblock.o path.o pgcheckdir.o pg_crc.o pgmalloc.o \
+ pgmkdirp.o pgsleep.o pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o \
+ thread.o
# foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND
OBJS_SRV = $(OBJS:%.o=%_srv.o)
diff -durpN postgresql.2/src/port/pgmalloc.c postgresql.3/src/port/pgmalloc.c
--- postgresql.2/src/port/pgmalloc.c 1970-01-01 01:00:00.000000000 +0100
+++ postgresql.3/src/port/pgmalloc.c 2012-11-21 17:59:52.107088562 +0100
@@ -0,0 +1,125 @@
+/*-------------------------------------------------------------------------
+ *
+ * pgmalloc.c
+ * Functions for allocating memory and
+ * exiting on out-of-memory
+ *
+ *
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/port/pgmalloc.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifdef FRONTEND
+#include "postgres_fe.h"
+
+#include <stdio.h>
+
+typedef enum {
+ PG_MALLOC_NOP,
+ PG_MALLOC_OOM,
+ PG_STRDUP_NULL
+} PgMallocAction;
+
+static PgMallocAction pgmalloc_action = PG_MALLOC_NOP;
+
+void pgmalloc_atexit(void)
+{
+ switch (pgmalloc_action)
+ {
+ case PG_MALLOC_OOM:
+ if (pg_fedata && pg_fedata->pg_malloc_oom)
+ pg_fedata->pg_malloc_oom();
+ else
+ fprintf(stderr, "out of memory\n");
+ break;
+ case PG_STRDUP_NULL:
+ if (pg_fedata && pg_fedata->pg_strdup_null)
+ pg_fedata->pg_strdup_null();
+ else
+ fprintf(stderr, "pg_strdup: cannot duplicate null pointer (internal error)\n");
+ break;
+ case PG_MALLOC_NOP:
+ break;
+ }
+}
+
+/*
+ * "Safe" wrapper around strdup()
+ */
+char *
+pg_strdup(const char *string)
+{
+ char *tmp;
+
+ if (!string)
+ {
+ pgmalloc_action = PG_STRDUP_NULL;
+ exit(1);
+ }
+ tmp = strdup(string);
+ if (!tmp)
+ {
+ pgmalloc_action = PG_MALLOC_OOM;
+ exit(1);
+ }
+ 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)
+ {
+ pgmalloc_action = PG_MALLOC_OOM;
+ exit(1);
+ }
+ 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)
+ {
+ pgmalloc_action = PG_MALLOC_OOM;
+ exit(1);
+ }
+ return tmp;
+}
+
+void
+pg_free(void *ptr)
+{
+ if (ptr != NULL)
+ free(ptr);
+}
+
+#endif