diff -durpN postgresql/contrib/oid2name/oid2name.c postgresql.2/contrib/oid2name/oid2name.c
--- postgresql/contrib/oid2name/oid2name.c	2012-10-03 10:40:48.241207023 +0200
+++ postgresql.2/contrib/oid2name/oid2name.c	2012-11-30 09:49:47.067595921 +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/contrib/pgbench/pgbench.c postgresql.2/contrib/pgbench/pgbench.c
--- postgresql/contrib/pgbench/pgbench.c	2012-10-21 10:56:15.358945296 +0200
+++ postgresql.2/contrib/pgbench/pgbench.c	2012-11-30 09:49:47.068595928 +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/contrib/pg_upgrade/pg_upgrade.c postgresql.2/contrib/pg_upgrade/pg_upgrade.c
--- postgresql/contrib/pg_upgrade/pg_upgrade.c	2012-09-04 11:02:05.935828363 +0200
+++ postgresql.2/contrib/pg_upgrade/pg_upgrade.c	2012-11-30 09:49:47.073595967 +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/contrib/pg_upgrade/pg_upgrade.h postgresql.2/contrib/pg_upgrade/pg_upgrade.h
--- postgresql/contrib/pg_upgrade/pg_upgrade.h	2012-11-15 13:39:47.132060180 +0100
+++ postgresql.2/contrib/pg_upgrade/pg_upgrade.h	2012-11-30 09:49:47.073595967 +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/contrib/pg_upgrade/util.c postgresql.2/contrib/pg_upgrade/util.c
--- postgresql/contrib/pg_upgrade/util.c	2012-10-03 10:40:48.243207034 +0200
+++ postgresql.2/contrib/pg_upgrade/util.c	2012-11-30 09:49:47.074595974 +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/src/bin/initdb/initdb.c postgresql.2/src/bin/initdb/initdb.c
--- postgresql/src/bin/initdb/initdb.c	2012-10-15 10:44:54.640429361 +0200
+++ postgresql.2/src/bin/initdb/initdb.c	2012-11-30 09:49:47.076595989 +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/src/bin/pg_basebackup/pg_basebackup.c postgresql.2/src/bin/pg_basebackup/pg_basebackup.c
--- postgresql/src/bin/pg_basebackup/pg_basebackup.c	2012-10-03 10:40:48.297207389 +0200
+++ postgresql.2/src/bin/pg_basebackup/pg_basebackup.c	2012-11-30 09:49:47.077595997 +0100
@@ -1262,6 +1262,8 @@ main(int argc, char **argv)
 
 	int			option_index;
 
+	InitPostgresFrontend(&streamutil_fe_data);
+
 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
 
diff -durpN postgresql/src/bin/pg_basebackup/pg_receivexlog.c postgresql.2/src/bin/pg_basebackup/pg_receivexlog.c
--- postgresql/src/bin/pg_basebackup/pg_receivexlog.c	2012-10-03 10:40:48.298207395 +0200
+++ postgresql.2/src/bin/pg_basebackup/pg_receivexlog.c	2012-11-30 09:49:47.078596004 +0100
@@ -283,6 +283,7 @@ StreamLog(void)
 					  stop_streaming, standby_message_timeout, false);
 
 	PQfinish(conn);
+	conn = NULL; /* don't crash on the atexit function */
 }
 
 /*
@@ -318,6 +319,8 @@ main(int argc, char **argv)
 	int			c;
 	int			option_index;
 
+	InitPostgresFrontend(&streamutil_fe_data);
+
 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_receivexlog"));
 
diff -durpN postgresql/src/bin/pg_basebackup/streamutil.c postgresql.2/src/bin/pg_basebackup/streamutil.c
--- postgresql/src/bin/pg_basebackup/streamutil.c	2012-10-03 10:40:48.298207395 +0200
+++ postgresql.2/src/bin/pg_basebackup/streamutil.c	2012-11-30 09:49:47.078596004 +0100
@@ -31,42 +31,29 @@ int			dbgetpassword = 0;	/* 0=auto, -1=n
 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)
+static void
+streamutil_malloc_oom(void)
 {
-	char	   *result;
-
-	result = strdup(s);
-	if (!result)
-	{
-		fprintf(stderr, _("%s: out of memory\n"), progname);
-		exit(1);
-	}
-	return result;
+	fprintf(stderr, _("%s: out of memory\n"), progname);
 }
 
-void *
-pg_malloc0(size_t size)
+static void
+streamutil_strdup_null(void)
 {
-	void	   *result;
+	fprintf(stderr, _("%s: pg_strdup: cannot duplicate null pointer (internal error)\n"), progname);
+}
 
-	/* 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;
+static void
+streamutil_app_atexit(void)
+{
+	if (conn != NULL)
+		PQfinish(conn);
 }
 
+PostgresFrontendData	streamutil_fe_data = {
+	streamutil_malloc_oom, streamutil_strdup_null, streamutil_app_atexit
+};
+
 
 /*
  * Connect to the server. Returns a valid PGconn pointer if connected,
diff -durpN postgresql/src/bin/pg_basebackup/streamutil.h postgresql.2/src/bin/pg_basebackup/streamutil.h
--- postgresql/src/bin/pg_basebackup/streamutil.h	2012-10-03 10:40:48.299207401 +0200
+++ postgresql.2/src/bin/pg_basebackup/streamutil.h	2012-11-30 09:49:47.079596011 +0100
@@ -15,8 +15,6 @@ extern PGconn *conn;
 	exit(code);									\
 	}
 
-
-extern char *pg_strdup(const char *s);
-extern void *pg_malloc0(size_t size);
+extern PostgresFrontendData streamutil_fe_data;
 
 extern PGconn *GetConnection(void);
diff -durpN postgresql/src/bin/pg_ctl/pg_ctl.c postgresql.2/src/bin/pg_ctl/pg_ctl.c
--- postgresql/src/bin/pg_ctl/pg_ctl.c	2012-10-19 19:12:00.307691010 +0200
+++ postgresql.2/src/bin/pg_ctl/pg_ctl.c	2012-11-30 09:49:47.079596011 +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/src/bin/pg_dump/common.c postgresql.2/src/bin/pg_dump/common.c
--- postgresql/src/bin/pg_dump/common.c	2012-07-22 16:48:48.536857822 +0200
+++ postgresql.2/src/bin/pg_dump/common.c	2012-11-30 09:49:47.080596019 +0100
@@ -18,7 +18,6 @@
 #include <ctype.h>
 
 #include "catalog/pg_class.h"
-#include "dumpmem.h"
 #include "dumputils.h"
 
 
diff -durpN postgresql/src/bin/pg_dump/compress_io.c postgresql.2/src/bin/pg_dump/compress_io.c
--- postgresql/src/bin/pg_dump/compress_io.c	2012-10-03 10:40:48.301207415 +0200
+++ postgresql.2/src/bin/pg_dump/compress_io.c	2012-11-30 09:49:47.080596019 +0100
@@ -53,7 +53,6 @@
  */
 
 #include "compress_io.h"
-#include "dumpmem.h"
 #include "dumputils.h"
 
 /*----------------------
diff -durpN postgresql/src/bin/pg_dump/dumpmem.c postgresql.2/src/bin/pg_dump/dumpmem.c
--- postgresql/src/bin/pg_dump/dumpmem.c	2012-10-03 10:40:48.301207415 +0200
+++ postgresql.2/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/src/bin/pg_dump/dumpmem.h postgresql.2/src/bin/pg_dump/dumpmem.h
--- postgresql/src/bin/pg_dump/dumpmem.h	2012-10-03 10:40:48.301207415 +0200
+++ postgresql.2/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/src/bin/pg_dump/Makefile postgresql.2/src/bin/pg_dump/Makefile
--- postgresql/src/bin/pg_dump/Makefile	2012-04-16 19:57:22.595917312 +0200
+++ postgresql.2/src/bin/pg_dump/Makefile	2012-11-30 09:49:47.085596058 +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/src/bin/pg_dump/nls.mk postgresql.2/src/bin/pg_dump/nls.mk
--- postgresql/src/bin/pg_dump/nls.mk	2012-04-16 19:57:22.596917323 +0200
+++ postgresql.2/src/bin/pg_dump/nls.mk	2012-11-30 09:49:47.086596065 +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/src/bin/pg_dump/pg_backup_archiver.c postgresql.2/src/bin/pg_dump/pg_backup_archiver.c
--- postgresql/src/bin/pg_dump/pg_backup_archiver.c	2012-10-21 10:56:15.398945610 +0200
+++ postgresql.2/src/bin/pg_dump/pg_backup_archiver.c	2012-11-30 09:49:47.088596080 +0100
@@ -21,7 +21,6 @@
  */
 
 #include "pg_backup_db.h"
-#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <ctype.h>
diff -durpN postgresql/src/bin/pg_dump/pg_backup_custom.c postgresql.2/src/bin/pg_dump/pg_backup_custom.c
--- postgresql/src/bin/pg_dump/pg_backup_custom.c	2012-10-03 10:40:48.303207429 +0200
+++ postgresql.2/src/bin/pg_dump/pg_backup_custom.c	2012-11-30 09:49:47.089596088 +0100
@@ -26,7 +26,6 @@
 
 #include "compress_io.h"
 #include "dumputils.h"
-#include "dumpmem.h"
 
 /*--------
  * Routines in the format interface
diff -durpN postgresql/src/bin/pg_dump/pg_backup_db.c postgresql.2/src/bin/pg_dump/pg_backup_db.c
--- postgresql/src/bin/pg_dump/pg_backup_db.c	2012-07-25 10:51:14.973507544 +0200
+++ postgresql.2/src/bin/pg_dump/pg_backup_db.c	2012-11-30 09:49:47.090596096 +0100
@@ -11,7 +11,6 @@
  */
 
 #include "pg_backup_db.h"
-#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <unistd.h>
diff -durpN postgresql/src/bin/pg_dump/pg_backup_directory.c postgresql.2/src/bin/pg_dump/pg_backup_directory.c
--- postgresql/src/bin/pg_dump/pg_backup_directory.c	2012-10-03 10:40:48.303207429 +0200
+++ postgresql.2/src/bin/pg_dump/pg_backup_directory.c	2012-11-30 09:49:47.091596103 +0100
@@ -34,7 +34,6 @@
  */
 
 #include "compress_io.h"
-#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <dirent.h>
diff -durpN postgresql/src/bin/pg_dump/pg_backup_null.c postgresql.2/src/bin/pg_dump/pg_backup_null.c
--- postgresql/src/bin/pg_dump/pg_backup_null.c	2012-04-16 19:57:22.598917347 +0200
+++ postgresql.2/src/bin/pg_dump/pg_backup_null.c	2012-11-30 09:49:47.092596110 +0100
@@ -23,7 +23,6 @@
  */
 
 #include "pg_backup_archiver.h"
-#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <unistd.h>				/* for dup */
diff -durpN postgresql/src/bin/pg_dump/pg_backup_tar.c postgresql.2/src/bin/pg_dump/pg_backup_tar.c
--- postgresql/src/bin/pg_dump/pg_backup_tar.c	2012-10-03 10:40:48.304207436 +0200
+++ postgresql.2/src/bin/pg_dump/pg_backup_tar.c	2012-11-30 09:49:47.093596118 +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/src/bin/pg_dump/pg_dumpall.c postgresql.2/src/bin/pg_dump/pg_dumpall.c
--- postgresql/src/bin/pg_dump/pg_dumpall.c	2012-10-14 11:09:08.143146185 +0200
+++ postgresql.2/src/bin/pg_dump/pg_dumpall.c	2012-11-30 09:49:47.095596134 +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/src/bin/pg_dump/pg_dump.c postgresql.2/src/bin/pg_dump/pg_dump.c
--- postgresql/src/bin/pg_dump/pg_dump.c	2012-10-28 07:41:12.051532033 +0100
+++ postgresql.2/src/bin/pg_dump/pg_dump.c	2012-11-30 09:49:47.100596172 +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/src/bin/pg_dump/pg_dump_sort.c postgresql.2/src/bin/pg_dump/pg_dump_sort.c
--- postgresql/src/bin/pg_dump/pg_dump_sort.c	2012-10-19 19:12:00.334691199 +0200
+++ postgresql.2/src/bin/pg_dump/pg_dump_sort.c	2012-11-30 09:49:47.101596179 +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/src/bin/pg_dump/pg_restore.c postgresql.2/src/bin/pg_dump/pg_restore.c
--- postgresql/src/bin/pg_dump/pg_restore.c	2012-10-14 11:09:08.143146185 +0200
+++ postgresql.2/src/bin/pg_dump/pg_restore.c	2012-11-30 09:49:47.101596179 +0100
@@ -41,7 +41,6 @@
 
 #include "pg_backup_archiver.h"
 
-#include "dumpmem.h"
 #include "dumputils.h"
 
 #include <ctype.h>
diff -durpN postgresql/src/bin/psql/common.c postgresql.2/src/bin/psql/common.c
--- postgresql/src/bin/psql/common.c	2012-10-03 10:40:48.322207553 +0200
+++ postgresql.2/src/bin/psql/common.c	2012-11-30 09:49:47.102596186 +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/src/bin/psql/common.h postgresql.2/src/bin/psql/common.h
--- postgresql/src/bin/psql/common.h	2012-10-03 10:40:48.322207553 +0200
+++ postgresql.2/src/bin/psql/common.h	2012-11-30 09:49:47.102596186 +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/src/bin/psql/startup.c postgresql.2/src/bin/psql/startup.c
--- postgresql/src/bin/psql/startup.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/psql/startup.c	2012-11-30 09:49:47.102596186 +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/src/bin/scripts/clusterdb.c postgresql.2/src/bin/scripts/clusterdb.c
--- postgresql/src/bin/scripts/clusterdb.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/clusterdb.c	2012-11-30 09:49:47.103596194 +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/src/bin/scripts/common.c postgresql.2/src/bin/scripts/common.c
--- postgresql/src/bin/scripts/common.c	2012-10-03 10:40:48.324207567 +0200
+++ postgresql.2/src/bin/scripts/common.c	2012-11-30 09:49:47.104596202 +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/src/bin/scripts/common.h postgresql.2/src/bin/scripts/common.h
--- postgresql/src/bin/scripts/common.h	2012-10-03 10:40:48.324207567 +0200
+++ postgresql.2/src/bin/scripts/common.h	2012-11-30 09:49:47.104596202 +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/src/bin/scripts/createdb.c postgresql.2/src/bin/scripts/createdb.c
--- postgresql/src/bin/scripts/createdb.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/createdb.c	2012-11-30 09:49:47.105596209 +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/src/bin/scripts/createlang.c postgresql.2/src/bin/scripts/createlang.c
--- postgresql/src/bin/scripts/createlang.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/createlang.c	2012-11-30 09:49:47.105596209 +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/src/bin/scripts/createuser.c postgresql.2/src/bin/scripts/createuser.c
--- postgresql/src/bin/scripts/createuser.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/createuser.c	2012-11-30 09:49:47.106596217 +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/src/bin/scripts/dropdb.c postgresql.2/src/bin/scripts/dropdb.c
--- postgresql/src/bin/scripts/dropdb.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/dropdb.c	2012-11-30 09:49:47.107596225 +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/src/bin/scripts/droplang.c postgresql.2/src/bin/scripts/droplang.c
--- postgresql/src/bin/scripts/droplang.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/droplang.c	2012-11-30 09:49:47.107596225 +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/src/bin/scripts/dropuser.c postgresql.2/src/bin/scripts/dropuser.c
--- postgresql/src/bin/scripts/dropuser.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/dropuser.c	2012-11-30 09:49:47.108596233 +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/src/bin/scripts/reindexdb.c postgresql.2/src/bin/scripts/reindexdb.c
--- postgresql/src/bin/scripts/reindexdb.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/reindexdb.c	2012-11-30 09:49:47.108596233 +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/src/bin/scripts/vacuumdb.c postgresql.2/src/bin/scripts/vacuumdb.c
--- postgresql/src/bin/scripts/vacuumdb.c	2012-10-14 11:09:08.144146192 +0200
+++ postgresql.2/src/bin/scripts/vacuumdb.c	2012-11-30 09:49:47.109596240 +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/src/include/port.h postgresql.2/src/include/port.h
--- postgresql/src/include/port.h	2012-07-22 16:48:48.548857900 +0200
+++ postgresql.2/src/include/port.h	2012-11-30 09:49:47.109596240 +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/src/port/init.c postgresql.2/src/port/init.c
--- postgresql/src/port/init.c	1970-01-01 01:00:00.000000000 +0100
+++ postgresql.2/src/port/init.c	2012-11-30 09:49:47.109596240 +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/src/port/Makefile postgresql.2/src/port/Makefile
--- postgresql/src/port/Makefile	2012-05-09 12:28:11.755496856 +0200
+++ postgresql.2/src/port/Makefile	2012-11-30 09:49:47.110596247 +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/src/port/pgmalloc.c postgresql.2/src/port/pgmalloc.c
--- postgresql/src/port/pgmalloc.c	1970-01-01 01:00:00.000000000 +0100
+++ postgresql.2/src/port/pgmalloc.c	2012-11-30 09:49:47.111596255 +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
