pg_basebackup: Use atexit()
authorPeter Eisentraut
Sat, 29 Dec 2018 12:21:47 +0000 (13:21 +0100)
committerPeter Eisentraut
Mon, 7 Jan 2019 15:21:47 +0000 (16:21 +0100)
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: Alvaro Herrera
Reviewed-by: Michael Paquier
Discussion: https://www.postgresql.org/message-id/flat/ec4135ba-84e9-28bf-b584-0e78d47448d5@2ndquadrant.com/

src/bin/pg_basebackup/pg_basebackup.c
src/bin/pg_basebackup/pg_receivewal.c
src/bin/pg_basebackup/pg_recvlogical.c

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