diff options
Diffstat (limited to 'minigzip.c')
-rw-r--r-- | minigzip.c | 66 |
1 files changed, 59 insertions, 7 deletions
@@ -25,6 +25,11 @@ | |||
25 | extern void exit OF((int)); | 25 | extern void exit OF((int)); |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #ifdef USE_MMAP | ||
29 | # include <sys/types.h> | ||
30 | # include <sys/mman.h> | ||
31 | # include <sys/stat.h> | ||
32 | #endif | ||
28 | 33 | ||
29 | #if defined(MSDOS) || defined(OS2) || defined(WIN32) | 34 | #if defined(MSDOS) || defined(OS2) || defined(WIN32) |
30 | # include <fcntl.h> | 35 | # include <fcntl.h> |
@@ -53,7 +58,7 @@ | |||
53 | #endif | 58 | #endif |
54 | #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) | 59 | #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) |
55 | 60 | ||
56 | #define BUFLEN 4096 | 61 | #define BUFLEN 16384 |
57 | #define MAX_NAME_LEN 1024 | 62 | #define MAX_NAME_LEN 1024 |
58 | 63 | ||
59 | #ifdef MAXSEG_64K | 64 | #ifdef MAXSEG_64K |
@@ -65,12 +70,15 @@ | |||
65 | 70 | ||
66 | char *prog; | 71 | char *prog; |
67 | 72 | ||
68 | void error OF((const char *msg)); | 73 | void error OF((const char *msg)); |
69 | void gz_compress OF((FILE *in, gzFile out)); | 74 | void gz_compress OF((FILE *in, gzFile out)); |
70 | void gz_uncompress OF((gzFile in, FILE *out)); | 75 | #ifdef USE_MMAP |
71 | void file_compress OF((char *file, char *mode)); | 76 | int gz_compress_mmap OF((FILE *in, gzFile out)); |
72 | void file_uncompress OF((char *file)); | 77 | #endif |
73 | int main OF((int argc, char *argv[])); | 78 | void gz_uncompress OF((gzFile in, FILE *out)); |
79 | void file_compress OF((char *file, char *mode)); | ||
80 | void file_uncompress OF((char *file)); | ||
81 | int main OF((int argc, char *argv[])); | ||
74 | 82 | ||
75 | /* =========================================================================== | 83 | /* =========================================================================== |
76 | * Display error message and exit | 84 | * Display error message and exit |
@@ -85,6 +93,7 @@ void error(msg) | |||
85 | /* =========================================================================== | 93 | /* =========================================================================== |
86 | * Compress input to output then close both files. | 94 | * Compress input to output then close both files. |
87 | */ | 95 | */ |
96 | |||
88 | void gz_compress(in, out) | 97 | void gz_compress(in, out) |
89 | FILE *in; | 98 | FILE *in; |
90 | gzFile out; | 99 | gzFile out; |
@@ -93,6 +102,12 @@ void gz_compress(in, out) | |||
93 | int len; | 102 | int len; |
94 | int err; | 103 | int err; |
95 | 104 | ||
105 | #ifdef USE_MMAP | ||
106 | /* Try first compressing with mmap. If mmap fails (minigzip used in a | ||
107 | * pipe), use the normal fread loop. | ||
108 | */ | ||
109 | if (gz_compress_mmap(in, out) == Z_OK) return; | ||
110 | #endif | ||
96 | for (;;) { | 111 | for (;;) { |
97 | len = fread(buf, 1, sizeof(buf), in); | 112 | len = fread(buf, 1, sizeof(buf), in); |
98 | if (ferror(in)) { | 113 | if (ferror(in)) { |
@@ -107,6 +122,43 @@ void gz_compress(in, out) | |||
107 | if (gzclose(out) != Z_OK) error("failed gzclose"); | 122 | if (gzclose(out) != Z_OK) error("failed gzclose"); |
108 | } | 123 | } |
109 | 124 | ||
125 | #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */ | ||
126 | |||
127 | /* Try compressing the input file at once using mmap. Return Z_OK if | ||
128 | * if success, Z_ERRNO otherwise. | ||
129 | */ | ||
130 | int gz_compress_mmap(in, out) | ||
131 | FILE *in; | ||
132 | gzFile out; | ||
133 | { | ||
134 | int len; | ||
135 | int err; | ||
136 | int ifd = fileno(in); | ||
137 | caddr_t buf; /* mmap'ed buffer for the entire input file */ | ||
138 | off_t buf_len; /* length of the input file */ | ||
139 | struct stat sb; | ||
140 | |||
141 | /* Determine the size of the file, needed for mmap: */ | ||
142 | if (fstat(ifd, &sb) < 0) return Z_ERRNO; | ||
143 | buf_len = sb.st_size; | ||
144 | if (buf_len <= 0) return Z_ERRNO; | ||
145 | |||
146 | /* Now do the actual mmap: */ | ||
147 | buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); | ||
148 | if (buf == (caddr_t)(-1)) return Z_ERRNO; | ||
149 | |||
150 | /* Compress the whole file at once: */ | ||
151 | len = gzwrite(out, (char *)buf, (unsigned)buf_len); | ||
152 | |||
153 | if (len != (int)buf_len) error(gzerror(out, &err)); | ||
154 | |||
155 | munmap(buf, buf_len); | ||
156 | fclose(in); | ||
157 | if (gzclose(out) != Z_OK) error("failed gzclose"); | ||
158 | return Z_OK; | ||
159 | } | ||
160 | #endif /* USE_MMAP */ | ||
161 | |||
110 | /* =========================================================================== | 162 | /* =========================================================================== |
111 | * Uncompress input to output then close both files. | 163 | * Uncompress input to output then close both files. |
112 | */ | 164 | */ |