From 96f222dc44e318f1a3e40c58c04c16d06580e12d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 22:02:11 +0000 Subject: [PATCH 1/2] Initial plan From 887fedd4fb8f92da66418da6082bfcde2b8564f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Mar 2026 22:14:27 +0000 Subject: [PATCH 2/2] Close file handles before pg_fatal outside pg_upgrade Co-authored-by: yjhjstz <3832082+yjhjstz@users.noreply.github.com> --- src/bin/pg_basebackup/pg_basebackup.c | 17 +++++++++++++---- src/bin/pg_basebackup/pg_createsubscriber.c | 18 ++++++++++++------ src/bin/pg_waldump/pg_waldump.c | 20 +++++++++++++------- src/bin/pgbench/pgbench.c | 7 +++++++ src/fe_utils/astreamer_file.c | 9 +++++++-- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index fa169a8d6423b..94e3f7fee1912 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -1426,12 +1426,17 @@ ReceiveArchiveStreamChunk(size_t r, char *copybuf, void *callback_data) if (fwrite(copybuf + 1, r - 1, 1, state->manifest_file) != 1) { + int save_errno = errno; + /* * If fwrite() didn't set errno, assume that the * problem is that we're out of disk space. */ - if (errno == 0) - errno = ENOSPC; + if (save_errno == 0) + save_errno = ENOSPC; + fclose(state->manifest_file); + state->manifest_file = NULL; + errno = save_errno; pg_fatal("could not write to file \"%s\": %m", state->manifest_filename); } @@ -1723,9 +1728,13 @@ ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data) errno = 0; if (fwrite(copybuf, r, 1, state->file) != 1) { + int save_errno = errno; + /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; + if (save_errno == 0) + save_errno = ENOSPC; + fclose(state->file); + errno = save_errno; pg_fatal("could not write to file \"%s\": %m", state->filename); } } diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c index 2bc84505aab89..e57c19b10d2de 100644 --- a/src/bin/pg_basebackup/pg_createsubscriber.c +++ b/src/bin/pg_basebackup/pg_createsubscriber.c @@ -1383,15 +1383,21 @@ setup_recovery(const struct LogicalRepInfo *dbinfo, const char *datadir, const c /* Write the recovery parameters to INCLUDED_CONF_FILE */ snprintf(conf_filename, MAXPGPATH, "%s/%s", datadir, INCLUDED_CONF_FILE); - fd = fopen(conf_filename, "w"); - if (fd == NULL) - pg_fatal("could not open file \"%s\": %m", conf_filename); + fd = fopen(conf_filename, "w"); + if (fd == NULL) + pg_fatal("could not open file \"%s\": %m", conf_filename); - if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, fd) != 1) - pg_fatal("could not write to file \"%s\": %m", conf_filename); + if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, fd) != 1) + { + int save_errno = errno; fclose(fd); - recovery_params_set = true; + errno = save_errno; + pg_fatal("could not write to file \"%s\": %m", conf_filename); + } + + fclose(fd); + recovery_params_set = true; /* Include conditionally the recovery parameters. */ resetPQExpBuffer(recoveryconfcontents); diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index f3446385d6aab..9eea2e93ab362 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -527,15 +527,21 @@ XLogRecordSaveFPWs(XLogReaderState *record, const char *savepath) LSN_FORMAT_ARGS(record->ReadRecPtr), rnode.spcOid, rnode.dbOid, rnode.relNumber, blk, forkname); - file = fopen(filename, PG_BINARY_W); - if (!file) - pg_fatal("could not open file \"%s\": %m", filename); + file = fopen(filename, PG_BINARY_W); + if (!file) + pg_fatal("could not open file \"%s\": %m", filename); - if (fwrite(page, BLCKSZ, 1, file) != 1) - pg_fatal("could not write file \"%s\": %m", filename); + if (fwrite(page, BLCKSZ, 1, file) != 1) + { + int save_errno = errno; + + fclose(file); + errno = save_errno; + pg_fatal("could not write file \"%s\": %m", filename); + } - if (fclose(file) != 0) - pg_fatal("could not close file \"%s\": %m", filename); + if (fclose(file) != 0) + pg_fatal("could not close file \"%s\": %m", filename); } } diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 1dae918cc09d2..d262e4a5f993d 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -6185,7 +6185,14 @@ process_file(const char *filename, int weight) buf = read_file_contents(fd); if (ferror(fd)) + { + int save_errno = errno; + + if (fd != stdin) + fclose(fd); + errno = save_errno; pg_fatal("could not read file \"%s\": %m", filename); + } if (fd != stdin) fclose(fd); diff --git a/src/fe_utils/astreamer_file.c b/src/fe_utils/astreamer_file.c index 6e63a41af0d93..36ef72669fe7a 100644 --- a/src/fe_utils/astreamer_file.c +++ b/src/fe_utils/astreamer_file.c @@ -255,9 +255,14 @@ astreamer_extractor_content(astreamer *streamer, astreamer_member *member, errno = 0; if (len > 0 && fwrite(data, len, 1, mystreamer->file) != 1) { + int save_errno = errno; + /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; + if (save_errno == 0) + save_errno = ENOSPC; + fclose(mystreamer->file); + mystreamer->file = NULL; + errno = save_errno; pg_fatal("could not write to file \"%s\": %m", mystreamer->filename); }