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 <pryz...@telsasoft.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;