From 415cb8dd5bbb589a928c5c542fcc38a720b3e502 Mon Sep 17 00:00:00 2001 From: Andreas Karlsson Date: Tue, 19 Aug 2025 15:32:54 +0200 Subject: [PATCH] Properly print errors from system() in archive and restore commands We used to assume that the only errors which could happen were ones which set the errno, but that is not the case. We also want to give nice output on non-zero return values and if the process was killed by a signal. --- .../pg_tde/src/bin/pg_tde_archive_decrypt.c | 18 ++++++++++++++++-- .../pg_tde/src/bin/pg_tde_restore_encrypt.c | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/contrib/pg_tde/src/bin/pg_tde_archive_decrypt.c b/contrib/pg_tde/src/bin/pg_tde_archive_decrypt.c index 3afe254b491..786919a3150 100644 --- a/contrib/pg_tde/src/bin/pg_tde_archive_decrypt.c +++ b/contrib/pg_tde/src/bin/pg_tde_archive_decrypt.c @@ -146,6 +146,7 @@ main(int argc, char *argv[]) char tmpdir[MAXPGPATH] = TMPFS_DIRECTORY "/pg_tde_archiveXXXXXX"; char tmppath[MAXPGPATH]; bool issegment; + int rc; pg_logging_init(argv[0]); progname = get_progname(argv[0]); @@ -208,9 +209,22 @@ main(int argc, char *argv[]) command = replace_percent_placeholders(command, "ARCHIVE-COMMAND", "fp", targetname, sourcepath); + rc = system(command); - if (system(command) != 0) - pg_fatal("ARCHIVE-COMMAND \"%s\" failed: %m", command); + if (rc != 0) + { + if (rc == -1) + pg_fatal("ARCHIVE-COMMAND \"%s\" failed: %m", command); + else if (WIFEXITED(rc)) + pg_fatal("ARCHIVE-COMMAND \"%s\" failed with exit code %d", + command, WEXITSTATUS(rc)); + else if (WIFSIGNALED(rc)) + pg_fatal("ARCHIVE-COMMAND \"%s\" was terminated by signal %d: %s", + command, WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))); + else + pg_fatal("ARCHIVE-COMMAND \"%s\" exited with unrecognized status %d", + command, rc); + } free(command); diff --git a/contrib/pg_tde/src/bin/pg_tde_restore_encrypt.c b/contrib/pg_tde/src/bin/pg_tde_restore_encrypt.c index 03f73cc1e6a..1d5c51f4a7b 100644 --- a/contrib/pg_tde/src/bin/pg_tde_restore_encrypt.c +++ b/contrib/pg_tde/src/bin/pg_tde_restore_encrypt.c @@ -141,6 +141,7 @@ main(int argc, char *argv[]) char tmpdir[MAXPGPATH] = TMPFS_DIRECTORY "/pg_tde_restoreXXXXXX"; char tmppath[MAXPGPATH]; bool issegment; + int rc; pg_logging_init(argv[0]); progname = get_progname(argv[0]); @@ -201,9 +202,22 @@ main(int argc, char *argv[]) command = replace_percent_placeholders(command, "RESTORE-COMMAND", "fp", sourcename, targetpath); + rc = system(command); - if (system(command) != 0) - pg_fatal("RESTORE-COMMAND \"%s\" failed: %m", command); + if (rc != 0) + { + if (rc == -1) + pg_fatal("RESTORE-COMMAND \"%s\" failed: %m", command); + else if (WIFEXITED(rc)) + pg_fatal("RESTORE-COMMAND \"%s\" failed with exit code %d", + command, WEXITSTATUS(rc)); + else if (WIFSIGNALED(rc)) + pg_fatal("RESTORE-COMMAND \"%s\" was terminated by signal %d: %s", + command, WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))); + else + pg_fatal("RESTORE-COMMAND \"%s\" exited with unrecognized status %d", + command, rc); + } free(command);