@@ -455,13 +455,25 @@ struct cfp
455455static int hasSuffix (const char * filename ,const char * suffix );
456456#endif
457457
458+ /* free() without changing errno; useful in several places below */
459+ static void
460+ free_keep_errno (void * p )
461+ {
462+ int save_errno = errno ;
463+
464+ free (p );
465+ errno = save_errno ;
466+ }
467+
458468/*
459469 * Open a file for reading. 'path' is the file to open, and 'mode' should
460470 * be either "r" or "rb".
461471 *
462472 * If the file at 'path' does not exist, we append the ".gz" suffix (if 'path'
463473 * doesn't already have it) and try again. So if you pass "foo" as 'path',
464474 * this will open either "foo" or "foo.gz".
475+ *
476+ * On failure, return NULL with an error code in errno.
465477 */
466478cfp *
467479cfopen_read (const char * path ,const char * mode )
@@ -483,7 +495,7 @@ cfopen_read(const char *path, const char *mode)
483495
484496snprintf (fname ,fnamelen ,"%s%s" ,path ,".gz" );
485497fp = cfopen (fname ,mode ,1 );
486- free (fname );
498+ free_keep_errno (fname );
487499}
488500#endif
489501}
@@ -496,8 +508,10 @@ cfopen_read(const char *path, const char *mode)
496508 * ("w", "wb", "a", or "ab").
497509 *
498510 * If 'compression' is non-zero, a gzip compressed stream is opened, and
499- *and 'compression' indicates the compression level used. The ".gz" suffix
511+ * 'compression' indicates the compression level used. The ".gz" suffix
500512 * is automatically added to 'path' in that case.
513+ *
514+ * On failure, return NULL with an error code in errno.
501515 */
502516cfp *
503517cfopen_write (const char * path ,const char * mode ,int compression )
@@ -513,8 +527,8 @@ cfopen_write(const char *path, const char *mode, int compression)
513527char * fname = pg_malloc (fnamelen );
514528
515529snprintf (fname ,fnamelen ,"%s%s" ,path ,".gz" );
516- fp = cfopen (fname ,mode ,1 );
517- free (fname );
530+ fp = cfopen (fname ,mode ,compression );
531+ free_keep_errno (fname );
518532#else
519533exit_horribly (modulename ,"not built with zlib support\n" );
520534fp = NULL ;/* keep compiler quiet */
@@ -525,7 +539,9 @@ cfopen_write(const char *path, const char *mode, int compression)
525539
526540/*
527541 * Opens file 'path' in 'mode'. If 'compression' is non-zero, the file
528- * is opened with libz gzopen(), otherwise with plain fopen()
542+ * is opened with libz gzopen(), otherwise with plain fopen().
543+ *
544+ * On failure, return NULL with an error code in errno.
529545 */
530546cfp *
531547cfopen (const char * path ,const char * mode ,int compression )
@@ -535,11 +551,15 @@ cfopen(const char *path, const char *mode, int compression)
535551if (compression != 0 )
536552{
537553#ifdef HAVE_LIBZ
538- fp -> compressedfp = gzopen (path ,mode );
554+ char mode_compression [32 ];
555+
556+ snprintf (mode_compression ,sizeof (mode_compression ),"%s%d" ,
557+ mode ,compression );
558+ fp -> compressedfp = gzopen (path ,mode_compression );
539559fp -> uncompressedfp = NULL ;
540560if (fp -> compressedfp == NULL )
541561{
542- free (fp );
562+ free_keep_errno (fp );
543563fp = NULL ;
544564}
545565#else
@@ -554,7 +574,7 @@ cfopen(const char *path, const char *mode, int compression)
554574fp -> uncompressedfp = fopen (path ,mode );
555575if (fp -> uncompressedfp == NULL )
556576{
557- free (fp );
577+ free_keep_errno (fp );
558578fp = NULL ;
559579}
560580}
@@ -629,7 +649,7 @@ cfclose(cfp *fp)
629649result = fclose (fp -> uncompressedfp );
630650fp -> uncompressedfp = NULL ;
631651}
632- free (fp );
652+ free_keep_errno (fp );
633653
634654return result ;
635655}