extern void exit OF((int));
#endif
+#ifdef USE_MMAP
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+#endif
#if defined(MSDOS) || defined(OS2) || defined(WIN32)
# include <fcntl.h>
# define GZ_SUFFIX "-gz"
# define fileno(file) file->__file
#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fileno */
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+ extern int unlink OF((const char *));
+#endif
#ifndef GZ_SUFFIX
# define GZ_SUFFIX ".gz"
#endif
#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
-extern int unlink OF((const char *));
-
-#define BUFLEN 4096
+#define BUFLEN 16384
#define MAX_NAME_LEN 1024
#ifdef MAXSEG_64K
char *prog;
-void error OF((const char *msg));
-void gz_compress OF((FILE *in, gzFile out));
-void gz_uncompress OF((gzFile in, FILE *out));
-void file_compress OF((char *file));
-void file_uncompress OF((char *file));
-int main OF((int argc, char *argv[]));
+void error OF((const char *msg));
+void gz_compress OF((FILE *in, gzFile out));
+#ifdef USE_MMAP
+int gz_compress_mmap OF((FILE *in, gzFile out));
+#endif
+void gz_uncompress OF((gzFile in, FILE *out));
+void file_compress OF((char *file, char *mode));
+void file_uncompress OF((char *file));
+int main OF((int argc, char *argv[]));
/* ===========================================================================
* Display error message and exit
/* ===========================================================================
* Compress input to output then close both files.
*/
+
void gz_compress(in, out)
FILE *in;
gzFile out;
int len;
int err;
+#ifdef USE_MMAP
+ /* Try first compressing with mmap. If mmap fails (minigzip used in a
+ * pipe), use the normal fread loop.
+ */
+ if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
for (;;) {
len = fread(buf, 1, sizeof(buf), in);
if (ferror(in)) {
if (gzclose(out) != Z_OK) error("failed gzclose");
}
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+ FILE *in;
+ gzFile out;
+{
+ int len;
+ int err;
+ int ifd = fileno(in);
+ caddr_t buf; /* mmap'ed buffer for the entire input file */
+ off_t buf_len; /* length of the input file */
+ struct stat sb;
+
+ /* Determine the size of the file, needed for mmap: */
+ if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+ buf_len = sb.st_size;
+ if (buf_len <= 0) return Z_ERRNO;
+
+ /* Now do the actual mmap: */
+ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+ if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+ /* Compress the whole file at once: */
+ len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+ if (len != (int)buf_len) error(gzerror(out, &err));
+
+ munmap(buf, buf_len);
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+ return Z_OK;
+}
+#endif /* USE_MMAP */
+
/* ===========================================================================
* Uncompress input to output then close both files.
*/
* Compress the given file: create a corresponding .gz file and remove the
* original.
*/
-void file_compress(file)
+void file_compress(file, mode)
char *file;
+ char *mode;
{
local char outfile[MAX_NAME_LEN];
FILE *in;
perror(file);
exit(1);
}
- out = gzopen(outfile, "wb"); /* use "wb9" for maximal compression */
+ out = gzopen(outfile, mode);
if (out == NULL) {
fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
exit(1);
if (uncompr) {
file_uncompress(*argv);
} else {
- file_compress(*argv);
+ file_compress(*argv, outmode);
}
} while (argv++, --argc);
}