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
        {
                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
                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)
 
 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
 
        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;
 }
        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;
 }
        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;
 }
 
                        {
                                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
                        {