aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_dump/dumputils.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-03-27 18:10:40 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-03-27 18:10:40 +0200
commit7800a71291690dcc34eb3b7aab18750b5a7ebe2c (patch)
treece2832159c7f6486c12faff5191b114339ee8065 /src/bin/pg_dump/dumputils.c
parent1cea9bbb21e9e90dc7085ce605d9160e7161fa58 (diff)
downloadpostgresql-7800a71291690dcc34eb3b7aab18750b5a7ebe2c.tar.gz
postgresql-7800a71291690dcc34eb3b7aab18750b5a7ebe2c.zip
Move some pg_dump function around.
Move functions used only by pg_dump and pg_restore from dumputils.c to a new file, pg_backup_utils.c. dumputils.c is linked into psql and some programs in bin/scripts, so it seems good to keep it slim. The parallel functionality is moved to parallel.c, as is exit_horribly, because the interesting code in exit_horribly is parallel-related. This refactoring gets rid of the on_exit_msg_func function pointer. It was problematic, because a modern gcc version with -Wmissing-format-attribute complained if it wasn't marked with PF_PRINTF_ATTRIBUTE, but the ancient gcc version that Tom Lane's old HP-UX box has didn't accept that attribute on a function pointer, and gave an error. We still use a similar function pointer trick for getLocalPQBuffer() function, to use a thread-local version of that in parallel mode on Windows, but that dodges the problem because it doesn't take printf-like arguments.
Diffstat (limited to 'src/bin/pg_dump/dumputils.c')
-rw-r--r--src/bin/pg_dump/dumputils.c208
1 files changed, 14 insertions, 194 deletions
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 31e56ef7fb5..9c55147c816 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -25,21 +25,6 @@
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,
@@ -49,68 +34,24 @@ 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 PQExpBuffer defaultGetLocalPQExpBuffer(void);
-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
-}
+/* Globals exported by this file */
+int quote_all_identifiers = 0;
+PQExpBuffer (*getLocalPQExpBuffer) (void) = defaultGetLocalPQExpBuffer;
/*
- * 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).
+ * 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
-getThreadLocalPQExpBuffer(void)
+defaultGetLocalPQExpBuffer(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
+ static PQExpBuffer id_return = NULL;
if (id_return) /* first time through? */
{
@@ -121,15 +62,6 @@ 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;
@@ -144,7 +76,7 @@ getThreadLocalPQExpBuffer(void)
const char *
fmtId(const char *rawid)
{
- PQExpBuffer id_return = getThreadLocalPQExpBuffer();
+ PQExpBuffer id_return = getLocalPQExpBuffer();
const char *cp;
bool need_quotes = false;
@@ -238,7 +170,7 @@ fmtQualifiedId(int remoteVersion, const char *schema, const char *id)
}
appendPQExpBuffer(lcl_pqexp, "%s", fmtId(id));
- id_return = getThreadLocalPQExpBuffer();
+ id_return = getLocalPQExpBuffer();
appendPQExpBuffer(id_return, "%s", lcl_pqexp->data);
destroyPQExpBuffer(lcl_pqexp);
@@ -1278,118 +1210,6 @@ 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)
{