@@ -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
499511snprintf (fname ,fnamelen ,"%s%s" ,path ,".gz" );
500512fp = 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)
531545die_horribly (NULL ,modulename ,"Out of memory\n" );
532546
533547snprintf (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
537551die_horribly (NULL ,modulename ,"not built with zlib support\n" );
538552fp = 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)
556572if (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 );
560580fp -> uncompressedfp = NULL ;
561581if (fp -> compressedfp == NULL )
562582{
563- free (fp );
583+ free_keep_errno (fp );
564584fp = NULL ;
565585}
566586#else
@@ -575,7 +595,7 @@ cfopen(const char *path, const char *mode, int compression)
575595fp -> uncompressedfp = fopen (path ,mode );
576596if (fp -> uncompressedfp == NULL )
577597{
578- free (fp );
598+ free_keep_errno (fp );
579599fp = NULL ;
580600}
581601}
@@ -650,7 +670,7 @@ cfclose(cfp *fp)
650670result = fclose (fp -> uncompressedfp );
651671fp -> uncompressedfp = NULL ;
652672}
653- free (fp );
673+ free_keep_errno (fp );
654674
655675return result ;
656676}