@@ -464,13 +464,25 @@ struct cfp
464464static int hasSuffix (const char * filename , const char * suffix );
465465#endif
466466
467+ /* free() without changing errno; useful in several places below */
468+ static void
469+ free_keep_errno (void * p )
470+ {
471+ int save_errno = errno ;
472+
473+ free (p );
474+ errno = save_errno ;
475+ }
476+
467477/*
468478 * Open a file for reading. 'path' is the file to open, and 'mode' should
469479 * be either "r" or "rb".
470480 *
471481 * If the file at 'path' does not exist, we append the ".gz" suffix (if 'path'
472482 * doesn't already have it) and try again. So if you pass "foo" as 'path',
473483 * this will open either "foo" or "foo.gz".
484+ *
485+ * On failure, return NULL with an error code in errno.
474486 */
475487cfp *
476488cfopen_read (const char * path , const char * mode )
@@ -492,7 +504,7 @@ cfopen_read(const char *path, const char *mode)
492504
493505 snprintf (fname , fnamelen , "%s%s" , path , ".gz" );
494506 fp = cfopen (fname , mode , 1 );
495- free (fname );
507+ free_keep_errno (fname );
496508 }
497509#endif
498510 }
@@ -505,8 +517,10 @@ cfopen_read(const char *path, const char *mode)
505517 * ("w", "wb", "a", or "ab").
506518 *
507519 * If 'compression' is non-zero, a gzip compressed stream is opened, and
508- * and 'compression' indicates the compression level used. The ".gz" suffix
520+ * 'compression' indicates the compression level used. The ".gz" suffix
509521 * is automatically added to 'path' in that case.
522+ *
523+ * On failure, return NULL with an error code in errno.
510524 */
511525cfp *
512526cfopen_write (const char * path , const char * mode , int compression )
@@ -522,8 +536,8 @@ cfopen_write(const char *path, const char *mode, int compression)
522536 char * fname = pg_malloc (fnamelen );
523537
524538 snprintf (fname , fnamelen , "%s%s" , path , ".gz" );
525- fp = cfopen (fname , mode , 1 );
526- free (fname );
539+ fp = cfopen (fname , mode , compression );
540+ free_keep_errno (fname );
527541#else
528542 exit_horribly (modulename , "not built with zlib support\n" );
529543 fp = NULL ; /* keep compiler quiet */
@@ -534,7 +548,9 @@ cfopen_write(const char *path, const char *mode, int compression)
534548
535549/*
536550 * Opens file 'path' in 'mode'. If 'compression' is non-zero, the file
537- * is opened with libz gzopen(), otherwise with plain fopen()
551+ * is opened with libz gzopen(), otherwise with plain fopen().
552+ *
553+ * On failure, return NULL with an error code in errno.
538554 */
539555cfp *
540556cfopen (const char * path , const char * mode , int compression )
@@ -544,11 +560,15 @@ cfopen(const char *path, const char *mode, int compression)
544560 if (compression != 0 )
545561 {
546562#ifdef HAVE_LIBZ
547- fp -> compressedfp = gzopen (path , mode );
563+ char mode_compression [32 ];
564+
565+ snprintf (mode_compression , sizeof (mode_compression ), "%s%d" ,
566+ mode , compression );
567+ fp -> compressedfp = gzopen (path , mode_compression );
548568 fp -> uncompressedfp = NULL ;
549569 if (fp -> compressedfp == NULL )
550570 {
551- free (fp );
571+ free_keep_errno (fp );
552572 fp = NULL ;
553573 }
554574#else
@@ -563,7 +583,7 @@ cfopen(const char *path, const char *mode, int compression)
563583 fp -> uncompressedfp = fopen (path , mode );
564584 if (fp -> uncompressedfp == NULL )
565585 {
566- free (fp );
586+ free_keep_errno (fp );
567587 fp = NULL ;
568588 }
569589 }
@@ -638,7 +658,7 @@ cfclose(cfp *fp)
638658 result = fclose (fp -> uncompressedfp );
639659 fp -> uncompressedfp = NULL ;
640660 }
641- free (fp );
661+ free_keep_errno (fp );
642662
643663 return result ;
644664}
0 commit comments