@@ -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
481493fname = psprintf ("%s.gz" ,path );
482494fp = 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)
509523char * fname ;
510524
511525fname = 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
515529exit_horribly (modulename ,"not built with zlib support\n" );
516530fp = 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)
531547if (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 );
535555fp -> uncompressedfp = NULL ;
536556if (fp -> compressedfp == NULL )
537557{
538- free (fp );
558+ free_keep_errno (fp );
539559fp = NULL ;
540560}
541561#else
@@ -550,7 +570,7 @@ cfopen(const char *path, const char *mode, int compression)
550570fp -> uncompressedfp = fopen (path ,mode );
551571if (fp -> uncompressedfp == NULL )
552572{
553- free (fp );
573+ free_keep_errno (fp );
554574fp = NULL ;
555575}
556576}
@@ -659,7 +679,7 @@ cfclose(cfp *fp)
659679result = fclose (fp -> uncompressedfp );
660680fp -> uncompressedfp = NULL ;
661681}
662- free (fp );
682+ free_keep_errno (fp );
663683
664684return result ;
665685}