mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
Fix failure to honor -Z compression level option in pg_dump -Fd.
cfopen() and cfopen_write() failed to pass the compression level through to zlib, so that you always got the default compression level if you got any at all. In passing, also fix these and related functions so that the correct errno is reliably returned on failure; the original coding supposes that free() cannot change errno, which is untrue on at least some platforms. Per bug #12779 from Christoph Berg. Back-patch to 9.1 where the faulty code was introduced. Michael Paquier
This commit is contained in:
parent
abe45a9b31
commit
0e7e355f27
@ -453,6 +453,16 @@ struct cfp
|
||||
static int hasSuffix(const char *filename, const char *suffix);
|
||||
#endif
|
||||
|
||||
/* free() without changing errno; useful in several places below */
|
||||
static void
|
||||
free_keep_errno(void *p)
|
||||
{
|
||||
int save_errno = errno;
|
||||
|
||||
free(p);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a file for reading. 'path' is the file to open, and 'mode' should
|
||||
* be either "r" or "rb".
|
||||
@ -460,6 +470,8 @@ static int hasSuffix(const char *filename, const char *suffix);
|
||||
* If the file at 'path' does not exist, we append the ".gz" suffix (if 'path'
|
||||
* doesn't already have it) and try again. So if you pass "foo" as 'path',
|
||||
* this will open either "foo" or "foo.gz".
|
||||
*
|
||||
* On failure, return NULL with an error code in errno.
|
||||
*/
|
||||
cfp *
|
||||
cfopen_read(const char *path, const char *mode)
|
||||
@ -480,7 +492,7 @@ cfopen_read(const char *path, const char *mode)
|
||||
|
||||
fname = psprintf("%s.gz", path);
|
||||
fp = cfopen(fname, mode, 1);
|
||||
free(fname);
|
||||
free_keep_errno(fname);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -493,8 +505,10 @@ cfopen_read(const char *path, const char *mode)
|
||||
* ("w", "wb", "a", or "ab").
|
||||
*
|
||||
* If 'compression' is non-zero, a gzip compressed stream is opened, and
|
||||
* and 'compression' indicates the compression level used. The ".gz" suffix
|
||||
* 'compression' indicates the compression level used. The ".gz" suffix
|
||||
* is automatically added to 'path' in that case.
|
||||
*
|
||||
* On failure, return NULL with an error code in errno.
|
||||
*/
|
||||
cfp *
|
||||
cfopen_write(const char *path, const char *mode, int compression)
|
||||
@ -509,8 +523,8 @@ cfopen_write(const char *path, const char *mode, int compression)
|
||||
char *fname;
|
||||
|
||||
fname = psprintf("%s.gz", path);
|
||||
fp = cfopen(fname, mode, 1);
|
||||
free(fname);
|
||||
fp = cfopen(fname, mode, compression);
|
||||
free_keep_errno(fname);
|
||||
#else
|
||||
exit_horribly(modulename, "not built with zlib support\n");
|
||||
fp = NULL; /* keep compiler quiet */
|
||||
@ -521,7 +535,9 @@ cfopen_write(const char *path, const char *mode, int compression)
|
||||
|
||||
/*
|
||||
* Opens file 'path' in 'mode'. If 'compression' is non-zero, the file
|
||||
* is opened with libz gzopen(), otherwise with plain fopen()
|
||||
* is opened with libz gzopen(), otherwise with plain fopen().
|
||||
*
|
||||
* On failure, return NULL with an error code in errno.
|
||||
*/
|
||||
cfp *
|
||||
cfopen(const char *path, const char *mode, int compression)
|
||||
@ -531,11 +547,15 @@ cfopen(const char *path, const char *mode, int compression)
|
||||
if (compression != 0)
|
||||
{
|
||||
#ifdef HAVE_LIBZ
|
||||
fp->compressedfp = gzopen(path, mode);
|
||||
char mode_compression[32];
|
||||
|
||||
snprintf(mode_compression, sizeof(mode_compression), "%s%d",
|
||||
mode, compression);
|
||||
fp->compressedfp = gzopen(path, mode_compression);
|
||||
fp->uncompressedfp = NULL;
|
||||
if (fp->compressedfp == NULL)
|
||||
{
|
||||
free(fp);
|
||||
free_keep_errno(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
#else
|
||||
@ -550,7 +570,7 @@ cfopen(const char *path, const char *mode, int compression)
|
||||
fp->uncompressedfp = fopen(path, mode);
|
||||
if (fp->uncompressedfp == NULL)
|
||||
{
|
||||
free(fp);
|
||||
free_keep_errno(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
}
|
||||
@ -659,7 +679,7 @@ cfclose(cfp *fp)
|
||||
result = fclose(fp->uncompressedfp);
|
||||
fp->uncompressedfp = NULL;
|
||||
}
|
||||
free(fp);
|
||||
free_keep_errno(fp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user