[PATCH] pg_restore: use strerror for errors other than ENOENT

From: Justin Pryzby <pryzby(at)telsasoft(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: [PATCH] pg_restore: use strerror for errors other than ENOENT
Date: 2023-01-15 02:16:28
Message-ID: 20230115021627.GD9837@telsasoft.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Without this patch:

$ mkdir 000; chmod 000 ./000
$ strace -fe open,stat ./tmp_install/usr/local/pgsql/bin/pg_restore -vvv -l ./000
...
pg_restore: allocating AH for ./000, format 0
pg_restore: attempting to ascertain archive format
stat("./000", {st_mode=S_IFDIR|000, st_size=4096, ...}) = 0
stat("./000/toc.dat", 0x7ffc679fb3a0) = -1 EACCES (Permission denied)
stat("./000/toc.dat.gz", 0x7ffc679fb3a0) = -1 EACCES (Permission denied)
pg_restore: error: directory "./000" does not appear to be a valid archive ("toc.dat" does not exist)
+++ exited with 1 +++

With:
stat("./000/toc.dat", 0x7ffc29ad0eb0) = -1 EACCES (Permission denied)
pg_restore: error: could not open input file "./000": Permission denied

I "learned" some time ago to infer what the error message should have
said, and finally wrote this so it does what it should. I'd consider
this a backpatchable fix to save people the trouble of diagnosing the
meaning of the error message.

commit 45722852d98b8e9c2702aabe2745d7df200da124
Author: Justin Pryzby <pryzbyj(at)telsasoft(dot)com>
Date: Sat Jan 14 19:51:31 2023 -0600

pg_restore: use strerror for errors other than ENOENT

diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 7f7a0f1ce7b..e36ee7af157 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -2107,7 +2107,12 @@ _discoverArchiveFormat(ArchiveHandle *AH)
if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH)
pg_fatal("directory name too long: \"%s\"",
AH->fSpec);
- if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
+ if (stat(buf, &st) != 0)
+ {
+ if (errno != ENOENT)
+ pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
+ }
+ else if (S_ISREG(st.st_mode))
{
AH->format = archDirectory;
return AH->format;
@@ -2117,7 +2122,12 @@ _discoverArchiveFormat(ArchiveHandle *AH)
if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH)
pg_fatal("directory name too long: \"%s\"",
AH->fSpec);
- if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
+ if (stat(buf, &st) != 0)
+ {
+ if (errno != ENOENT)
+ pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
+ }
+ else if (S_ISREG(st.st_mode))
{
AH->format = archDirectory;
return AH->format;

Browse pgsql-hackers by date

  From Date Subject
Next Message David G. Johnston 2023-01-15 02:19:21 Re: pgsql: Add new GUC createrole_self_grant.
Previous Message David G. Johnston 2023-01-15 01:12:24 Re: pgsql: Add new GUC createrole_self_grant.