PostgreSQL Source Code  git master
pg_backup_utils.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_backup_utils.c
4  * Utility routines shared by pg_dump and pg_restore
5  *
6  *
7  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/bin/pg_dump/pg_backup_utils.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres_fe.h"
15 
16 #include "parallel.h"
17 #include "pg_backup_utils.h"
18 
19 /* Globals exported by this file */
20 const char *progname = NULL;
21 
22 #define MAX_ON_EXIT_NICELY 20
23 
24 static struct
25 {
27  void *arg;
29 
31 
32 /*
33  * Parse a --section=foo command line argument.
34  *
35  * Set or update the bitmask in *dumpSections according to arg.
36  * dumpSections is initialised as DUMP_UNSECTIONED by pg_dump and
37  * pg_restore so they can know if this has even been called.
38  */
39 void
40 set_dump_section(const char *arg, int *dumpSections)
41 {
42  /* if this is the first call, clear all the bits */
43  if (*dumpSections == DUMP_UNSECTIONED)
44  *dumpSections = 0;
45 
46  if (strcmp(arg, "pre-data") == 0)
47  *dumpSections |= DUMP_PRE_DATA;
48  else if (strcmp(arg, "data") == 0)
49  *dumpSections |= DUMP_DATA;
50  else if (strcmp(arg, "post-data") == 0)
51  *dumpSections |= DUMP_POST_DATA;
52  else
53  {
54  pg_log_error("unrecognized section name: \"%s\"", arg);
55  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
56  exit_nicely(1);
57  }
58 }
59 
60 
61 /* Register a callback to be run when exit_nicely is invoked. */
62 void
64 {
66  pg_fatal("out of on_exit_nicely slots");
67  on_exit_nicely_list[on_exit_nicely_index].function = function;
70 }
71 
72 /*
73  * Run accumulated on_exit_nicely callbacks in reverse order and then exit
74  * without printing any message.
75  *
76  * If running in a parallel worker thread on Windows, we only exit the thread,
77  * not the whole process.
78  *
79  * Note that in parallel operation on Windows, the callback(s) will be run
80  * by each thread since the list state is necessarily shared by all threads;
81  * each callback must contain logic to ensure it does only what's appropriate
82  * for its thread. On Unix, callbacks are also run by each process, but only
83  * for callbacks established before we fork off the child processes. (It'd
84  * be cleaner to reset the list after fork(), and let each child establish
85  * its own callbacks; but then the behavior would be completely inconsistent
86  * between Windows and Unix. For now, just be sure to establish callbacks
87  * before forking to avoid inconsistency.)
88  */
89 void
90 exit_nicely(int code)
91 {
92  int i;
93 
94  for (i = on_exit_nicely_index - 1; i >= 0; i--)
95  on_exit_nicely_list[i].function(code,
97 
98 #ifdef WIN32
99  if (parallel_init_done && GetCurrentThreadId() != mainThreadId)
100  _endthreadex(code);
101 #endif
102 
103  exit(code);
104 }
int i
Definition: isn.c:73
exit(1)
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_hint(...)
Definition: logging.h:112
static int on_exit_nicely_index
void exit_nicely(int code)
static struct @33 on_exit_nicely_list[MAX_ON_EXIT_NICELY]
#define MAX_ON_EXIT_NICELY
void set_dump_section(const char *arg, int *dumpSections)
void * arg
void on_exit_nicely(on_exit_nicely_callback function, void *arg)
const char * progname
#define DUMP_PRE_DATA
void(* on_exit_nicely_callback)(int code, void *arg)
#define DUMP_DATA
#define DUMP_UNSECTIONED
#define pg_fatal(...)
#define DUMP_POST_DATA