diff -durpN postgresql.4/src/bin/pg_basebackup/pg_basebackup.c postgresql.5/src/bin/pg_basebackup/pg_basebackup.c --- postgresql.4/src/bin/pg_basebackup/pg_basebackup.c 2013-01-02 13:33:46.127749834 +0100 +++ postgresql.5/src/bin/pg_basebackup/pg_basebackup.c 2013-01-02 16:21:32.022484045 +0100 @@ -251,7 +251,7 @@ LogStreamerMain(logstreamer_param *param */ return 1; - PQfinish(param->bgconn); + PQfinishSafe(param->bgconn); return 0; } @@ -277,7 +277,7 @@ StartLogStreamer(char *startpos, uint32 fprintf(stderr, _("%s: could not parse transaction log location \"%s\"\n"), progname, startpos); - disconnect_and_exit(1); + exit(1); } param->startptr = ((uint64) hi) << 32 | lo; /* Round off to even segment position */ @@ -290,7 +290,7 @@ StartLogStreamer(char *startpos, uint32 fprintf(stderr, _("%s: could not create pipe for background process: %s\n"), progname, strerror(errno)); - disconnect_and_exit(1); + exit(1); } #endif @@ -323,7 +323,7 @@ StartLogStreamer(char *startpos, uint32 { fprintf(stderr, _("%s: could not create background process: %s\n"), progname, strerror(errno)); - disconnect_and_exit(1); + exit(1); } /* @@ -335,7 +335,7 @@ StartLogStreamer(char *startpos, uint32 { fprintf(stderr, _("%s: could not create background thread: %s\n"), progname, strerror(errno)); - disconnect_and_exit(1); + exit(1); } #endif } @@ -360,7 +360,7 @@ verify_dir_is_empty_or_create(char *dirn fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), progname, dirname, strerror(errno)); - disconnect_and_exit(1); + exit(1); } return; case 1: @@ -377,7 +377,7 @@ verify_dir_is_empty_or_create(char *dirn fprintf(stderr, _("%s: directory \"%s\" exists but is not empty\n"), progname, dirname); - disconnect_and_exit(1); + exit(1); case -1: /* @@ -385,7 +385,7 @@ verify_dir_is_empty_or_create(char *dirn */ fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), progname, dirname, strerror(errno)); - disconnect_and_exit(1); + exit(1); } } @@ -493,7 +493,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 @@ -503,7 +503,7 @@ writeTarData( { fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), progname, current_file, strerror(errno)); - disconnect_and_exit(1); + exit(1); } } } @@ -557,7 +557,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); - disconnect_and_exit(1); + exit(1); } } else @@ -577,7 +577,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); - disconnect_and_exit(1); + exit(1); } } else @@ -605,7 +605,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r fprintf(stderr, _("%s: could not set compression level %d: %s\n"), progname, compresslevel, get_gz_error(ztarfile)); - disconnect_and_exit(1); + exit(1); } } else @@ -626,7 +626,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r fprintf(stderr, _("%s: could not create compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); - disconnect_and_exit(1); + exit(1); } } else @@ -637,7 +637,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r { fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); - disconnect_and_exit(1); + exit(1); } } @@ -649,7 +649,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r { fprintf(stderr, _("%s: could not get COPY data stream: %s"), progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } /* @@ -717,7 +717,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r fprintf(stderr, _("%s: could not close compressed file \"%s\": %s\n"), progname, filename, get_gz_error(ztarfile)); - disconnect_and_exit(1); + exit(1); } } else @@ -730,7 +730,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), progname, filename, strerror(errno)); - disconnect_and_exit(1); + exit(1); } } } @@ -741,7 +741,7 @@ ReceiveTarFile(PGconn *conn, PGresult *r { fprintf(stderr, _("%s: could not read COPY data: %s"), progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } if (!writerecoveryconf || !basetablespace) @@ -907,7 +907,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: could not get COPY data stream: %s"), progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } while (1) @@ -936,7 +936,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: could not read COPY data: %s"), progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } if (file == NULL) @@ -950,7 +950,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: invalid tar block header size: %d\n"), progname, r); - disconnect_and_exit(1); + exit(1); } totaldone += 512; @@ -958,7 +958,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: could not parse file size\n"), progname); - disconnect_and_exit(1); + exit(1); } /* Set permissions on the file */ @@ -966,7 +966,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: could not parse file mode\n"), progname); - disconnect_and_exit(1); + exit(1); } /* @@ -1003,7 +1003,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), progname, filename, strerror(errno)); - disconnect_and_exit(1); + exit(1); } } #ifndef WIN32 @@ -1024,7 +1024,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG fprintf(stderr, _("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"), progname, filename, ©buf[157], strerror(errno)); - disconnect_and_exit(1); + exit(1); } } else @@ -1032,7 +1032,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG fprintf(stderr, _("%s: unrecognized link indicator \"%c\"\n"), progname, copybuf[156]); - disconnect_and_exit(1); + exit(1); } continue; /* directory or link handled */ } @@ -1045,7 +1045,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); - disconnect_and_exit(1); + exit(1); } #ifndef WIN32 @@ -1085,7 +1085,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG { fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), progname, filename, strerror(errno)); - disconnect_and_exit(1); + exit(1); } totaldone += r; if (showprogress) @@ -1111,7 +1111,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PG fprintf(stderr, _("%s: COPY stream ended before last file was finished\n"), progname); - disconnect_and_exit(1); + exit(1); } if (copybuf != NULL) @@ -1149,21 +1149,21 @@ CreateRecoveryConf(PGconn *conn) if (connOptions == NULL) { fprintf(stderr, _("%s: out of memory"), progname); - disconnect_and_exit(1); + exit(1); } appendPQExpBufferStr(rcExpBuf, "standby_mode = 'on'\n"); if (PQExpBufferBroken(rcExpBuf)) { fprintf(stderr, _("%s: out of memory"), progname); - disconnect_and_exit(1); + exit(1); } appendPQExpBufferStr(rcExpBuf, "primary_conninfo = '"); if (PQExpBufferBroken(rcExpBuf)) { fprintf(stderr, _("%s: out of memory"), progname); - disconnect_and_exit(1); + exit(1); } for (option = connOptions; option && option->keyword; option++) @@ -1194,7 +1194,7 @@ CreateRecoveryConf(PGconn *conn) if (PQExpBufferBroken(rcExpBuf)) { fprintf(stderr, _("%s: out of memory"), progname); - disconnect_and_exit(1); + exit(1); } free(escaped); @@ -1204,7 +1204,7 @@ CreateRecoveryConf(PGconn *conn) if (PQExpBufferBroken(rcExpBuf)) { fprintf(stderr, _("%s: out of memory"), progname); - disconnect_and_exit(1); + exit(1); } PQconninfoFree(connOptions); @@ -1226,7 +1226,7 @@ WriteRecoveryConf(void) if (cf == NULL) { fprintf(stderr, _("%s: cannot create %s: %s"), progname, filename, strerror(errno)); - disconnect_and_exit(1); + exit(1); } if (fwrite(rcExpBuf->data, rcExpBuf->len, 1, cf) != 1) @@ -1234,7 +1234,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); @@ -1268,7 +1268,7 @@ BaseBackup(void) if (!rcExpBuf) { fprintf(stderr, _("%s: out of memory"), progname); - disconnect_and_exit(1); + exit(1); } CreateRecoveryConf(conn); @@ -1281,18 +1281,18 @@ BaseBackup(void) { fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), progname, "IDENTIFY_SYSTEM", PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } if (PQntuples(res) != 1 || PQnfields(res) != 3) { fprintf(stderr, _("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d fields\n"), progname, PQntuples(res), PQnfields(res), 1, 3); - disconnect_and_exit(1); + exit(1); } sysidentifier = pg_strdup(PQgetvalue(res, 0, 0)); timeline = atoi(PQgetvalue(res, 0, 1)); - PQclear(res); + PQclearSafe(res); /* * Start the actual backup @@ -1310,7 +1310,7 @@ BaseBackup(void) { fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), progname, "BASE_BACKUP", PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } /* @@ -1321,18 +1321,18 @@ 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: no start point returned from server\n"), progname); - disconnect_and_exit(1); + exit(1); } strcpy(xlogstart, PQgetvalue(res, 0, 0)); if (verbose && includewal) fprintf(stderr, "transaction log start point: %s\n", xlogstart); - PQclear(res); + PQclearSafe(res); MemSet(xlogend, 0, sizeof(xlogend)); /* @@ -1343,12 +1343,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); } /* @@ -1378,7 +1378,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); } /* @@ -1409,7 +1409,7 @@ BaseBackup(void) progress_report(PQntuples(res), NULL); fprintf(stderr, "\n"); /* Need to move to next line */ } - PQclear(res); + PQclearSafe(res); /* * Get the stop position @@ -1420,26 +1420,26 @@ BaseBackup(void) fprintf(stderr, _("%s: could not get transaction log end position from server: %s"), progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } if (PQntuples(res) != 1) { fprintf(stderr, _("%s: no transaction log end position returned from server\n"), progname); - disconnect_and_exit(1); + exit(1); } strcpy(xlogend, PQgetvalue(res, 0, 0)); if (verbose && includewal) fprintf(stderr, "transaction log end point: %s\n", xlogend); - PQclear(res); + PQclearSafe(res); res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, _("%s: final receive failed: %s"), progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } if (bgchild > 0) @@ -1463,7 +1463,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 */ @@ -1472,25 +1472,25 @@ 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, r, (int) bgchild); - disconnect_and_exit(1); + exit(1); } if (!WIFEXITED(status)) { fprintf(stderr, _("%s: child process did not exit normally\n"), progname); - disconnect_and_exit(1); + exit(1); } if (WEXITSTATUS(status) != 0) { fprintf(stderr, _("%s: child process exited with error %d\n"), progname, WEXITSTATUS(status)); - disconnect_and_exit(1); + exit(1); } /* Exited normally, we're happy! */ #else /* WIN32 */ @@ -1505,7 +1505,7 @@ BaseBackup(void) fprintf(stderr, _("%s: could not parse transaction log location \"%s\"\n"), progname, xlogend); - disconnect_and_exit(1); + exit(1); } xlogendptr = ((uint64) hi) << 32 | lo; InterlockedIncrement(&has_xlogendptr); @@ -1517,20 +1517,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, &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 @@ -1542,8 +1542,8 @@ BaseBackup(void) /* * End of copy data. Final result is already checked inside the loop. */ - PQclear(res); - PQfinish(conn); + PQclearSafe(res); + PQfinishSafe(conn); if (verbose) fprintf(stderr, "%s: base backup completed\n", progname); @@ -1579,6 +1579,8 @@ main(int argc, char **argv) int option_index; + atexit(disconnect_on_exit); + progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup")); diff -durpN postgresql.4/src/bin/pg_basebackup/pg_receivexlog.c postgresql.5/src/bin/pg_basebackup/pg_receivexlog.c --- postgresql.4/src/bin/pg_basebackup/pg_receivexlog.c 2013-01-02 13:46:06.828642607 +0100 +++ postgresql.5/src/bin/pg_basebackup/pg_receivexlog.c 2013-01-02 16:22:26.319862083 +0100 @@ -108,7 +108,7 @@ FindStreamingStart(XLogRecPtr currentpos { fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), progname, basedir, strerror(errno)); - disconnect_and_exit(1); + exit(1); } while ((dirent = readdir(dir)) != NULL) @@ -150,7 +150,7 @@ FindStreamingStart(XLogRecPtr currentpos fprintf(stderr, _("%s: could not parse transaction log file name \"%s\"\n"), progname, dirent->d_name); - disconnect_and_exit(1); + exit(1); } segno = ((uint64) log) << 32 | seg; @@ -164,7 +164,7 @@ FindStreamingStart(XLogRecPtr currentpos { fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"), progname, fullpath, strerror(errno)); - disconnect_and_exit(1); + exit(1); } if (statbuf.st_size == XLOG_SEG_SIZE) @@ -234,14 +234,14 @@ StreamLog(void) { fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), progname, "IDENTIFY_SYSTEM", PQerrorMessage(conn)); - disconnect_and_exit(1); + exit(1); } if (PQntuples(res) != 1 || PQnfields(res) != 3) { fprintf(stderr, _("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d fields\n"), progname, PQntuples(res), PQnfields(res), 1, 3); - disconnect_and_exit(1); + exit(1); } timeline = atoi(PQgetvalue(res, 0, 1)); if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &hi, &lo) != 2) @@ -249,10 +249,10 @@ StreamLog(void) fprintf(stderr, _("%s: could not parse transaction log location \"%s\"\n"), progname, PQgetvalue(res, 0, 2)); - disconnect_and_exit(1); + exit(1); } startpos = ((uint64) hi) << 32 | lo; - PQclear(res); + PQclearSafe(res); /* * Figure out where to start streaming. @@ -276,7 +276,7 @@ StreamLog(void) ReceiveXlogStream(conn, startpos, timeline, NULL, basedir, stop_streaming, standby_message_timeout, false); - PQfinish(conn); + PQfinishSafe(conn); } /* @@ -313,6 +313,8 @@ main(int argc, char **argv) int c; int option_index; + atexit(disconnect_on_exit); + progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_receivexlog")); diff -durpN postgresql.4/src/bin/pg_basebackup/streamutil.c postgresql.5/src/bin/pg_basebackup/streamutil.c --- postgresql.4/src/bin/pg_basebackup/streamutil.c 2013-01-02 12:57:57.401140484 +0100 +++ postgresql.5/src/bin/pg_basebackup/streamutil.c 2013-01-02 16:21:23.247422858 +0100 @@ -170,3 +170,9 @@ GetConnection(void) return tmpconn; } } + +void +disconnect_on_exit(void) +{ + PQfinishSafe(conn); +} diff -durpN postgresql.4/src/bin/pg_basebackup/streamutil.h postgresql.5/src/bin/pg_basebackup/streamutil.h --- postgresql.4/src/bin/pg_basebackup/streamutil.h 2013-01-02 13:34:42.760112017 +0100 +++ postgresql.5/src/bin/pg_basebackup/streamutil.h 2013-01-02 16:21:25.111435906 +0100 @@ -9,10 +9,6 @@ extern int dbgetpassword; /* Connection kept global so we can disconnect easily */ extern PGconn *conn; -#define disconnect_and_exit(code) \ - { \ - if (conn != NULL) PQfinish(conn); \ - exit(code); \ - } - extern PGconn *GetConnection(void); + +extern void disconnect_on_exit(void);