Commit a4205fa0 authored by Peter Eisentraut's avatar Peter Eisentraut

pg_basebackup: Use atexit()

Instead of using our custom disconnect_and_exit(), just register the
desired cleanup using atexit() and use the standard exit() to leave
the program.
Reviewed-by: default avatarAlvaro Herrera <alvherre@2ndquadrant.com>
Reviewed-by: default avatarMichael Paquier <michael@paquier.xyz>
Discussion: https://www.postgresql.org/message-id/flat/ec4135ba-84e9-28bf-b584-0e78d47448d5@2ndquadrant.com/
parent afb0d071
...@@ -136,7 +136,6 @@ static PQExpBuffer recoveryconfcontents = NULL; ...@@ -136,7 +136,6 @@ static PQExpBuffer recoveryconfcontents = NULL;
/* Function headers */ /* Function headers */
static void usage(void); static void usage(void);
static void disconnect_and_exit(int code) pg_attribute_noreturn();
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found); static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
static void progress_report(int tablespacenum, const char *filename, bool force); static void progress_report(int tablespacenum, const char *filename, bool force);
...@@ -217,25 +216,25 @@ cleanup_directories_atexit(void) ...@@ -217,25 +216,25 @@ cleanup_directories_atexit(void)
} }
static void static void
disconnect_and_exit(int code) disconnect_atexit(void)
{ {
if (conn != NULL) if (conn != NULL)
PQfinish(conn); PQfinish(conn);
}
#ifndef WIN32 #ifndef WIN32
/*
/* * On windows, our background thread dies along with the process. But on
* On windows, our background thread dies along with the process. But on * Unix, if we have started a subprocess, we want to kill it off so it
* Unix, if we have started a subprocess, we want to kill it off so it * doesn't remain running trying to stream data.
* doesn't remain running trying to stream data. */
*/ static void
kill_bgchild_atexit(void)
{
if (bgchild > 0) if (bgchild > 0)
kill(bgchild, SIGTERM); kill(bgchild, SIGTERM);
#endif
exit(code);
} }
#endif
/* /*
* Split argument into old_dir and new_dir and append to tablespace mapping * Split argument into old_dir and new_dir and append to tablespace mapping
...@@ -562,7 +561,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) ...@@ -562,7 +561,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
fprintf(stderr, fprintf(stderr,
_("%s: could not parse write-ahead log location \"%s\"\n"), _("%s: could not parse write-ahead log location \"%s\"\n"),
progname, startpos); progname, startpos);
disconnect_and_exit(1); exit(1);
} }
param->startptr = ((uint64) hi) << 32 | lo; param->startptr = ((uint64) hi) << 32 | lo;
/* Round off to even segment position */ /* Round off to even segment position */
...@@ -575,7 +574,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) ...@@ -575,7 +574,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
fprintf(stderr, fprintf(stderr,
_("%s: could not create pipe for background process: %s\n"), _("%s: could not create pipe for background process: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
#endif #endif
...@@ -604,7 +603,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) ...@@ -604,7 +603,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
{ {
if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL, if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL,
temp_replication_slot, true, true, false)) temp_replication_slot, true, true, false))
disconnect_and_exit(1); exit(1);
if (verbose) if (verbose)
{ {
...@@ -635,7 +634,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) ...@@ -635,7 +634,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
fprintf(stderr, fprintf(stderr,
_("%s: could not create directory \"%s\": %s\n"), _("%s: could not create directory \"%s\": %s\n"),
progname, statusdir, strerror(errno)); progname, statusdir, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
...@@ -654,19 +653,20 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) ...@@ -654,19 +653,20 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
{ {
fprintf(stderr, _("%s: could not create background process: %s\n"), fprintf(stderr, _("%s: could not create background process: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
/* /*
* Else we are in the parent process and all is well. * Else we are in the parent process and all is well.
*/ */
atexit(kill_bgchild_atexit);
#else /* WIN32 */ #else /* WIN32 */
bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL); bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
if (bgchild == 0) if (bgchild == 0)
{ {
fprintf(stderr, _("%s: could not create background thread: %s\n"), fprintf(stderr, _("%s: could not create background thread: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
#endif #endif
} }
...@@ -691,7 +691,7 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found) ...@@ -691,7 +691,7 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
fprintf(stderr, fprintf(stderr,
_("%s: could not create directory \"%s\": %s\n"), _("%s: could not create directory \"%s\": %s\n"),
progname, dirname, strerror(errno)); progname, dirname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (created) if (created)
*created = true; *created = true;
...@@ -714,7 +714,7 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found) ...@@ -714,7 +714,7 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
fprintf(stderr, fprintf(stderr,
_("%s: directory \"%s\" exists but is not empty\n"), _("%s: directory \"%s\" exists but is not empty\n"),
progname, dirname); progname, dirname);
disconnect_and_exit(1); exit(1);
case -1: case -1:
/* /*
...@@ -722,7 +722,7 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found) ...@@ -722,7 +722,7 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
*/ */
fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"),
progname, dirname, strerror(errno)); progname, dirname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
...@@ -933,7 +933,7 @@ writeTarData( ...@@ -933,7 +933,7 @@ writeTarData(
fprintf(stderr, fprintf(stderr,
_("%s: could not write to compressed file \"%s\": %s\n"), _("%s: could not write to compressed file \"%s\": %s\n"),
progname, current_file, get_gz_error(ztarfile)); progname, current_file, get_gz_error(ztarfile));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -943,7 +943,7 @@ writeTarData( ...@@ -943,7 +943,7 @@ writeTarData(
{ {
fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
progname, current_file, strerror(errno)); progname, current_file, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
} }
...@@ -1005,7 +1005,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1005,7 +1005,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not set compression level %d: %s\n"), _("%s: could not set compression level %d: %s\n"),
progname, compresslevel, get_gz_error(ztarfile)); progname, compresslevel, get_gz_error(ztarfile));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -1026,7 +1026,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1026,7 +1026,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not set compression level %d: %s\n"), _("%s: could not set compression level %d: %s\n"),
progname, compresslevel, get_gz_error(ztarfile)); progname, compresslevel, get_gz_error(ztarfile));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -1054,7 +1054,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1054,7 +1054,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not set compression level %d: %s\n"), _("%s: could not set compression level %d: %s\n"),
progname, compresslevel, get_gz_error(ztarfile)); progname, compresslevel, get_gz_error(ztarfile));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -1075,7 +1075,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1075,7 +1075,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not create compressed file \"%s\": %s\n"), _("%s: could not create compressed file \"%s\": %s\n"),
progname, filename, get_gz_error(ztarfile)); progname, filename, get_gz_error(ztarfile));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -1086,7 +1086,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1086,7 +1086,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), fprintf(stderr, _("%s: could not create file \"%s\": %s\n"),
progname, filename, strerror(errno)); progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
...@@ -1098,7 +1098,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1098,7 +1098,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not get COPY data stream: %s"), fprintf(stderr, _("%s: could not get COPY data stream: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
while (1) while (1)
...@@ -1167,7 +1167,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1167,7 +1167,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not close compressed file \"%s\": %s\n"), _("%s: could not close compressed file \"%s\": %s\n"),
progname, filename, get_gz_error(ztarfile)); progname, filename, get_gz_error(ztarfile));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -1180,7 +1180,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1180,7 +1180,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not close file \"%s\": %s\n"), _("%s: could not close file \"%s\": %s\n"),
progname, filename, strerror(errno)); progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
} }
...@@ -1191,7 +1191,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1191,7 +1191,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not read COPY data: %s"), fprintf(stderr, _("%s: could not read COPY data: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
if (!writerecoveryconf || !basetablespace) if (!writerecoveryconf || !basetablespace)
...@@ -1427,7 +1427,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1427,7 +1427,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not get COPY data stream: %s"), fprintf(stderr, _("%s: could not get COPY data stream: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
while (1) while (1)
...@@ -1456,7 +1456,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1456,7 +1456,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not read COPY data: %s"), fprintf(stderr, _("%s: could not read COPY data: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
if (file == NULL) if (file == NULL)
...@@ -1470,7 +1470,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1470,7 +1470,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: invalid tar block header size: %d\n"), fprintf(stderr, _("%s: invalid tar block header size: %d\n"),
progname, r); progname, r);
disconnect_and_exit(1); exit(1);
} }
totaldone += 512; totaldone += 512;
...@@ -1520,7 +1520,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1520,7 +1520,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: could not create directory \"%s\": %s\n"), _("%s: could not create directory \"%s\": %s\n"),
progname, filename, strerror(errno)); progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
#ifndef WIN32 #ifndef WIN32
...@@ -1553,7 +1553,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1553,7 +1553,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
_("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"), _("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"),
progname, filename, mapped_tblspc_path, progname, filename, mapped_tblspc_path,
strerror(errno)); strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
else else
...@@ -1561,7 +1561,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1561,7 +1561,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: unrecognized link indicator \"%c\"\n"), _("%s: unrecognized link indicator \"%c\"\n"),
progname, copybuf[156]); progname, copybuf[156]);
disconnect_and_exit(1); exit(1);
} }
continue; /* directory or link handled */ continue; /* directory or link handled */
} }
...@@ -1574,7 +1574,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1574,7 +1574,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), fprintf(stderr, _("%s: could not create file \"%s\": %s\n"),
progname, filename, strerror(errno)); progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
#ifndef WIN32 #ifndef WIN32
...@@ -1614,7 +1614,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1614,7 +1614,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
{ {
fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"),
progname, filename, strerror(errno)); progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
totaldone += r; totaldone += r;
progress_report(rownum, filename, false); progress_report(rownum, filename, false);
...@@ -1640,7 +1640,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) ...@@ -1640,7 +1640,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
fprintf(stderr, fprintf(stderr,
_("%s: COPY stream ended before last file was finished\n"), _("%s: COPY stream ended before last file was finished\n"),
progname); progname);
disconnect_and_exit(1); exit(1);
} }
if (copybuf != NULL) if (copybuf != NULL)
...@@ -1687,14 +1687,14 @@ GenerateRecoveryConf(PGconn *conn) ...@@ -1687,14 +1687,14 @@ GenerateRecoveryConf(PGconn *conn)
if (!recoveryconfcontents) if (!recoveryconfcontents)
{ {
fprintf(stderr, _("%s: out of memory\n"), progname); fprintf(stderr, _("%s: out of memory\n"), progname);
disconnect_and_exit(1); exit(1);
} }
connOptions = PQconninfo(conn); connOptions = PQconninfo(conn);
if (connOptions == NULL) if (connOptions == NULL)
{ {
fprintf(stderr, _("%s: out of memory\n"), progname); fprintf(stderr, _("%s: out of memory\n"), progname);
disconnect_and_exit(1); exit(1);
} }
initPQExpBuffer(&conninfo_buf); initPQExpBuffer(&conninfo_buf);
...@@ -1745,7 +1745,7 @@ GenerateRecoveryConf(PGconn *conn) ...@@ -1745,7 +1745,7 @@ GenerateRecoveryConf(PGconn *conn)
PQExpBufferDataBroken(conninfo_buf)) PQExpBufferDataBroken(conninfo_buf))
{ {
fprintf(stderr, _("%s: out of memory\n"), progname); fprintf(stderr, _("%s: out of memory\n"), progname);
disconnect_and_exit(1); exit(1);
} }
termPQExpBuffer(&conninfo_buf); termPQExpBuffer(&conninfo_buf);
...@@ -1771,7 +1771,7 @@ WriteRecoveryConf(void) ...@@ -1771,7 +1771,7 @@ WriteRecoveryConf(void)
if (cf == NULL) if (cf == NULL)
{ {
fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, filename, strerror(errno)); fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1) if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1)
...@@ -1779,7 +1779,7 @@ WriteRecoveryConf(void) ...@@ -1779,7 +1779,7 @@ WriteRecoveryConf(void)
fprintf(stderr, fprintf(stderr,
_("%s: could not write to file \"%s\": %s\n"), _("%s: could not write to file \"%s\": %s\n"),
progname, filename, strerror(errno)); progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
fclose(cf); fclose(cf);
...@@ -1789,7 +1789,7 @@ WriteRecoveryConf(void) ...@@ -1789,7 +1789,7 @@ WriteRecoveryConf(void)
if (cf == NULL) if (cf == NULL)
{ {
fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
fclose(cf); fclose(cf);
...@@ -1830,7 +1830,7 @@ BaseBackup(void) ...@@ -1830,7 +1830,7 @@ BaseBackup(void)
fprintf(stderr, _("%s: incompatible server version %s\n"), fprintf(stderr, _("%s: incompatible server version %s\n"),
progname, serverver ? serverver : "'unknown'"); progname, serverver ? serverver : "'unknown'");
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -1844,7 +1844,7 @@ BaseBackup(void) ...@@ -1844,7 +1844,7 @@ BaseBackup(void)
* but add a hint about using -X none. * but add a hint about using -X none.
*/ */
fprintf(stderr, _("HINT: use -X none or -X fetch to disable log streaming\n")); fprintf(stderr, _("HINT: use -X none or -X fetch to disable log streaming\n"));
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -1857,7 +1857,7 @@ BaseBackup(void) ...@@ -1857,7 +1857,7 @@ BaseBackup(void)
* Run IDENTIFY_SYSTEM so we can get the timeline * Run IDENTIFY_SYSTEM so we can get the timeline
*/ */
if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL)) if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
disconnect_and_exit(1); exit(1);
/* /*
* Start the actual backup * Start the actual backup
...@@ -1896,7 +1896,7 @@ BaseBackup(void) ...@@ -1896,7 +1896,7 @@ BaseBackup(void)
{ {
fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), fprintf(stderr, _("%s: could not send replication command \"%s\": %s"),
progname, "BASE_BACKUP", PQerrorMessage(conn)); progname, "BASE_BACKUP", PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -1907,14 +1907,14 @@ BaseBackup(void) ...@@ -1907,14 +1907,14 @@ BaseBackup(void)
{ {
fprintf(stderr, _("%s: could not initiate base backup: %s"), fprintf(stderr, _("%s: could not initiate base backup: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
if (PQntuples(res) != 1) if (PQntuples(res) != 1)
{ {
fprintf(stderr, fprintf(stderr,
_("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"), _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"),
progname, PQntuples(res), PQnfields(res), 1, 2); progname, PQntuples(res), PQnfields(res), 1, 2);
disconnect_and_exit(1); exit(1);
} }
strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart)); strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
...@@ -1946,12 +1946,12 @@ BaseBackup(void) ...@@ -1946,12 +1946,12 @@ BaseBackup(void)
{ {
fprintf(stderr, _("%s: could not get backup header: %s"), fprintf(stderr, _("%s: could not get backup header: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
if (PQntuples(res) < 1) if (PQntuples(res) < 1)
{ {
fprintf(stderr, _("%s: no data returned from server\n"), progname); fprintf(stderr, _("%s: no data returned from server\n"), progname);
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -1984,7 +1984,7 @@ BaseBackup(void) ...@@ -1984,7 +1984,7 @@ BaseBackup(void)
fprintf(stderr, fprintf(stderr,
_("%s: can only write single tablespace to stdout, database has %d\n"), _("%s: can only write single tablespace to stdout, database has %d\n"),
progname, PQntuples(res)); progname, PQntuples(res));
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -2028,14 +2028,14 @@ BaseBackup(void) ...@@ -2028,14 +2028,14 @@ BaseBackup(void)
fprintf(stderr, fprintf(stderr,
_("%s: could not get write-ahead log end position from server: %s"), _("%s: could not get write-ahead log end position from server: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
disconnect_and_exit(1); exit(1);
} }
if (PQntuples(res) != 1) if (PQntuples(res) != 1)
{ {
fprintf(stderr, fprintf(stderr,
_("%s: no write-ahead log end position returned from server\n"), _("%s: no write-ahead log end position returned from server\n"),
progname); progname);
disconnect_and_exit(1); exit(1);
} }
strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend)); strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend));
if (verbose && includewal != NO_WAL) if (verbose && includewal != NO_WAL)
...@@ -2059,7 +2059,7 @@ BaseBackup(void) ...@@ -2059,7 +2059,7 @@ BaseBackup(void)
fprintf(stderr, _("%s: final receive failed: %s"), fprintf(stderr, _("%s: final receive failed: %s"),
progname, PQerrorMessage(conn)); progname, PQerrorMessage(conn));
} }
disconnect_and_exit(1); exit(1);
} }
if (bgchild > 0) if (bgchild > 0)
...@@ -2089,7 +2089,7 @@ BaseBackup(void) ...@@ -2089,7 +2089,7 @@ BaseBackup(void)
fprintf(stderr, fprintf(stderr,
_("%s: could not send command to background pipe: %s\n"), _("%s: could not send command to background pipe: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
/* Just wait for the background process to exit */ /* Just wait for the background process to exit */
...@@ -2098,19 +2098,19 @@ BaseBackup(void) ...@@ -2098,19 +2098,19 @@ BaseBackup(void)
{ {
fprintf(stderr, _("%s: could not wait for child process: %s\n"), fprintf(stderr, _("%s: could not wait for child process: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (r != bgchild) if (r != bgchild)
{ {
fprintf(stderr, _("%s: child %d died, expected %d\n"), fprintf(stderr, _("%s: child %d died, expected %d\n"),
progname, (int) r, (int) bgchild); progname, (int) r, (int) bgchild);
disconnect_and_exit(1); exit(1);
} }
if (status != 0) if (status != 0)
{ {
fprintf(stderr, "%s: %s\n", fprintf(stderr, "%s: %s\n",
progname, wait_result_to_str(status)); progname, wait_result_to_str(status));
disconnect_and_exit(1); exit(1);
} }
/* Exited normally, we're happy! */ /* Exited normally, we're happy! */
#else /* WIN32 */ #else /* WIN32 */
...@@ -2125,7 +2125,7 @@ BaseBackup(void) ...@@ -2125,7 +2125,7 @@ BaseBackup(void)
fprintf(stderr, fprintf(stderr,
_("%s: could not parse write-ahead log location \"%s\"\n"), _("%s: could not parse write-ahead log location \"%s\"\n"),
progname, xlogend); progname, xlogend);
disconnect_and_exit(1); exit(1);
} }
xlogendptr = ((uint64) hi) << 32 | lo; xlogendptr = ((uint64) hi) << 32 | lo;
InterlockedIncrement(&has_xlogendptr); InterlockedIncrement(&has_xlogendptr);
...@@ -2137,20 +2137,20 @@ BaseBackup(void) ...@@ -2137,20 +2137,20 @@ BaseBackup(void)
_dosmaperr(GetLastError()); _dosmaperr(GetLastError());
fprintf(stderr, _("%s: could not wait for child thread: %s\n"), fprintf(stderr, _("%s: could not wait for child thread: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0) if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
{ {
_dosmaperr(GetLastError()); _dosmaperr(GetLastError());
fprintf(stderr, _("%s: could not get child thread exit status: %s\n"), fprintf(stderr, _("%s: could not get child thread exit status: %s\n"),
progname, strerror(errno)); progname, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (status != 0) if (status != 0)
{ {
fprintf(stderr, _("%s: child thread exited with error %u\n"), fprintf(stderr, _("%s: child thread exited with error %u\n"),
progname, (unsigned int) status); progname, (unsigned int) status);
disconnect_and_exit(1); exit(1);
} }
/* Exited normally, we're happy */ /* Exited normally, we're happy */
#endif #endif
...@@ -2164,6 +2164,7 @@ BaseBackup(void) ...@@ -2164,6 +2164,7 @@ BaseBackup(void)
*/ */
PQclear(res); PQclear(res);
PQfinish(conn); PQfinish(conn);
conn = NULL;
/* /*
* Make data persistent on disk once backup is completed. For tar format * Make data persistent on disk once backup is completed. For tar format
...@@ -2542,6 +2543,7 @@ main(int argc, char **argv) ...@@ -2542,6 +2543,7 @@ main(int argc, char **argv)
/* Error message already written in GetConnection() */ /* Error message already written in GetConnection() */
exit(1); exit(1);
} }
atexit(disconnect_atexit);
/* /*
* Set umask so that directories/files are created with the same * Set umask so that directories/files are created with the same
...@@ -2563,7 +2565,7 @@ main(int argc, char **argv) ...@@ -2563,7 +2565,7 @@ main(int argc, char **argv)
/* determine remote server's xlog segment size */ /* determine remote server's xlog segment size */
if (!RetrieveWalSegSize(conn)) if (!RetrieveWalSegSize(conn))
disconnect_and_exit(1); exit(1);
/* Create pg_wal symlink, if required */ /* Create pg_wal symlink, if required */
if (xlog_dir) if (xlog_dir)
...@@ -2585,11 +2587,11 @@ main(int argc, char **argv) ...@@ -2585,11 +2587,11 @@ main(int argc, char **argv)
{ {
fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"), fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
progname, linkloc, strerror(errno)); progname, linkloc, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
#else #else
fprintf(stderr, _("%s: symlinks are not supported on this platform\n"), progname); fprintf(stderr, _("%s: symlinks are not supported on this platform\n"), progname);
disconnect_and_exit(1); exit(1);
#endif #endif
free(linkloc); free(linkloc);
} }
......
...@@ -55,11 +55,12 @@ static void StreamLog(void); ...@@ -55,11 +55,12 @@ static void StreamLog(void);
static bool stop_streaming(XLogRecPtr segendpos, uint32 timeline, static bool stop_streaming(XLogRecPtr segendpos, uint32 timeline,
bool segment_finished); bool segment_finished);
#define disconnect_and_exit(code) \ static void
{ \ disconnect_atexit(void)
if (conn != NULL) PQfinish(conn); \ {
exit(code); \ if (conn != NULL)
} PQfinish(conn);
}
/* Routines to evaluate segment file format */ /* Routines to evaluate segment file format */
#define IsCompressXLogFileName(fname) \ #define IsCompressXLogFileName(fname) \
...@@ -168,7 +169,7 @@ get_destination_dir(char *dest_folder) ...@@ -168,7 +169,7 @@ get_destination_dir(char *dest_folder)
{ {
fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
progname, basedir, strerror(errno)); progname, basedir, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
return dir; return dir;
...@@ -186,7 +187,7 @@ close_destination_dir(DIR *dest_dir, char *dest_folder) ...@@ -186,7 +187,7 @@ close_destination_dir(DIR *dest_dir, char *dest_folder)
{ {
fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"), fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
progname, dest_folder, strerror(errno)); progname, dest_folder, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
} }
...@@ -267,7 +268,7 @@ FindStreamingStart(uint32 *tli) ...@@ -267,7 +268,7 @@ FindStreamingStart(uint32 *tli)
{ {
fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"), fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"),
progname, fullpath, strerror(errno)); progname, fullpath, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (statbuf.st_size != WalSegSz) if (statbuf.st_size != WalSegSz)
...@@ -293,13 +294,13 @@ FindStreamingStart(uint32 *tli) ...@@ -293,13 +294,13 @@ FindStreamingStart(uint32 *tli)
{ {
fprintf(stderr, _("%s: could not open compressed file \"%s\": %s\n"), fprintf(stderr, _("%s: could not open compressed file \"%s\": %s\n"),
progname, fullpath, strerror(errno)); progname, fullpath, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
if (lseek(fd, (off_t) (-4), SEEK_END) < 0) if (lseek(fd, (off_t) (-4), SEEK_END) < 0)
{ {
fprintf(stderr, _("%s: could not seek in compressed file \"%s\": %s\n"), fprintf(stderr, _("%s: could not seek in compressed file \"%s\": %s\n"),
progname, fullpath, strerror(errno)); progname, fullpath, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
r = read(fd, (char *) buf, sizeof(buf)); r = read(fd, (char *) buf, sizeof(buf));
if (r != sizeof(buf)) if (r != sizeof(buf))
...@@ -310,7 +311,7 @@ FindStreamingStart(uint32 *tli) ...@@ -310,7 +311,7 @@ FindStreamingStart(uint32 *tli)
else else
fprintf(stderr, _("%s: could not read compressed file \"%s\": read %d of %zu\n"), fprintf(stderr, _("%s: could not read compressed file \"%s\": read %d of %zu\n"),
progname, fullpath, r, sizeof(buf)); progname, fullpath, r, sizeof(buf));
disconnect_and_exit(1); exit(1);
} }
close(fd); close(fd);
...@@ -341,7 +342,7 @@ FindStreamingStart(uint32 *tli) ...@@ -341,7 +342,7 @@ FindStreamingStart(uint32 *tli)
{ {
fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"), fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
progname, basedir, strerror(errno)); progname, basedir, strerror(errno));
disconnect_and_exit(1); exit(1);
} }
close_destination_dir(dir, basedir); close_destination_dir(dir, basedir);
...@@ -395,7 +396,7 @@ StreamLog(void) ...@@ -395,7 +396,7 @@ StreamLog(void)
* There's no hope of recovering from a version mismatch, so don't * There's no hope of recovering from a version mismatch, so don't
* retry. * retry.
*/ */
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -404,7 +405,7 @@ StreamLog(void) ...@@ -404,7 +405,7 @@ StreamLog(void)
* existing output directory. * existing output directory.
*/ */
if (!RunIdentifySystem(conn, NULL, &servertli, &serverpos, NULL)) if (!RunIdentifySystem(conn, NULL, &servertli, &serverpos, NULL))
disconnect_and_exit(1); exit(1);
/* /*
* Figure out where to start streaming. * Figure out where to start streaming.
...@@ -452,6 +453,7 @@ StreamLog(void) ...@@ -452,6 +453,7 @@ StreamLog(void)
} }
PQfinish(conn); PQfinish(conn);
conn = NULL;
FreeWalDirectoryMethod(); FreeWalDirectoryMethod();
pg_free(stream.walmethod); pg_free(stream.walmethod);
...@@ -701,6 +703,7 @@ main(int argc, char **argv) ...@@ -701,6 +703,7 @@ main(int argc, char **argv)
if (!conn) if (!conn)
/* error message already written in GetConnection() */ /* error message already written in GetConnection() */
exit(1); exit(1);
atexit(disconnect_atexit);
/* /*
* Run IDENTIFY_SYSTEM to make sure we've successfully have established a * Run IDENTIFY_SYSTEM to make sure we've successfully have established a
...@@ -708,7 +711,7 @@ main(int argc, char **argv) ...@@ -708,7 +711,7 @@ main(int argc, char **argv)
* connection. * connection.
*/ */
if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name)) if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name))
disconnect_and_exit(1); exit(1);
/* /*
* Set umask so that directories/files are created with the same * Set umask so that directories/files are created with the same
...@@ -722,7 +725,7 @@ main(int argc, char **argv) ...@@ -722,7 +725,7 @@ main(int argc, char **argv)
/* determine remote server's xlog segment size */ /* determine remote server's xlog segment size */
if (!RetrieveWalSegSize(conn)) if (!RetrieveWalSegSize(conn))
disconnect_and_exit(1); exit(1);
/* /*
* Check that there is a database associated with connection, none should * Check that there is a database associated with connection, none should
...@@ -733,7 +736,7 @@ main(int argc, char **argv) ...@@ -733,7 +736,7 @@ main(int argc, char **argv)
fprintf(stderr, fprintf(stderr,
_("%s: replication connection using slot \"%s\" is unexpectedly database specific\n"), _("%s: replication connection using slot \"%s\" is unexpectedly database specific\n"),
progname, replication_slot); progname, replication_slot);
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -747,8 +750,8 @@ main(int argc, char **argv) ...@@ -747,8 +750,8 @@ main(int argc, char **argv)
progname, replication_slot); progname, replication_slot);
if (!DropReplicationSlot(conn, replication_slot)) if (!DropReplicationSlot(conn, replication_slot))
disconnect_and_exit(1); exit(1);
disconnect_and_exit(0); exit(0);
} }
/* Create a replication slot */ /* Create a replication slot */
...@@ -761,8 +764,8 @@ main(int argc, char **argv) ...@@ -761,8 +764,8 @@ main(int argc, char **argv)
if (!CreateReplicationSlot(conn, replication_slot, NULL, false, true, false, if (!CreateReplicationSlot(conn, replication_slot, NULL, false, true, false,
slot_exists_ok)) slot_exists_ok))
disconnect_and_exit(1); exit(1);
disconnect_and_exit(0); exit(0);
} }
/* /*
......
...@@ -65,7 +65,6 @@ static XLogRecPtr output_fsync_lsn = InvalidXLogRecPtr; ...@@ -65,7 +65,6 @@ static XLogRecPtr output_fsync_lsn = InvalidXLogRecPtr;
static void usage(void); static void usage(void);
static void StreamLogicalLog(void); static void StreamLogicalLog(void);
static void disconnect_and_exit(int code) pg_attribute_noreturn();
static bool flushAndSendFeedback(PGconn *conn, TimestampTz *now); static bool flushAndSendFeedback(PGconn *conn, TimestampTz *now);
static void prepareToTerminate(PGconn *conn, XLogRecPtr endpos, static void prepareToTerminate(PGconn *conn, XLogRecPtr endpos,
bool keepalive, XLogRecPtr lsn); bool keepalive, XLogRecPtr lsn);
...@@ -167,12 +166,10 @@ sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested) ...@@ -167,12 +166,10 @@ sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested)
} }
static void static void
disconnect_and_exit(int code) disconnect_atexit(void)
{ {
if (conn != NULL) if (conn != NULL)
PQfinish(conn); PQfinish(conn);
exit(code);
} }
static bool static bool
...@@ -944,20 +941,21 @@ main(int argc, char **argv) ...@@ -944,20 +941,21 @@ main(int argc, char **argv)
if (!conn) if (!conn)
/* Error message already written in GetConnection() */ /* Error message already written in GetConnection() */
exit(1); exit(1);
atexit(disconnect_atexit);
/* /*
* Run IDENTIFY_SYSTEM to make sure we connected using a database specific * Run IDENTIFY_SYSTEM to make sure we connected using a database specific
* replication connection. * replication connection.
*/ */
if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name)) if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name))
disconnect_and_exit(1); exit(1);
if (db_name == NULL) if (db_name == NULL)
{ {
fprintf(stderr, fprintf(stderr,
_("%s: could not establish database-specific replication connection\n"), _("%s: could not establish database-specific replication connection\n"),
progname); progname);
disconnect_and_exit(1); exit(1);
} }
/* /*
...@@ -979,7 +977,7 @@ main(int argc, char **argv) ...@@ -979,7 +977,7 @@ main(int argc, char **argv)
progname, replication_slot); progname, replication_slot);
if (!DropReplicationSlot(conn, replication_slot)) if (!DropReplicationSlot(conn, replication_slot))
disconnect_and_exit(1); exit(1);
} }
/* Create a replication slot. */ /* Create a replication slot. */
...@@ -992,12 +990,12 @@ main(int argc, char **argv) ...@@ -992,12 +990,12 @@ main(int argc, char **argv)
if (!CreateReplicationSlot(conn, replication_slot, plugin, false, if (!CreateReplicationSlot(conn, replication_slot, plugin, false,
false, false, slot_exists_ok)) false, false, slot_exists_ok))
disconnect_and_exit(1); exit(1);
startpos = InvalidXLogRecPtr; startpos = InvalidXLogRecPtr;
} }
if (!do_start_slot) if (!do_start_slot)
disconnect_and_exit(0); exit(0);
/* Stream loop */ /* Stream loop */
while (true) while (true)
...@@ -1009,7 +1007,7 @@ main(int argc, char **argv) ...@@ -1009,7 +1007,7 @@ main(int argc, char **argv)
* We've been Ctrl-C'ed or reached an exit limit condition. That's * We've been Ctrl-C'ed or reached an exit limit condition. That's
* not an error, so exit without an errorcode. * not an error, so exit without an errorcode.
*/ */
disconnect_and_exit(0); exit(0);
} }
else if (noloop) else if (noloop)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment