@@ -453,13 +453,25 @@ struct cfp
453453static int hasSuffix (const char * filename , const char * suffix );
454454#endif
455455
456+ /* free() without changing errno; useful in several places below */
457+ static void
458+ free_keep_errno (void * p )
459+ {
460+ int save_errno = errno ;
461+
462+ free (p );
463+ errno = save_errno ;
464+ }
465+
456466/*
457467 * Open a file for reading. 'path' is the file to open, and 'mode' should
458468 * be either "r" or "rb".
459469 *
460470 * If the file at 'path' does not exist, we append the ".gz" suffix (if 'path'
461471 * doesn't already have it) and try again. So if you pass "foo" as 'path',
462472 * this will open either "foo" or "foo.gz".
473+ *
474+ * On failure, return NULL with an error code in errno.
463475 */
464476cfp *
465477cfopen_read (const char * path , const char * mode )
@@ -480,7 +492,7 @@ cfopen_read(const char *path, const char *mode)
480492
481493 fname = psprintf ("%s.gz" , path );
482494 fp = cfopen (fname , mode , 1 );
483- free (fname );
495+ free_keep_errno (fname );
484496 }
485497#endif
486498 }
@@ -493,8 +505,10 @@ cfopen_read(const char *path, const char *mode)
493505 * ("w", "wb", "a", or "ab").
494506 *
495507 * If 'compression' is non-zero, a gzip compressed stream is opened, and
496- * and 'compression' indicates the compression level used. The ".gz" suffix
508+ * 'compression' indicates the compression level used. The ".gz" suffix
497509 * is automatically added to 'path' in that case.
510+ *
511+ * On failure, return NULL with an error code in errno.
498512 */
499513cfp *
500514cfopen_write (const char * path , const char * mode , int compression )
@@ -509,8 +523,8 @@ cfopen_write(const char *path, const char *mode, int compression)
509523 char * fname ;
510524
511525 fname = psprintf ("%s.gz" , path );
512- fp = cfopen (fname , mode , 1 );
513- free (fname );
526+ fp = cfopen (fname , mode , compression );
527+ free_keep_errno (fname );
514528#else
515529 exit_horribly (modulename , "not built with zlib support\n" );
516530 fp = NULL ; /* keep compiler quiet */
@@ -521,7 +535,9 @@ cfopen_write(const char *path, const char *mode, int compression)
521535
522536/*
523537 * Opens file 'path' in 'mode'. If 'compression' is non-zero, the file
524- * is opened with libz gzopen(), otherwise with plain fopen()
538+ * is opened with libz gzopen(), otherwise with plain fopen().
539+ *
540+ * On failure, return NULL with an error code in errno.
525541 */
526542cfp *
527543cfopen (const char * path , const char * mode , int compression )
@@ -531,11 +547,15 @@ cfopen(const char *path, const char *mode, int compression)
531547 if (compression != 0 )
532548 {
533549#ifdef HAVE_LIBZ
534- fp -> compressedfp = gzopen (path , mode );
550+ char mode_compression [32 ];
551+
552+ snprintf (mode_compression , sizeof (mode_compression ), "%s%d" ,
553+ mode , compression );
554+ fp -> compressedfp = gzopen (path , mode_compression );
535555 fp -> uncompressedfp = NULL ;
536556 if (fp -> compressedfp == NULL )
537557 {
538- free (fp );
558+ free_keep_errno (fp );
539559 fp = NULL ;
540560 }
541561#else
@@ -550,7 +570,7 @@ cfopen(const char *path, const char *mode, int compression)
550570 fp -> uncompressedfp = fopen (path , mode );
551571 if (fp -> uncompressedfp == NULL )
552572 {
553- free (fp );
573+ free_keep_errno (fp );
554574 fp = NULL ;
555575 }
556576 }
@@ -659,7 +679,7 @@ cfclose(cfp *fp)
659679 result = fclose (fp -> uncompressedfp );
660680 fp -> uncompressedfp = NULL ;
661681 }
662- free (fp );
682+ free_keep_errno (fp );
663683
664684 return result ;
665685}
0 commit comments