static int hasSuffix(const char *filename, const char *suffix);
#endif
+/* free() without changing errno; useful in several places below */
+static void
+free_keep_errno(void *p)
+{
+ int save_errno = errno;
+
+ free(p);
+ errno = save_errno;
+}
+
/*
* Open a file for reading. 'path' is the file to open, and 'mode' should
* be either "r" or "rb".
* If the file at 'path' does not exist, we append the ".gz" suffix (if 'path'
* doesn't already have it) and try again. So if you pass "foo" as 'path',
* this will open either "foo" or "foo.gz".
+ *
+ * On failure, return NULL with an error code in errno.
*/
cfp *
cfopen_read(const char *path, const char *mode)
fname = psprintf("%s.gz", path);
fp = cfopen(fname, mode, 1);
- free(fname);
+ free_keep_errno(fname);
}
#endif
}
* ("w", "wb", "a", or "ab").
*
* If 'compression' is non-zero, a gzip compressed stream is opened, and
- * and 'compression' indicates the compression level used. The ".gz" suffix
+ * 'compression' indicates the compression level used. The ".gz" suffix
* is automatically added to 'path' in that case.
+ *
+ * On failure, return NULL with an error code in errno.
*/
cfp *
cfopen_write(const char *path, const char *mode, int compression)
char *fname;
fname = psprintf("%s.gz", path);
- fp = cfopen(fname, mode, 1);
- free(fname);
+ fp = cfopen(fname, mode, compression);
+ free_keep_errno(fname);
#else
exit_horribly(modulename, "not built with zlib support\n");
fp = NULL; /* keep compiler quiet */
/*
* Opens file 'path' in 'mode'. If 'compression' is non-zero, the file
- * is opened with libz gzopen(), otherwise with plain fopen()
+ * is opened with libz gzopen(), otherwise with plain fopen().
+ *
+ * On failure, return NULL with an error code in errno.
*/
cfp *
cfopen(const char *path, const char *mode, int compression)
if (compression != 0)
{
#ifdef HAVE_LIBZ
- fp->compressedfp = gzopen(path, mode);
+ char mode_compression[32];
+
+ snprintf(mode_compression, sizeof(mode_compression), "%s%d",
+ mode, compression);
+ fp->compressedfp = gzopen(path, mode_compression);
fp->uncompressedfp = NULL;
if (fp->compressedfp == NULL)
{
- free(fp);
+ free_keep_errno(fp);
fp = NULL;
}
#else
fp->uncompressedfp = fopen(path, mode);
if (fp->uncompressedfp == NULL)
{
- free(fp);
+ free_keep_errno(fp);
fp = NULL;
}
}
result = fclose(fp->uncompressedfp);
fp->uncompressedfp = NULL;
}
- free(fp);
+ free_keep_errno(fp);
return result;
}