@@ -467,13 +467,25 @@ struct cfp
467467static int hasSuffix (const char * filename , const char * suffix );
468468#endif
469469
470+ /* free() without changing errno; useful in several places below */
471+ static void
472+ free_keep_errno (void * p )
473+ {
474+ int save_errno = errno ;
475+
476+ free (p );
477+ errno = save_errno ;
478+ }
479+
470480/*
471481 * Open a file for reading. 'path' is the file to open, and 'mode' should
472482 * be either "r" or "rb".
473483 *
474484 * If the file at 'path' does not exist, we append the ".gz" suffix (if 'path'
475485 * doesn't already have it) and try again. So if you pass "foo" as 'path',
476486 * this will open either "foo" or "foo.gz".
487+ *
488+ * On failure, return NULL with an error code in errno.
477489 */
478490cfp *
479491cfopen_read (const char * path , const char * mode )
@@ -498,7 +510,7 @@ cfopen_read(const char *path, const char *mode)
498510
499511 snprintf (fname , fnamelen , "%s%s" , path , ".gz" );
500512 fp = cfopen (fname , mode , 1 );
501- free (fname );
513+ free_keep_errno (fname );
502514 }
503515#endif
504516 }
@@ -511,8 +523,10 @@ cfopen_read(const char *path, const char *mode)
511523 * ("w", "wb", "a", or "ab").
512524 *
513525 * If 'compression' is non-zero, a gzip compressed stream is opened, and
514- * and 'compression' indicates the compression level used. The ".gz" suffix
526+ * 'compression' indicates the compression level used. The ".gz" suffix
515527 * is automatically added to 'path' in that case.
528+ *
529+ * On failure, return NULL with an error code in errno.
516530 */
517531cfp *
518532cfopen_write (const char * path , const char * mode , int compression )
@@ -531,8 +545,8 @@ cfopen_write(const char *path, const char *mode, int compression)
531545 die_horribly (NULL , modulename , "Out of memory\n" );
532546
533547 snprintf (fname , fnamelen , "%s%s" , path , ".gz" );
534- fp = cfopen (fname , mode , 1 );
535- free (fname );
548+ fp = cfopen (fname , mode , compression );
549+ free_keep_errno (fname );
536550#else
537551 die_horribly (NULL , modulename , "not built with zlib support\n" );
538552 fp = NULL ; /* keep compiler quiet */
@@ -543,7 +557,9 @@ cfopen_write(const char *path, const char *mode, int compression)
543557
544558/*
545559 * Opens file 'path' in 'mode'. If 'compression' is non-zero, the file
546- * is opened with libz gzopen(), otherwise with plain fopen()
560+ * is opened with libz gzopen(), otherwise with plain fopen().
561+ *
562+ * On failure, return NULL with an error code in errno.
547563 */
548564cfp *
549565cfopen (const char * path , const char * mode , int compression )
@@ -556,11 +572,15 @@ cfopen(const char *path, const char *mode, int compression)
556572 if (compression != 0 )
557573 {
558574#ifdef HAVE_LIBZ
559- fp -> compressedfp = gzopen (path , mode );
575+ char mode_compression [32 ];
576+
577+ snprintf (mode_compression , sizeof (mode_compression ), "%s%d" ,
578+ mode , compression );
579+ fp -> compressedfp = gzopen (path , mode_compression );
560580 fp -> uncompressedfp = NULL ;
561581 if (fp -> compressedfp == NULL )
562582 {
563- free (fp );
583+ free_keep_errno (fp );
564584 fp = NULL ;
565585 }
566586#else
@@ -575,7 +595,7 @@ cfopen(const char *path, const char *mode, int compression)
575595 fp -> uncompressedfp = fopen (path , mode );
576596 if (fp -> uncompressedfp == NULL )
577597 {
578- free (fp );
598+ free_keep_errno (fp );
579599 fp = NULL ;
580600 }
581601 }
@@ -650,7 +670,7 @@ cfclose(cfp *fp)
650670 result = fclose (fp -> uncompressedfp );
651671 fp -> uncompressedfp = NULL ;
652672 }
653- free (fp );
673+ free_keep_errno (fp );
654674
655675 return result ;
656676}
0 commit comments