Header And Logo

PostgreSQL
| The world's most advanced open source database.

pg_backup_utils.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * pg_backup_utils.c
00004  *  Utility routines shared by pg_dump and pg_restore
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * src/bin/pg_dump/pg_backup_utils.c
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #include "postgres_fe.h"
00015 
00016 #include "pg_backup_utils.h"
00017 #include "parallel.h"
00018 
00019 /* Globals exported by this file */
00020 const char *progname = NULL;
00021 
00022 #define MAX_ON_EXIT_NICELY              20
00023 
00024 static struct
00025 {
00026     on_exit_nicely_callback function;
00027     void       *arg;
00028 }   on_exit_nicely_list[MAX_ON_EXIT_NICELY];
00029 
00030 static int  on_exit_nicely_index;
00031 
00032 /*
00033  * Parse a --section=foo command line argument.
00034  *
00035  * Set or update the bitmask in *dumpSections according to arg.
00036  * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
00037  * pg_restore so they can know if this has even been called.
00038  */
00039 void
00040 set_dump_section(const char *arg, int *dumpSections)
00041 {
00042     /* if this is the first call, clear all the bits */
00043     if (*dumpSections == DUMP_UNSECTIONED)
00044         *dumpSections = 0;
00045 
00046     if (strcmp(arg, "pre-data") == 0)
00047         *dumpSections |= DUMP_PRE_DATA;
00048     else if (strcmp(arg, "data") == 0)
00049         *dumpSections |= DUMP_DATA;
00050     else if (strcmp(arg, "post-data") == 0)
00051         *dumpSections |= DUMP_POST_DATA;
00052     else
00053     {
00054         fprintf(stderr, _("%s: unrecognized section name: \"%s\"\n"),
00055                 progname, arg);
00056         fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
00057                 progname);
00058         exit_nicely(1);
00059     }
00060 }
00061 
00062 
00063 /*
00064  * Write a printf-style message to stderr.
00065  *
00066  * The program name is prepended, if "progname" has been set.
00067  * Also, if modulename isn't NULL, that's included too.
00068  * Note that we'll try to translate the modulename and the fmt string.
00069  */
00070 void
00071 write_msg(const char *modulename, const char *fmt,...)
00072 {
00073     va_list     ap;
00074 
00075     va_start(ap, fmt);
00076     vwrite_msg(modulename, fmt, ap);
00077     va_end(ap);
00078 }
00079 
00080 /*
00081  * As write_msg, but pass a va_list not variable arguments.
00082  */
00083 void
00084 vwrite_msg(const char *modulename, const char *fmt, va_list ap)
00085 {
00086     if (progname)
00087     {
00088         if (modulename)
00089             fprintf(stderr, "%s: [%s] ", progname, _(modulename));
00090         else
00091             fprintf(stderr, "%s: ", progname);
00092     }
00093     vfprintf(stderr, _(fmt), ap);
00094 }
00095 
00096 /* Register a callback to be run when exit_nicely is invoked. */
00097 void
00098 on_exit_nicely(on_exit_nicely_callback function, void *arg)
00099 {
00100     if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY)
00101         exit_horribly(NULL, "out of on_exit_nicely slots\n");
00102     on_exit_nicely_list[on_exit_nicely_index].function = function;
00103     on_exit_nicely_list[on_exit_nicely_index].arg = arg;
00104     on_exit_nicely_index++;
00105 }
00106 
00107 /*
00108  * Run accumulated on_exit_nicely callbacks in reverse order and then exit
00109  * quietly.  This needs to be thread-safe.
00110  */
00111 void
00112 exit_nicely(int code)
00113 {
00114     int         i;
00115 
00116     for (i = on_exit_nicely_index - 1; i >= 0; i--)
00117         (*on_exit_nicely_list[i].function) (code,
00118                                             on_exit_nicely_list[i].arg);
00119 
00120 #ifdef WIN32
00121     if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
00122         ExitThread(code);
00123 #endif
00124 
00125     exit(code);
00126 }