pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Started by Heikki Linnakangasalmost 13 years ago12 messages
#1Heikki Linnakangas
heikki.linnakangas@iki.fi

Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Per warning from -Wmissing-format-attribute.

Branch
------
master

Details
-------
http://git.postgresql.org/pg/commitdiff/ea988ee8c8b191615e730f930bcde6144a598688

Modified Files
--------------
src/bin/pg_dump/dumputils.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

--
Sent via pgsql-committers mailing list (pgsql-committers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-committers

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#1)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Heikki Linnakangas <heikki.linnakangas@iki.fi> writes:

Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.
Per warning from -Wmissing-format-attribute.

Hm, this is exactly what I removed yesterday, because it makes the build
fail outright on old gcc:

gcc -O1 -Wall -Wmissing-prototypes -Wpointer-arith -Wformat-security -fno-strict-aliasing -g -I../../../src/interfaces/libpq -I../../../src/include -D_XOPEN_SOURCE_EXTENDED -D_USE_CTYPE_MACROS -c -o pg_dump.o pg_dump.c
In file included from pg_backup.h:29,
from pg_backup_archiver.h:32,
from pg_dump.c:60:
dumputils.h:48: argument format specified for non-function `on_exit_msg_func'
make: *** [pg_dump.o] Error 1

Perhaps we have to refactor to avoid the use of a function variable
here. It didn't seem particularly critical to do it like that rather
than with, say, a bool.

Or maybe we should turn off that warning. It seems to be leaping to
conclusions about what the usage of the function variable is.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Tom Lane (#2)
1 attachment(s)
Re: pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

On 25.03.2013 15:36, Tom Lane wrote:

Heikki Linnakangas<heikki.linnakangas@iki.fi> writes:

Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.
Per warning from -Wmissing-format-attribute.

Hm, this is exactly what I removed yesterday, because it makes the build
fail outright on old gcc:

gcc -O1 -Wall -Wmissing-prototypes -Wpointer-arith -Wformat-security -fno-strict-aliasing -g -I../../../src/interfaces/libpq -I../../../src/include -D_XOPEN_SOURCE_EXTENDED -D_USE_CTYPE_MACROS -c -o pg_dump.o pg_dump.c
In file included from pg_backup.h:29,
from pg_backup_archiver.h:32,
from pg_dump.c:60:
dumputils.h:48: argument format specified for non-function `on_exit_msg_func'
make: *** [pg_dump.o] Error 1

Perhaps we have to refactor to avoid the use of a function variable
here. It didn't seem particularly critical to do it like that rather
than with, say, a bool.

Hmm. exit_horribly() is also used in pg_dumpall, so if you just put a
call to a function in parallel.c in there, the linker will complain when
linking pg_dumpall.

BTW, we never reset on_exit_msg_func, even after getting out of parallel
mode by calling ParallelBackupEnd(). The Assert in
parallel_exit_msg_func() will fail if it gets called after
ParallelBackupEnd().

The attached seems to work. With this patch, on_exit_msg_func() is gone.
There's a different implementation of exit_horribly for pg_dumpall and
pg_dump/restore. In pg_dumpall, it just calls vwrite_msg(). In
pg_dump/restore's version, the logic from parallel_exit_msg_func() is
moved directly to exit_horribly().

Or maybe we should turn off that warning. It seems to be leaping to
conclusions about what the usage of the function variable is.

Oh? Its conclusion seems correct to me: the function variable takes
printf-like arguments.

- Heikki

Attachments:

avoid-printf-like-function-var.patchtext/x-diff; name=avoid-printf-like-function-var.patchDownload
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 38,44 **** static struct
  }	on_exit_nicely_list[MAX_ON_EXIT_NICELY];
  
  static int	on_exit_nicely_index;
- void		(*on_exit_msg_func) (const char *modulename, const char *fmt, va_list ap) = vwrite_msg;
  
  #define supports_grant_options(version) ((version) >= 70400)
  
--- 38,43 ----
***************
*** 1365,1386 **** vwrite_msg(const char *modulename, const char *fmt, va_list ap)
  	vfprintf(stderr, _(fmt), ap);
  }
  
- 
- /*
-  * Fail and die, with a message to stderr.	Parameters as for write_msg.
-  */
- void
- exit_horribly(const char *modulename, const char *fmt,...)
- {
- 	va_list		ap;
- 
- 	va_start(ap, fmt);
- 	on_exit_msg_func(modulename, fmt, ap);
- 	va_end(ap);
- 
- 	exit_nicely(1);
- }
- 
  /* Register a callback to be run when exit_nicely is invoked. */
  void
  on_exit_nicely(on_exit_nicely_callback function, void *arg)
--- 1364,1369 ----
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
***************
*** 44,51 **** typedef void (*on_exit_nicely_callback) (int code, void *arg);
  
  extern int	quote_all_identifiers;
  extern const char *progname;
- extern void (*on_exit_msg_func) (const char *modulename, const char *fmt, va_list ap)
- __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
  
  extern void init_parallel_dump_utils(void);
  extern const char *fmtId(const char *identifier);
--- 44,49 ----
***************
*** 86,91 **** __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
--- 84,93 ----
  extern void
  vwrite_msg(const char *modulename, const char *fmt, va_list ap)
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+ /*
+  * exit_horribly is not implemented in dumputils.c. Rather, pg_dump and
+  * pg_dumpall have a different implementation of it, with the same signature.
+  */
  extern void
  exit_horribly(const char *modulename, const char *fmt,...)
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
*** a/src/bin/pg_dump/parallel.c
--- b/src/bin/pg_dump/parallel.c
***************
*** 72,87 **** typedef struct ShutdownInformation
  	Archive    *AHX;
  } ShutdownInformation;
  
! static ShutdownInformation shutdown_info;
  
  static const char *modulename = gettext_noop("parallel archiver");
  
  static ParallelSlot *GetMyPSlot(ParallelState *pstate);
  static void
- parallel_exit_msg_func(const char *modulename,
- 					   const char *fmt, va_list ap)
- __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
- static void
  parallel_msg_master(ParallelSlot *slot, const char *modulename,
  					const char *fmt, va_list ap)
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
--- 72,83 ----
  	Archive    *AHX;
  } ShutdownInformation;
  
! static ShutdownInformation shutdown_info = { NULL, NULL };
  
  static const char *modulename = gettext_noop("parallel archiver");
  
  static ParallelSlot *GetMyPSlot(ParallelState *pstate);
  static void
  parallel_msg_master(ParallelSlot *slot, const char *modulename,
  					const char *fmt, va_list ap)
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
***************
*** 129,157 **** GetMyPSlot(ParallelState *pstate)
  }
  
  /*
!  * This is the function that will be called from exit_horribly() to print the
!  * error message. If the worker process does exit_horribly(), we forward its
!  * last words to the master process. The master process then does
!  * exit_horribly() with this error message itself and prints it normally.
!  * After printing the message, exit_horribly() on the master will shut down
!  * the remaining worker processes.
   */
! static void
! parallel_exit_msg_func(const char *modulename, const char *fmt, va_list ap)
  {
  	ParallelState *pstate = shutdown_info.pstate;
  	ParallelSlot *slot;
  
! 	Assert(pstate);
  
! 	slot = GetMyPSlot(pstate);
! 
! 	if (!slot)
! 		/* We're the parent, just write the message out */
  		vwrite_msg(modulename, fmt, ap);
  	else
! 		/* If we're a worker process, send the msg to the master process */
! 		parallel_msg_master(slot, modulename, fmt, ap);
  }
  
  /* Sends the error message from the worker to the master process */
--- 125,168 ----
  }
  
  /*
!  * Fail and die, with a message to stderr.	Parameters as for write_msg.
!  *
!  * This is defined in parallel.c because in parallel mode, things are more
!  * complicated. If The worker process does exit_horribly(), we forward its last
!  * words to the master process. The master process then does exit_horribly()
!  * with this error message itself and prints it normally. After printing the
!  * message, exit_horribly() on the master will shut down the remaining worker
!  * processes.
   */
! void
! exit_horribly(const char *modulename, const char *fmt,...)
  {
+ 	va_list		ap;
  	ParallelState *pstate = shutdown_info.pstate;
  	ParallelSlot *slot;
  
! 	va_start(ap, fmt);
  
! 	if (pstate == NULL)
! 	{
! 		/* Not in parallel mode, just write it out */
  		vwrite_msg(modulename, fmt, ap);
+ 	}
  	else
! 	{
! 		slot = GetMyPSlot(pstate);
! 
! 		if (!slot)
! 			/* We're the parent, just write the message out */
! 			vwrite_msg(modulename, fmt, ap);
! 		else
! 			/* If we're a worker process, send the msg to the master process */
! 			parallel_msg_master(slot, modulename, fmt, ap);
! 	}
! 
! 	va_end(ap);
! 
! 	exit_nicely(1);
  }
  
  /* Sends the error message from the worker to the master process */
***************
*** 408,414 **** ParallelBackupStart(ArchiveHandle *AH, RestoreOptions *ropt)
  	 * set and falls back to AHX otherwise.
  	 */
  	shutdown_info.pstate = pstate;
- 	on_exit_msg_func = parallel_exit_msg_func;
  
  #ifdef WIN32
  	tMasterThreadId = GetCurrentThreadId();
--- 419,424 ----
*** a/src/bin/pg_dump/pg_dumpall.c
--- b/src/bin/pg_dump/pg_dumpall.c
***************
*** 583,588 **** help(void)
--- 583,602 ----
  	printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
  }
  
+ /*
+  * Fail and die, with a message to stderr.	Parameters as for write_msg.
+  */
+ void
+ exit_horribly(const char *modulename, const char *fmt,...)
+ {
+ 	va_list		ap;
+ 
+ 	va_start(ap, fmt);
+ 	vwrite_msg(modulename, fmt, ap);
+ 	va_end(ap);
+ 
+ 	exit_nicely(1);
+ }
  
  /*
   * Drop roles
#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#3)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Heikki Linnakangas <hlinnakangas@vmware.com> writes:

On 25.03.2013 15:36, Tom Lane wrote:

Heikki Linnakangas<heikki.linnakangas@iki.fi> writes:

Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.
Per warning from -Wmissing-format-attribute.

Hm, this is exactly what I removed yesterday, because it makes the build
fail outright on old gcc:

The attached seems to work. With this patch, on_exit_msg_func() is gone.
There's a different implementation of exit_horribly for pg_dumpall and
pg_dump/restore. In pg_dumpall, it just calls vwrite_msg(). In
pg_dump/restore's version, the logic from parallel_exit_msg_func() is
moved directly to exit_horribly().

Seems probably reasonable, though if we're taking exit_horribly out of
dumputils.c, meseems it ought not be declared in dumputils.h anymore.
Can we put that declaration someplace else, rather than commenting it
with an apology?

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Tom Lane (#4)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

On 26.03.2013 02:02, Tom Lane wrote:

Heikki Linnakangas<hlinnakangas@vmware.com> writes:

On 25.03.2013 15:36, Tom Lane wrote:

Heikki Linnakangas<heikki.linnakangas@iki.fi> writes:

Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.
Per warning from -Wmissing-format-attribute.

Hm, this is exactly what I removed yesterday, because it makes the build
fail outright on old gcc:

The attached seems to work. With this patch, on_exit_msg_func() is gone.
There's a different implementation of exit_horribly for pg_dumpall and
pg_dump/restore. In pg_dumpall, it just calls vwrite_msg(). In
pg_dump/restore's version, the logic from parallel_exit_msg_func() is
moved directly to exit_horribly().

Seems probably reasonable, though if we're taking exit_horribly out of
dumputils.c, meseems it ought not be declared in dumputils.h anymore.
Can we put that declaration someplace else, rather than commenting it
with an apology?

Ugh, the patch I posted doesn't actually work, because dumputils.c is
also used in psql and some scripts, so you get a linker error in those.
psql and scripts don't use exit_horribly or many of the other functions
in dumputils.c, so I think we should split dumputils.c into two parts
anyway. fmtId and the other functions that are used by psql in one file,
and the functions that are only shared between pg_dumpall and pg_dump in
another. Then there's also functions that are used by pg_dump and
pg_restore, but not pg_dumpall or psql.

I'll try moving things around a bit...

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Heikki Linnakangas (#5)
1 attachment(s)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

On 26.03.2013 09:51, Heikki Linnakangas wrote:

On 26.03.2013 02:02, Tom Lane wrote:

Heikki Linnakangas<hlinnakangas@vmware.com> writes:

On 25.03.2013 15:36, Tom Lane wrote:

Heikki Linnakangas<heikki.linnakangas@iki.fi> writes:

Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.
Per warning from -Wmissing-format-attribute.

Hm, this is exactly what I removed yesterday, because it makes the
build
fail outright on old gcc:

The attached seems to work. With this patch, on_exit_msg_func() is gone.
There's a different implementation of exit_horribly for pg_dumpall and
pg_dump/restore. In pg_dumpall, it just calls vwrite_msg(). In
pg_dump/restore's version, the logic from parallel_exit_msg_func() is
moved directly to exit_horribly().

Seems probably reasonable, though if we're taking exit_horribly out of
dumputils.c, meseems it ought not be declared in dumputils.h anymore.
Can we put that declaration someplace else, rather than commenting it
with an apology?

Ugh, the patch I posted doesn't actually work, because dumputils.c is
also used in psql and some scripts, so you get a linker error in those.
psql and scripts don't use exit_horribly or many of the other functions
in dumputils.c, so I think we should split dumputils.c into two parts
anyway. fmtId and the other functions that are used by psql in one file,
and the functions that are only shared between pg_dumpall and pg_dump in
another. Then there's also functions that are used by pg_dump and
pg_restore, but not pg_dumpall or psql.

I'll try moving things around a bit...

This is what I came up with. I created a new file, misc.c (for lack of a
better name), for things that are shared by pg_dump and pg_restore, but
not pg_dumpall or other programs. I moved all the parallel stuff from
dumputils.c to parallel.c, and everything else that's not used outside
pg_dump and pg_restore to misc.c. I moved exit_horribly() to parallel.c,
because it needs to do things differently in parallel mode.

I still used a function pointer, not for the printf-style message
printing routine, but for making dumputils.c independent of parallel
mode. getThreadLocalPQBuffer() is now a function pointer; the default
implementation just uses a static variable, but when pg_dump/restore
enters parallel mode, it points the function pointer to a version that
uses thread-local storage (on windows).

- Heikki

Attachments:

refactor-dumputils.patchtext/x-diff; name=refactor-dumputils.patchDownload
*** a/src/bin/pg_dump/Makefile
--- b/src/bin/pg_dump/Makefile
***************
*** 19,25 **** include $(top_builddir)/src/Makefile.global
  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 parallel.o \
  	pg_backup_directory.o dumputils.o compress_io.o $(WIN32RES)
  
  KEYWRDOBJS = keywords.o kwlookup.o
--- 19,25 ----
  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 parallel.o misc.o \
  	pg_backup_directory.o dumputils.o compress_io.o $(WIN32RES)
  
  KEYWRDOBJS = keywords.o kwlookup.o
*** a/src/bin/pg_dump/common.c
--- b/src/bin/pg_dump/common.c
***************
*** 14,19 ****
--- 14,20 ----
   *-------------------------------------------------------------------------
   */
  #include "pg_backup_archiver.h"
+ #include "misc.h"
  
  #include <ctype.h>
  
*** a/src/bin/pg_dump/compress_io.c
--- b/src/bin/pg_dump/compress_io.c
***************
*** 53,59 ****
   */
  
  #include "compress_io.h"
! #include "dumputils.h"
  #include "parallel.h"
  
  /*----------------------
--- 53,59 ----
   */
  
  #include "compress_io.h"
! #include "misc.h"
  #include "parallel.h"
  
  /*----------------------
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 25,45 ****
  extern const ScanKeyword FEScanKeywords[];
  extern const int NumFEScanKeywords;
  
- /* Globals exported by this file */
- int			quote_all_identifiers = 0;
- const char *progname = NULL;
- 
- #define MAX_ON_EXIT_NICELY				20
- 
- static struct
- {
- 	on_exit_nicely_callback function;
- 	void	   *arg;
- }	on_exit_nicely_list[MAX_ON_EXIT_NICELY];
- 
- static int	on_exit_nicely_index;
- void		(*on_exit_msg_func) (const char *modulename, const char *fmt, va_list ap) = vwrite_msg;
- 
  #define supports_grant_options(version) ((version) >= 70400)
  
  static bool parseAclItem(const char *item, const char *type,
--- 25,30 ----
***************
*** 49,116 **** static bool parseAclItem(const char *item, const char *type,
  static char *copyAclUserName(PQExpBuffer output, char *input);
  static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
  	   const char *subname);
! static PQExpBuffer getThreadLocalPQExpBuffer(void);
! 
! #ifdef WIN32
! static void shutdown_parallel_dump_utils(int code, void *unused);
! static bool parallel_init_done = false;
! static DWORD tls_index;
! static DWORD mainThreadId;
  
! static void
! shutdown_parallel_dump_utils(int code, void *unused)
! {
! 	/* Call the cleanup function only from the main thread */
! 	if (mainThreadId == GetCurrentThreadId())
! 		WSACleanup();
! }
! #endif
! 
! void
! init_parallel_dump_utils(void)
! {
! #ifdef WIN32
! 	if (!parallel_init_done)
! 	{
! 		WSADATA		wsaData;
! 		int			err;
! 
! 		tls_index = TlsAlloc();
! 		mainThreadId = GetCurrentThreadId();
! 		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
! 		if (err != 0)
! 		{
! 			fprintf(stderr, _("WSAStartup failed: %d\n"), err);
! 			exit_nicely(1);
! 		}
! 		on_exit_nicely(shutdown_parallel_dump_utils, NULL);
! 		parallel_init_done = true;
! 	}
! #endif
! }
  
  /*
!  * Non-reentrant but reduces memory leakage. (On Windows the memory leakage
!  * will be one buffer per thread, which is at least better than one per call).
   */
  static PQExpBuffer
! getThreadLocalPQExpBuffer(void)
  {
! 	/*
! 	 * The Tls code goes awry if we use a static var, so we provide for both
! 	 * static and auto, and omit any use of the static var when using Tls.
! 	 */
! 	static PQExpBuffer s_id_return = NULL;
! 	PQExpBuffer id_return;
! 
! #ifdef WIN32
! 	if (parallel_init_done)
! 		id_return = (PQExpBuffer) TlsGetValue(tls_index);		/* 0 when not set */
! 	else
! 		id_return = s_id_return;
! #else
! 	id_return = s_id_return;
! #endif
  
  	if (id_return)				/* first time through? */
  	{
--- 34,57 ----
  static char *copyAclUserName(PQExpBuffer output, char *input);
  static void AddAcl(PQExpBuffer aclbuf, const char *keyword,
  	   const char *subname);
! static PQExpBuffer defaultGetLocalPQExpBuffer(void);
  
! /* Globals exported by this file */
! int			quote_all_identifiers = 0;
! PQExpBuffer (*getLocalPQExpBuffer) (void) = defaultGetLocalPQExpBuffer;
  
  /*
!  * Returns a temporary PQExpBuffer, valid until the next call to the function.
!  * This is used by fmtId and fmtQualifiedId.
!  *
!  * Non-reentrant and non-thread-safe but reduces memory leakage. You can
!  * replace this with a custom version by setting the getLocalPQExpBuffer
!  * function pointer.
   */
  static PQExpBuffer
! defaultGetLocalPQExpBuffer(void)
  {
! 	static PQExpBuffer id_return = NULL;
  
  	if (id_return)				/* first time through? */
  	{
***************
*** 121,135 **** getThreadLocalPQExpBuffer(void)
  	{
  		/* new buffer */
  		id_return = createPQExpBuffer();
- #ifdef WIN32
- 		if (parallel_init_done)
- 			TlsSetValue(tls_index, id_return);
- 		else
- 			s_id_return = id_return;
- #else
- 		s_id_return = id_return;
- #endif
- 
  	}
  
  	return id_return;
--- 62,67 ----
***************
*** 144,150 **** getThreadLocalPQExpBuffer(void)
  const char *
  fmtId(const char *rawid)
  {
! 	PQExpBuffer id_return = getThreadLocalPQExpBuffer();
  
  	const char *cp;
  	bool		need_quotes = false;
--- 76,82 ----
  const char *
  fmtId(const char *rawid)
  {
! 	PQExpBuffer id_return = getLocalPQExpBuffer();
  
  	const char *cp;
  	bool		need_quotes = false;
***************
*** 238,244 **** fmtQualifiedId(int remoteVersion, const char *schema, const char *id)
  	}
  	appendPQExpBuffer(lcl_pqexp, "%s", fmtId(id));
  
! 	id_return = getThreadLocalPQExpBuffer();
  
  	appendPQExpBuffer(id_return, "%s", lcl_pqexp->data);
  	destroyPQExpBuffer(lcl_pqexp);
--- 170,176 ----
  	}
  	appendPQExpBuffer(lcl_pqexp, "%s", fmtId(id));
  
! 	id_return = getLocalPQExpBuffer();
  
  	appendPQExpBuffer(id_return, "%s", lcl_pqexp->data);
  	destroyPQExpBuffer(lcl_pqexp);
***************
*** 1278,1395 **** emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer,
  }
  
  
- /*
-  * Parse a --section=foo command line argument.
-  *
-  * Set or update the bitmask in *dumpSections according to arg.
-  * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
-  * pg_restore so they can know if this has even been called.
-  */
- void
- set_dump_section(const char *arg, int *dumpSections)
- {
- 	/* if this is the first call, clear all the bits */
- 	if (*dumpSections == DUMP_UNSECTIONED)
- 		*dumpSections = 0;
- 
- 	if (strcmp(arg, "pre-data") == 0)
- 		*dumpSections |= DUMP_PRE_DATA;
- 	else if (strcmp(arg, "data") == 0)
- 		*dumpSections |= DUMP_DATA;
- 	else if (strcmp(arg, "post-data") == 0)
- 		*dumpSections |= DUMP_POST_DATA;
- 	else
- 	{
- 		fprintf(stderr, _("%s: unrecognized section name: \"%s\"\n"),
- 				progname, arg);
- 		fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
- 				progname);
- 		exit_nicely(1);
- 	}
- }
- 
- 
- /*
-  * Write a printf-style message to stderr.
-  *
-  * The program name is prepended, if "progname" has been set.
-  * Also, if modulename isn't NULL, that's included too.
-  * Note that we'll try to translate the modulename and the fmt string.
-  */
- void
- write_msg(const char *modulename, const char *fmt,...)
- {
- 	va_list		ap;
- 
- 	va_start(ap, fmt);
- 	vwrite_msg(modulename, fmt, ap);
- 	va_end(ap);
- }
- 
- /*
-  * As write_msg, but pass a va_list not variable arguments.
-  */
- void
- vwrite_msg(const char *modulename, const char *fmt, va_list ap)
- {
- 	if (progname)
- 	{
- 		if (modulename)
- 			fprintf(stderr, "%s: [%s] ", progname, _(modulename));
- 		else
- 			fprintf(stderr, "%s: ", progname);
- 	}
- 	vfprintf(stderr, _(fmt), ap);
- }
- 
- 
- /*
-  * Fail and die, with a message to stderr.	Parameters as for write_msg.
-  */
- void
- exit_horribly(const char *modulename, const char *fmt,...)
- {
- 	va_list		ap;
- 
- 	va_start(ap, fmt);
- 	on_exit_msg_func(modulename, fmt, ap);
- 	va_end(ap);
- 
- 	exit_nicely(1);
- }
- 
- /* Register a callback to be run when exit_nicely is invoked. */
- void
- on_exit_nicely(on_exit_nicely_callback function, void *arg)
- {
- 	if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
- 		exit_horribly(NULL, "out of on_exit_nicely slots\n");
- 	on_exit_nicely_list[on_exit_nicely_index].function = function;
- 	on_exit_nicely_list[on_exit_nicely_index].arg = arg;
- 	on_exit_nicely_index++;
- }
- 
- /*
-  * Run accumulated on_exit_nicely callbacks in reverse order and then exit
-  * quietly.  This needs to be thread-safe.
-  */
- void
- exit_nicely(int code)
- {
- 	int			i;
- 
- 	for (i = on_exit_nicely_index - 1; i >= 0; i--)
- 		(*on_exit_nicely_list[i].function) (code,
- 											on_exit_nicely_list[i].arg);
- 
- #ifdef WIN32
- 	if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
- 		ExitThread(code);
- #endif
- 
- 	exit(code);
- }
- 
  void
  simple_string_list_append(SimpleStringList *list, const char *val)
  {
--- 1210,1215 ----
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
***************
*** 19,32 ****
  #include "libpq-fe.h"
  #include "pqexpbuffer.h"
  
- typedef enum					/* bits returned by set_dump_section */
- {
- 	DUMP_PRE_DATA = 0x01,
- 	DUMP_DATA = 0x02,
- 	DUMP_POST_DATA = 0x04,
- 	DUMP_UNSECTIONED = 0xff
- } DumpSections;
- 
  typedef struct SimpleStringListCell
  {
  	struct SimpleStringListCell *next;
--- 19,24 ----
***************
*** 40,53 **** typedef struct SimpleStringList
  } SimpleStringList;
  
  
- typedef void (*on_exit_nicely_callback) (int code, void *arg);
- 
  extern int	quote_all_identifiers;
! extern const char *progname;
! extern void (*on_exit_msg_func) (const char *modulename, const char *fmt, va_list ap)
! __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
  
- extern void init_parallel_dump_utils(void);
  extern const char *fmtId(const char *identifier);
  extern const char *fmtQualifiedId(int remoteVersion,
  			   const char *schema, const char *id);
--- 32,40 ----
  } SimpleStringList;
  
  
  extern int	quote_all_identifiers;
! extern PQExpBuffer (*getLocalPQExpBuffer) (void);
  
  extern const char *fmtId(const char *identifier);
  extern const char *fmtQualifiedId(int remoteVersion,
  			   const char *schema, const char *id);
***************
*** 79,95 **** extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name,
  extern void emitShSecLabels(PGconn *conn, PGresult *res,
  				PQExpBuffer buffer, const char *target, const char *objname);
  extern void set_dump_section(const char *arg, int *dumpSections);
- extern void
- write_msg(const char *modulename, const char *fmt,...)
- __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
- extern void
- vwrite_msg(const char *modulename, const char *fmt, va_list ap)
- __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
- extern void
- exit_horribly(const char *modulename, const char *fmt,...)
- __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
- extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
- extern void exit_nicely(int code) __attribute__((noreturn));
  
  extern void simple_string_list_append(SimpleStringList *list, const char *val);
  extern bool simple_string_list_member(SimpleStringList *list, const char *val);
--- 66,71 ----
*** /dev/null
--- b/src/bin/pg_dump/misc.c
***************
*** 0 ****
--- 1,126 ----
+ /*-------------------------------------------------------------------------
+  *
+  * misc.c
+  *	Utility routines shared by pg_dump 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/misc.c
+  *
+  *-------------------------------------------------------------------------
+  */
+ #include "postgres_fe.h"
+ 
+ #include "misc.h"
+ #include "parallel.h"
+ 
+ /* Globals exported by this file */
+ const char *progname = NULL;
+ 
+ #define MAX_ON_EXIT_NICELY				20
+ 
+ static struct
+ {
+ 	on_exit_nicely_callback function;
+ 	void	   *arg;
+ }	on_exit_nicely_list[MAX_ON_EXIT_NICELY];
+ 
+ static int	on_exit_nicely_index;
+ 
+ /*
+  * Parse a --section=foo command line argument.
+  *
+  * Set or update the bitmask in *dumpSections according to arg.
+  * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
+  * pg_restore so they can know if this has even been called.
+  */
+ void
+ set_dump_section(const char *arg, int *dumpSections)
+ {
+ 	/* if this is the first call, clear all the bits */
+ 	if (*dumpSections == DUMP_UNSECTIONED)
+ 		*dumpSections = 0;
+ 
+ 	if (strcmp(arg, "pre-data") == 0)
+ 		*dumpSections |= DUMP_PRE_DATA;
+ 	else if (strcmp(arg, "data") == 0)
+ 		*dumpSections |= DUMP_DATA;
+ 	else if (strcmp(arg, "post-data") == 0)
+ 		*dumpSections |= DUMP_POST_DATA;
+ 	else
+ 	{
+ 		fprintf(stderr, _("%s: unrecognized section name: \"%s\"\n"),
+ 				progname, arg);
+ 		fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
+ 				progname);
+ 		exit_nicely(1);
+ 	}
+ }
+ 
+ 
+ /*
+  * Write a printf-style message to stderr.
+  *
+  * The program name is prepended, if "progname" has been set.
+  * Also, if modulename isn't NULL, that's included too.
+  * Note that we'll try to translate the modulename and the fmt string.
+  */
+ void
+ write_msg(const char *modulename, const char *fmt,...)
+ {
+ 	va_list		ap;
+ 
+ 	va_start(ap, fmt);
+ 	vwrite_msg(modulename, fmt, ap);
+ 	va_end(ap);
+ }
+ 
+ /*
+  * As write_msg, but pass a va_list not variable arguments.
+  */
+ void
+ vwrite_msg(const char *modulename, const char *fmt, va_list ap)
+ {
+ 	if (progname)
+ 	{
+ 		if (modulename)
+ 			fprintf(stderr, "%s: [%s] ", progname, _(modulename));
+ 		else
+ 			fprintf(stderr, "%s: ", progname);
+ 	}
+ 	vfprintf(stderr, _(fmt), ap);
+ }
+ 
+ /* Register a callback to be run when exit_nicely is invoked. */
+ void
+ on_exit_nicely(on_exit_nicely_callback function, void *arg)
+ {
+ 	if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
+ 		exit_horribly(NULL, "out of on_exit_nicely slots\n");
+ 	on_exit_nicely_list[on_exit_nicely_index].function = function;
+ 	on_exit_nicely_list[on_exit_nicely_index].arg = arg;
+ 	on_exit_nicely_index++;
+ }
+ 
+ /*
+  * Run accumulated on_exit_nicely callbacks in reverse order and then exit
+  * quietly.  This needs to be thread-safe.
+  */
+ void
+ exit_nicely(int code)
+ {
+ 	int			i;
+ 
+ 	for (i = on_exit_nicely_index - 1; i >= 0; i--)
+ 		(*on_exit_nicely_list[i].function) (code,
+ 											on_exit_nicely_list[i].arg);
+ 
+ #ifdef WIN32
+ 	if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
+ 		ExitThread(code);
+ #endif
+ 
+ 	exit(code);
+ }
*** /dev/null
--- b/src/bin/pg_dump/misc.h
***************
*** 0 ****
--- 1,47 ----
+ /*-------------------------------------------------------------------------
+  *
+  * misc.h
+  *	Utility routines shared by pg_dump 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/misc.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #ifndef PG_DUMP_MISC_H
+ #define PG_DUMP_MISC_H
+ 
+ #include "libpq-fe.h"
+ #include "pqexpbuffer.h"
+ 
+ typedef enum					/* bits returned by set_dump_section */
+ {
+ 	DUMP_PRE_DATA = 0x01,
+ 	DUMP_DATA = 0x02,
+ 	DUMP_POST_DATA = 0x04,
+ 	DUMP_UNSECTIONED = 0xff
+ } DumpSections;
+ 
+ typedef void (*on_exit_nicely_callback) (int code, void *arg);
+ 
+ extern const char *progname;
+ extern void (*on_exit_msg_func) (const char *modulename, const char *fmt, va_list ap)
+ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+ 
+ extern void set_dump_section(const char *arg, int *dumpSections);
+ extern void
+ write_msg(const char *modulename, const char *fmt,...)
+ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+ extern void
+ vwrite_msg(const char *modulename, const char *fmt, va_list ap)
+ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+ extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
+ extern void exit_nicely(int code) __attribute__((noreturn));
+ 
+ extern void init_parallel_dump_utils(void);
+ 
+ #endif   /* PG_DUMP_MISC_H */
*** a/src/bin/pg_dump/parallel.c
--- b/src/bin/pg_dump/parallel.c
***************
*** 16,24 ****
   *-------------------------------------------------------------------------
   */
  
! #include "pg_backup_db.h"
  
! #include "dumputils.h"
  #include "parallel.h"
  
  #ifndef WIN32
--- 16,24 ----
   *-------------------------------------------------------------------------
   */
  
! #include "postgres_fe.h"
  
! #include "misc.h"
  #include "parallel.h"
  
  #ifndef WIN32
***************
*** 78,87 **** static const char *modulename = gettext_noop("parallel archiver");
  
  static ParallelSlot *GetMyPSlot(ParallelState *pstate);
  static void
- parallel_exit_msg_func(const char *modulename,
- 					   const char *fmt, va_list ap)
- __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
- static void
  parallel_msg_master(ParallelSlot *slot, const char *modulename,
  					const char *fmt, va_list ap)
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
--- 78,83 ----
***************
*** 112,117 **** static char *readMessageFromPipe(int fd);
--- 108,120 ----
  #define messageEquals(msg, pattern) \
  	(strcmp(msg, pattern) == 0)
  
+ #ifdef WIN32
+ static void shutdown_parallel_dump_utils(int code, void *unused);
+ bool parallel_init_done = false;
+ static DWORD tls_index;
+ DWORD mainThreadId;
+ #endif
+ 
  static ParallelSlot *
  GetMyPSlot(ParallelState *pstate)
  {
***************
*** 128,157 **** GetMyPSlot(ParallelState *pstate)
  	return NULL;
  }
  
  /*
!  * This is the function that will be called from exit_horribly() to print the
!  * error message. If the worker process does exit_horribly(), we forward its
   * last words to the master process. The master process then does
   * exit_horribly() with this error message itself and prints it normally.
   * After printing the message, exit_horribly() on the master will shut down
   * the remaining worker processes.
   */
! static void
! parallel_exit_msg_func(const char *modulename, const char *fmt, va_list ap)
  {
  	ParallelState *pstate = shutdown_info.pstate;
  	ParallelSlot *slot;
  
! 	Assert(pstate);
  
! 	slot = GetMyPSlot(pstate);
! 
! 	if (!slot)
! 		/* We're the parent, just write the message out */
  		vwrite_msg(modulename, fmt, ap);
  	else
! 		/* If we're a worker process, send the msg to the master process */
! 		parallel_msg_master(slot, modulename, fmt, ap);
  }
  
  /* Sends the error message from the worker to the master process */
--- 131,176 ----
  	return NULL;
  }
  
+ 
  /*
!  * Fail and die, with a message to stderr.	Parameters as for write_msg.
!  *
!  * This is defined in parallel.c, because in parallel mode, things are more
!  * complicated. If the worker process does exit_horribly(), we forward its
   * last words to the master process. The master process then does
   * exit_horribly() with this error message itself and prints it normally.
   * After printing the message, exit_horribly() on the master will shut down
   * the remaining worker processes.
   */
! void
! exit_horribly(const char *modulename, const char *fmt,...)
  {
+ 	va_list		ap;
  	ParallelState *pstate = shutdown_info.pstate;
  	ParallelSlot *slot;
  
! 	va_start(ap, fmt);
  
! 	if (pstate == NULL)
! 	{
! 		/* Not in parallel mode, just write to stderr */
  		vwrite_msg(modulename, fmt, ap);
+ 	}
  	else
! 	{
! 		slot = GetMyPSlot(pstate);
! 
! 		if (!slot)
! 			/* We're the parent, just write the message out */
! 			vwrite_msg(modulename, fmt, ap);
! 		else
! 			/* If we're a worker process, send the msg to the master process */
! 			parallel_msg_master(slot, modulename, fmt, ap);
! 	}
! 
! 	va_end(ap);
! 
! 	exit_nicely(1);
  }
  
  /* Sends the error message from the worker to the master process */
***************
*** 172,177 **** parallel_msg_master(ParallelSlot *slot, const char *modulename,
--- 191,277 ----
  	sendMessageToMaster(pipefd, buf);
  }
  
+ #ifdef WIN32
+ static void
+ shutdown_parallel_dump_utils(int code, void *unused)
+ {
+ 	/* Call the cleanup function only from the main thread */
+ 	if (mainThreadId == GetCurrentThreadId())
+ 		WSACleanup();
+ }
+ #endif
+ 
+ void
+ init_parallel_dump_utils(void)
+ {
+ #ifdef WIN32
+ 	if (!parallel_init_done)
+ 	{
+ 		WSADATA		wsaData;
+ 		int			err;
+ 
+ 		tls_index = TlsAlloc();
+ 		mainThreadId = GetCurrentThreadId();
+ 		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
+ 		if (err != 0)
+ 		{
+ 			fprintf(stderr, _("WSAStartup failed: %d\n"), err);
+ 			exit_nicely(1);
+ 		}
+ 		on_exit_nicely(shutdown_parallel_dump_utils, NULL);
+ 		parallel_init_done = true;
+ 	}
+ #endif
+ }
+ 
+ /*
+  * A thread-local version of getLocalPQExpBuffer().
+  *
+  * Non-reentrant but reduces memory leakage. (On Windows the memory leakage
+  * will be one buffer per thread, which is at least better than one per call).
+  */
+ static PQExpBuffer
+ getThreadLocalPQExpBuffer(void)
+ {
+ 	/*
+ 	 * The Tls code goes awry if we use a static var, so we provide for both
+ 	 * static and auto, and omit any use of the static var when using Tls.
+ 	 */
+ 	static PQExpBuffer s_id_return = NULL;
+ 	PQExpBuffer id_return;
+ 
+ #ifdef WIN32
+ 	if (parallel_init_done)
+ 		id_return = (PQExpBuffer) TlsGetValue(tls_index);		/* 0 when not set */
+ 	else
+ 		id_return = s_id_return;
+ #else
+ 	id_return = s_id_return;
+ #endif
+ 
+ 	if (id_return)				/* first time through? */
+ 	{
+ 		/* same buffer, just wipe contents */
+ 		resetPQExpBuffer(id_return);
+ 	}
+ 	else
+ 	{
+ 		/* new buffer */
+ 		id_return = createPQExpBuffer();
+ #ifdef WIN32
+ 		if (parallel_init_done)
+ 			TlsSetValue(tls_index, id_return);
+ 		else
+ 			s_id_return = id_return;
+ #else
+ 		s_id_return = id_return;
+ #endif
+ 
+ 	}
+ 
+ 	return id_return;
+ }
+ 
  /*
   * pg_dump and pg_restore register the Archive pointer for the exit handler
   * (called from exit_horribly). This function mainly exists so that we can
***************
*** 408,414 **** ParallelBackupStart(ArchiveHandle *AH, RestoreOptions *ropt)
  	 * set and falls back to AHX otherwise.
  	 */
  	shutdown_info.pstate = pstate;
! 	on_exit_msg_func = parallel_exit_msg_func;
  
  #ifdef WIN32
  	tMasterThreadId = GetCurrentThreadId();
--- 508,514 ----
  	 * set and falls back to AHX otherwise.
  	 */
  	shutdown_info.pstate = pstate;
! 	getLocalPQExpBuffer = getThreadLocalPQExpBuffer;
  
  #ifdef WIN32
  	tMasterThreadId = GetCurrentThreadId();
*** a/src/bin/pg_dump/parallel.h
--- b/src/bin/pg_dump/parallel.h
***************
*** 16,21 ****
--- 16,24 ----
   *-------------------------------------------------------------------------
   */
  
+ #ifndef PG_DUMP_PARALLEL_H
+ #define PG_DUMP_PARALLEL_H
+ 
  #include "pg_backup_db.h"
  
  struct _archiveHandle;
***************
*** 62,67 **** typedef struct ParallelState
--- 65,75 ----
  	ParallelSlot *parallelSlot;
  } ParallelState;
  
+ #ifdef WIN32
+ extern bool parallel_init_done;
+ extern DWORD mainThreadId;
+ #endif
+ 
  extern int	GetIdleWorker(ParallelState *pstate);
  extern bool IsEveryWorkerIdle(ParallelState *pstate);
  extern void ListenToWorkers(struct _archiveHandle * AH, ParallelState *pstate, bool do_wait);
***************
*** 77,79 **** extern void DispatchJobForTocEntry(struct _archiveHandle * AH,
--- 85,93 ----
  extern void ParallelBackupEnd(struct _archiveHandle * AH, ParallelState *pstate);
  
  extern void checkAborting(struct _archiveHandle * AH);
+ 
+ extern void
+ exit_horribly(const char *modulename, const char *fmt,...)
+ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
+ 
+ #endif   /* PG_DUMP_PARALLEL_H */
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
***************
*** 21,27 ****
   */
  
  #include "pg_backup_db.h"
! #include "dumputils.h"
  #include "parallel.h"
  
  #include <ctype.h>
--- 21,27 ----
   */
  
  #include "pg_backup_db.h"
! #include "misc.h"
  #include "parallel.h"
  
  #include <ctype.h>
*** a/src/bin/pg_dump/pg_backup_custom.c
--- b/src/bin/pg_dump/pg_backup_custom.c
***************
*** 25,31 ****
   */
  
  #include "compress_io.h"
! #include "dumputils.h"
  #include "parallel.h"
  
  /*--------
--- 25,31 ----
   */
  
  #include "compress_io.h"
! #include "misc.h"
  #include "parallel.h"
  
  /*--------
*** a/src/bin/pg_dump/pg_backup_db.c
--- b/src/bin/pg_dump/pg_backup_db.c
***************
*** 12,17 ****
--- 12,19 ----
  
  #include "pg_backup_db.h"
  #include "dumputils.h"
+ #include "misc.h"
+ #include "parallel.h"
  
  #include <unistd.h>
  #include <ctype.h>
*** a/src/bin/pg_dump/pg_backup_directory.c
--- b/src/bin/pg_dump/pg_backup_directory.c
***************
*** 34,40 ****
   */
  
  #include "compress_io.h"
! #include "dumputils.h"
  #include "parallel.h"
  
  #include <dirent.h>
--- 34,40 ----
   */
  
  #include "compress_io.h"
! #include "misc.h"
  #include "parallel.h"
  
  #include <dirent.h>
*** a/src/bin/pg_dump/pg_backup_null.c
--- b/src/bin/pg_dump/pg_backup_null.c
***************
*** 23,29 ****
   */
  
  #include "pg_backup_archiver.h"
! #include "dumputils.h"
  
  #include <unistd.h>				/* for dup */
  
--- 23,30 ----
   */
  
  #include "pg_backup_archiver.h"
! #include "misc.h"
! #include "parallel.h"
  
  #include <unistd.h>				/* for dup */
  
*** a/src/bin/pg_dump/pg_backup_tar.c
--- b/src/bin/pg_dump/pg_backup_tar.c
***************
*** 31,37 ****
  #include "pg_backup.h"
  #include "pg_backup_archiver.h"
  #include "pg_backup_tar.h"
! #include "dumputils.h"
  #include "pgtar.h"
  
  #include <sys/stat.h>
--- 31,38 ----
  #include "pg_backup.h"
  #include "pg_backup_archiver.h"
  #include "pg_backup_tar.h"
! #include "misc.h"
! #include "parallel.h"
  #include "pgtar.h"
  
  #include <sys/stat.h>
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
***************
*** 60,65 ****
--- 60,67 ----
  #include "pg_backup_archiver.h"
  #include "pg_backup_db.h"
  #include "dumputils.h"
+ #include "misc.h"
+ #include "parallel.h"
  
  extern char *optarg;
  extern int	optind,
*** a/src/bin/pg_dump/pg_dump_sort.c
--- b/src/bin/pg_dump/pg_dump_sort.c
***************
*** 14,20 ****
   *-------------------------------------------------------------------------
   */
  #include "pg_backup_archiver.h"
! #include "dumputils.h"
  
  /* translator: this is a module name */
  static const char *modulename = gettext_noop("sorter");
--- 14,21 ----
   *-------------------------------------------------------------------------
   */
  #include "pg_backup_archiver.h"
! #include "misc.h"
! #include "parallel.h"
  
  /* translator: this is a module name */
  static const char *modulename = gettext_noop("sorter");
*** a/src/bin/pg_dump/pg_dumpall.c
--- b/src/bin/pg_dump/pg_dumpall.c
***************
*** 63,68 **** static PGresult *executeQuery(PGconn *conn, const char *query);
--- 63,69 ----
  static void executeCommand(PGconn *conn, const char *query);
  
  static char pg_dump_bin[MAXPGPATH];
+ static const char *progname;
  static PQExpBuffer pgdumpopts;
  static char *connstr = "";
  static bool skip_acls = false;
***************
*** 82,87 **** static int	server_version;
--- 83,89 ----
  static FILE *OPF;
  static char *filename = NULL;
  
+ #define exit_nicely(code) exit(code)
  
  int
  main(int argc, char *argv[])
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
***************
*** 42,47 ****
--- 42,48 ----
  #include "pg_backup_archiver.h"
  
  #include "dumputils.h"
+ #include "misc.h"
  
  #include <ctype.h>
  
#7Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Heikki Linnakangas (#6)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Heikki Linnakangas wrote:

This is what I came up with. I created a new file, misc.c (for lack
of a better name), for things that are shared by pg_dump and
pg_restore, but not pg_dumpall or other programs. I moved all the
parallel stuff from dumputils.c to parallel.c, and everything else
that's not used outside pg_dump and pg_restore to misc.c. I moved
exit_horribly() to parallel.c, because it needs to do things
differently in parallel mode.

Not happy with misc.c as a filename. How about pg_dump_utils.c or
pg_dump_misc.c? I think the comment at the top should explicitely say
that the file is intended not to be linked in pg_dumpall.

--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Kevin Grittner
kgrittn@ymail.com
In reply to: Alvaro Herrera (#7)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

Not happy with misc.c as a filename.

We already have two misc.c files:

src/backend/utils/adt/misc.c
src/interfaces/ecpg/ecpglib/misc.c

I much prefer not to repeat the same filename in different
directories if we can avoid it.

How about pg_dump_utils.c or pg_dump_misc.c?

Those seem reasonable to me.

--
Kevin Grittner
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Andres Freund
andres@2ndquadrant.com
In reply to: Kevin Grittner (#8)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

On 2013-03-26 13:14:53 -0700, Kevin Grittner wrote:

Alvaro Herrera <alvherre@2ndquadrant.com> wrote:

Not happy with misc.c as a filename.

We already have two misc.c files:

src/backend/utils/adt/misc.c
src/interfaces/ecpg/ecpglib/misc.c

I much prefer not to repeat the same filename in different
directories if we can avoid it.

How about pg_dump_utils.c or pg_dump_misc.c?

Those seem reasonable to me.

I vote against including pg_ in the filename, for an implementation
private file that seems duplicative.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Kevin Grittner (#8)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

On 26.03.2013 22:14, Kevin Grittner wrote:

Alvaro Herrera<alvherre@2ndquadrant.com> wrote:

Not happy with misc.c as a filename.

We already have two misc.c files:

src/backend/utils/adt/misc.c
src/interfaces/ecpg/ecpglib/misc.c

I much prefer not to repeat the same filename in different
directories if we can avoid it.

How about pg_dump_utils.c or pg_dump_misc.c?

Those seem reasonable to me.

pg_dump_utils.c could be confused with dumputils.c. And I'd rather not
have pg_dump in the filename, because the file is for functions that are
used in both pg_dump and pg_restore. To add to the confusion, there's
also common.c, which is only used by pg_dump (historical reasons).

There's a bunch of files called pg_backup_*.c that are also shared
between pg_dump and pg_restore, so perhaps pg_backup_utils.c?

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#10)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

Heikki Linnakangas <hlinnakangas@vmware.com> writes:

Alvaro Herrera<alvherre@2ndquadrant.com> wrote:

Not happy with misc.c as a filename.

There's a bunch of files called pg_backup_*.c that are also shared
between pg_dump and pg_restore, so perhaps pg_backup_utils.c?

Works for me. There's inherently not going to be a lot of content
in this filename, so we aren't going to get anything particularly
memorable (though I agree with the duplicativeness argument against
"misc.c").

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Tom Lane (#11)
Re: [COMMITTERS] pgsql: Add PF_PRINTF_ATTRIBUTE to on_exit_msg_fmt.

On 27.03.2013 15:28, Tom Lane wrote:

Heikki Linnakangas<hlinnakangas@vmware.com> writes:

Alvaro Herrera<alvherre@2ndquadrant.com> wrote:

Not happy with misc.c as a filename.

There's a bunch of files called pg_backup_*.c that are also shared
between pg_dump and pg_restore, so perhaps pg_backup_utils.c?

Works for me.

Ok, sold.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers