aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2017-08-02 18:26:26 -0400
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2017-08-02 18:26:58 -0400
commit060393f2a13651bf53c7626a3587baaf82942023 (patch)
treece890390f6d48cceaa0eb52f2704272cd956128a /src
parente5c87d5e1d9cad9019e2c4e4f392ba687bc58d02 (diff)
downloadpostgresql-060393f2a13651bf53c7626a3587baaf82942023.tar.gz
postgresql-060393f2a13651bf53c7626a3587baaf82942023.zip
Fix pg_dump's errno checking for zlib I/O
Some error reports were reporting strerror(errno), which for some error conditions coming from zlib are wrong, resulting in confusing reports such as pg_restore: [compress_io] could not read from input file: Success which makes no sense. To correctly extract the error message we need to use gzerror(), so let's do that. This isn't as comprehensive or as neat as I would like, but at least it should improve things in many common cases. The zlib abstraction in compress_io does not seem to be applied consistently enough; we could perhaps improve that, but it seems master-only material, not a bug fix for back-patching. This problem goes back all the way, but I decided to apply back to 9.4 only, because older branches don't contain commit 14ea89366 which this change depends on. Authors: Vladimir Kunschikov, Álvaro Herrera Discussion: https://postgr.es/m/1498120508308.9826@infotecs.ru
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/compress_io.c24
-rw-r--r--src/bin/pg_dump/compress_io.h1
-rw-r--r--src/bin/pg_dump/pg_backup_directory.c10
-rw-r--r--src/bin/pg_dump/pg_backup_tar.c8
4 files changed, 38 insertions, 5 deletions
diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c
index e0ef9cd60ac..eb590c348cb 100644
--- a/src/bin/pg_dump/compress_io.c
+++ b/src/bin/pg_dump/compress_io.c
@@ -592,8 +592,14 @@ cfread(void *ptr, int size, cfp *fp)
{
ret = gzread(fp->compressedfp, ptr, size);
if (ret != size && !gzeof(fp->compressedfp))
+ {
+ int errnum;
+ const char *errmsg = gzerror(fp->compressedfp, &errnum);
+
exit_horribly(modulename,
- "could not read from input file: %s\n", strerror(errno));
+ "could not read from input file: %s\n",
+ errnum == Z_ERRNO ? strerror(errno) : errmsg);
+ }
}
else
#endif
@@ -695,6 +701,22 @@ cfeof(cfp *fp)
return feof(fp->uncompressedfp);
}
+const char *
+get_cfp_error(cfp *fp)
+{
+#ifdef HAVE_LIBZ
+ if (fp->compressedfp)
+ {
+ int errnum;
+ const char *errmsg = gzerror(fp->compressedfp, &errnum);
+
+ if (errnum != Z_ERRNO)
+ return errmsg;
+ }
+#endif
+ return strerror(errno);
+}
+
#ifdef HAVE_LIBZ
static int
hasSuffix(const char *filename, const char *suffix)
diff --git a/src/bin/pg_dump/compress_io.h b/src/bin/pg_dump/compress_io.h
index 2a45600943a..89be583d456 100644
--- a/src/bin/pg_dump/compress_io.h
+++ b/src/bin/pg_dump/compress_io.h
@@ -65,5 +65,6 @@ extern int cfgetc(cfp *fp);
extern char *cfgets(cfp *fp, char *buf, int len);
extern int cfclose(cfp *fp);
extern int cfeof(cfp *fp);
+extern const char *get_cfp_error(cfp *fp);
#endif
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
index e52f12258a7..6673d4a3cdd 100644
--- a/src/bin/pg_dump/pg_backup_directory.c
+++ b/src/bin/pg_dump/pg_backup_directory.c
@@ -357,7 +357,9 @@ _WriteData(ArchiveHandle *AH, const void *data, size_t dLen)
lclContext *ctx = (lclContext *) AH->formatData;
if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen)
- WRITE_ERROR_EXIT;
+ exit_horribly(modulename, "could not write to output file: %s\n",
+ get_cfp_error(ctx->dataFH));
+
return;
}
@@ -495,7 +497,8 @@ _WriteByte(ArchiveHandle *AH, const int i)
lclContext *ctx = (lclContext *) AH->formatData;
if (cfwrite(&c, 1, ctx->dataFH) != 1)
- WRITE_ERROR_EXIT;
+ exit_horribly(modulename, "could not write to output file: %s\n",
+ get_cfp_error(ctx->dataFH));
return 1;
}
@@ -524,7 +527,8 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len)
lclContext *ctx = (lclContext *) AH->formatData;
if (cfwrite(buf, len, ctx->dataFH) != len)
- WRITE_ERROR_EXIT;
+ exit_horribly(modulename, "could not write to output file: %s\n",
+ get_cfp_error(ctx->dataFH));
return;
}
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 8dfc6a98de1..befbb4ade42 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -557,8 +557,14 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh)
{
res = GZREAD(&((char *) buf)[used], 1, len, th->zFH);
if (res != len && !GZEOF(th->zFH))
+ {
+ int errnum;
+ const char *errmsg = gzerror(th->zFH, &errnum);
+
exit_horribly(modulename,
- "could not read from input file: %s\n", strerror(errno));
+ "could not read from input file: %s\n",
+ errnum == Z_ERRNO ? strerror(errno) : errmsg);
+ }
}
else
{