modules/zlib/src/gzwrite.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* gzwrite.c -- zlib functions for writing gzip files
michael@0 2 * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
michael@0 3 * For conditions of distribution and use, see copyright notice in zlib.h
michael@0 4 */
michael@0 5
michael@0 6 #include "gzguts.h"
michael@0 7
michael@0 8 /* Local functions */
michael@0 9 local int gz_init OF((gz_statep));
michael@0 10 local int gz_comp OF((gz_statep, int));
michael@0 11 local int gz_zero OF((gz_statep, z_off64_t));
michael@0 12
michael@0 13 /* Initialize state for writing a gzip file. Mark initialization by setting
michael@0 14 state->size to non-zero. Return -1 on failure or 0 on success. */
michael@0 15 local int gz_init(state)
michael@0 16 gz_statep state;
michael@0 17 {
michael@0 18 int ret;
michael@0 19 z_streamp strm = &(state->strm);
michael@0 20
michael@0 21 /* allocate input buffer */
michael@0 22 state->in = (unsigned char *)malloc(state->want);
michael@0 23 if (state->in == NULL) {
michael@0 24 gz_error(state, Z_MEM_ERROR, "out of memory");
michael@0 25 return -1;
michael@0 26 }
michael@0 27
michael@0 28 /* only need output buffer and deflate state if compressing */
michael@0 29 if (!state->direct) {
michael@0 30 /* allocate output buffer */
michael@0 31 state->out = (unsigned char *)malloc(state->want);
michael@0 32 if (state->out == NULL) {
michael@0 33 free(state->in);
michael@0 34 gz_error(state, Z_MEM_ERROR, "out of memory");
michael@0 35 return -1;
michael@0 36 }
michael@0 37
michael@0 38 /* allocate deflate memory, set up for gzip compression */
michael@0 39 strm->zalloc = Z_NULL;
michael@0 40 strm->zfree = Z_NULL;
michael@0 41 strm->opaque = Z_NULL;
michael@0 42 ret = deflateInit2(strm, state->level, Z_DEFLATED,
michael@0 43 MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
michael@0 44 if (ret != Z_OK) {
michael@0 45 free(state->out);
michael@0 46 free(state->in);
michael@0 47 gz_error(state, Z_MEM_ERROR, "out of memory");
michael@0 48 return -1;
michael@0 49 }
michael@0 50 }
michael@0 51
michael@0 52 /* mark state as initialized */
michael@0 53 state->size = state->want;
michael@0 54
michael@0 55 /* initialize write buffer if compressing */
michael@0 56 if (!state->direct) {
michael@0 57 strm->avail_out = state->size;
michael@0 58 strm->next_out = state->out;
michael@0 59 state->x.next = strm->next_out;
michael@0 60 }
michael@0 61 return 0;
michael@0 62 }
michael@0 63
michael@0 64 /* Compress whatever is at avail_in and next_in and write to the output file.
michael@0 65 Return -1 if there is an error writing to the output file, otherwise 0.
michael@0 66 flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
michael@0 67 then the deflate() state is reset to start a new gzip stream. If gz->direct
michael@0 68 is true, then simply write to the output file without compressing, and
michael@0 69 ignore flush. */
michael@0 70 local int gz_comp(state, flush)
michael@0 71 gz_statep state;
michael@0 72 int flush;
michael@0 73 {
michael@0 74 int ret, got;
michael@0 75 unsigned have;
michael@0 76 z_streamp strm = &(state->strm);
michael@0 77
michael@0 78 /* allocate memory if this is the first time through */
michael@0 79 if (state->size == 0 && gz_init(state) == -1)
michael@0 80 return -1;
michael@0 81
michael@0 82 /* write directly if requested */
michael@0 83 if (state->direct) {
michael@0 84 got = write(state->fd, strm->next_in, strm->avail_in);
michael@0 85 if (got < 0 || (unsigned)got != strm->avail_in) {
michael@0 86 gz_error(state, Z_ERRNO, zstrerror());
michael@0 87 return -1;
michael@0 88 }
michael@0 89 strm->avail_in = 0;
michael@0 90 return 0;
michael@0 91 }
michael@0 92
michael@0 93 /* run deflate() on provided input until it produces no more output */
michael@0 94 ret = Z_OK;
michael@0 95 do {
michael@0 96 /* write out current buffer contents if full, or if flushing, but if
michael@0 97 doing Z_FINISH then don't write until we get to Z_STREAM_END */
michael@0 98 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
michael@0 99 (flush != Z_FINISH || ret == Z_STREAM_END))) {
michael@0 100 have = (unsigned)(strm->next_out - state->x.next);
michael@0 101 if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
michael@0 102 (unsigned)got != have)) {
michael@0 103 gz_error(state, Z_ERRNO, zstrerror());
michael@0 104 return -1;
michael@0 105 }
michael@0 106 if (strm->avail_out == 0) {
michael@0 107 strm->avail_out = state->size;
michael@0 108 strm->next_out = state->out;
michael@0 109 }
michael@0 110 state->x.next = strm->next_out;
michael@0 111 }
michael@0 112
michael@0 113 /* compress */
michael@0 114 have = strm->avail_out;
michael@0 115 ret = deflate(strm, flush);
michael@0 116 if (ret == Z_STREAM_ERROR) {
michael@0 117 gz_error(state, Z_STREAM_ERROR,
michael@0 118 "internal error: deflate stream corrupt");
michael@0 119 return -1;
michael@0 120 }
michael@0 121 have -= strm->avail_out;
michael@0 122 } while (have);
michael@0 123
michael@0 124 /* if that completed a deflate stream, allow another to start */
michael@0 125 if (flush == Z_FINISH)
michael@0 126 deflateReset(strm);
michael@0 127
michael@0 128 /* all done, no errors */
michael@0 129 return 0;
michael@0 130 }
michael@0 131
michael@0 132 /* Compress len zeros to output. Return -1 on error, 0 on success. */
michael@0 133 local int gz_zero(state, len)
michael@0 134 gz_statep state;
michael@0 135 z_off64_t len;
michael@0 136 {
michael@0 137 int first;
michael@0 138 unsigned n;
michael@0 139 z_streamp strm = &(state->strm);
michael@0 140
michael@0 141 /* consume whatever's left in the input buffer */
michael@0 142 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 143 return -1;
michael@0 144
michael@0 145 /* compress len zeros (len guaranteed > 0) */
michael@0 146 first = 1;
michael@0 147 while (len) {
michael@0 148 n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
michael@0 149 (unsigned)len : state->size;
michael@0 150 if (first) {
michael@0 151 memset(state->in, 0, n);
michael@0 152 first = 0;
michael@0 153 }
michael@0 154 strm->avail_in = n;
michael@0 155 strm->next_in = state->in;
michael@0 156 state->x.pos += n;
michael@0 157 if (gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 158 return -1;
michael@0 159 len -= n;
michael@0 160 }
michael@0 161 return 0;
michael@0 162 }
michael@0 163
michael@0 164 /* -- see zlib.h -- */
michael@0 165 int ZEXPORT gzwrite(file, buf, len)
michael@0 166 gzFile file;
michael@0 167 voidpc buf;
michael@0 168 unsigned len;
michael@0 169 {
michael@0 170 unsigned put = len;
michael@0 171 gz_statep state;
michael@0 172 z_streamp strm;
michael@0 173
michael@0 174 /* get internal structure */
michael@0 175 if (file == NULL)
michael@0 176 return 0;
michael@0 177 state = (gz_statep)file;
michael@0 178 strm = &(state->strm);
michael@0 179
michael@0 180 /* check that we're writing and that there's no error */
michael@0 181 if (state->mode != GZ_WRITE || state->err != Z_OK)
michael@0 182 return 0;
michael@0 183
michael@0 184 /* since an int is returned, make sure len fits in one, otherwise return
michael@0 185 with an error (this avoids the flaw in the interface) */
michael@0 186 if ((int)len < 0) {
michael@0 187 gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
michael@0 188 return 0;
michael@0 189 }
michael@0 190
michael@0 191 /* if len is zero, avoid unnecessary operations */
michael@0 192 if (len == 0)
michael@0 193 return 0;
michael@0 194
michael@0 195 /* allocate memory if this is the first time through */
michael@0 196 if (state->size == 0 && gz_init(state) == -1)
michael@0 197 return 0;
michael@0 198
michael@0 199 /* check for seek request */
michael@0 200 if (state->seek) {
michael@0 201 state->seek = 0;
michael@0 202 if (gz_zero(state, state->skip) == -1)
michael@0 203 return 0;
michael@0 204 }
michael@0 205
michael@0 206 /* for small len, copy to input buffer, otherwise compress directly */
michael@0 207 if (len < state->size) {
michael@0 208 /* copy to input buffer, compress when full */
michael@0 209 do {
michael@0 210 unsigned have, copy;
michael@0 211
michael@0 212 if (strm->avail_in == 0)
michael@0 213 strm->next_in = state->in;
michael@0 214 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
michael@0 215 copy = state->size - have;
michael@0 216 if (copy > len)
michael@0 217 copy = len;
michael@0 218 memcpy(state->in + have, buf, copy);
michael@0 219 strm->avail_in += copy;
michael@0 220 state->x.pos += copy;
michael@0 221 buf = (const char *)buf + copy;
michael@0 222 len -= copy;
michael@0 223 if (len && gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 224 return 0;
michael@0 225 } while (len);
michael@0 226 }
michael@0 227 else {
michael@0 228 /* consume whatever's left in the input buffer */
michael@0 229 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 230 return 0;
michael@0 231
michael@0 232 /* directly compress user buffer to file */
michael@0 233 strm->avail_in = len;
michael@0 234 strm->next_in = (z_const Bytef *)buf;
michael@0 235 state->x.pos += len;
michael@0 236 if (gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 237 return 0;
michael@0 238 }
michael@0 239
michael@0 240 /* input was all buffered or compressed (put will fit in int) */
michael@0 241 return (int)put;
michael@0 242 }
michael@0 243
michael@0 244 /* -- see zlib.h -- */
michael@0 245 int ZEXPORT gzputc(file, c)
michael@0 246 gzFile file;
michael@0 247 int c;
michael@0 248 {
michael@0 249 unsigned have;
michael@0 250 unsigned char buf[1];
michael@0 251 gz_statep state;
michael@0 252 z_streamp strm;
michael@0 253
michael@0 254 /* get internal structure */
michael@0 255 if (file == NULL)
michael@0 256 return -1;
michael@0 257 state = (gz_statep)file;
michael@0 258 strm = &(state->strm);
michael@0 259
michael@0 260 /* check that we're writing and that there's no error */
michael@0 261 if (state->mode != GZ_WRITE || state->err != Z_OK)
michael@0 262 return -1;
michael@0 263
michael@0 264 /* check for seek request */
michael@0 265 if (state->seek) {
michael@0 266 state->seek = 0;
michael@0 267 if (gz_zero(state, state->skip) == -1)
michael@0 268 return -1;
michael@0 269 }
michael@0 270
michael@0 271 /* try writing to input buffer for speed (state->size == 0 if buffer not
michael@0 272 initialized) */
michael@0 273 if (state->size) {
michael@0 274 if (strm->avail_in == 0)
michael@0 275 strm->next_in = state->in;
michael@0 276 have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
michael@0 277 if (have < state->size) {
michael@0 278 state->in[have] = c;
michael@0 279 strm->avail_in++;
michael@0 280 state->x.pos++;
michael@0 281 return c & 0xff;
michael@0 282 }
michael@0 283 }
michael@0 284
michael@0 285 /* no room in buffer or not initialized, use gz_write() */
michael@0 286 buf[0] = c;
michael@0 287 if (gzwrite(file, buf, 1) != 1)
michael@0 288 return -1;
michael@0 289 return c & 0xff;
michael@0 290 }
michael@0 291
michael@0 292 /* -- see zlib.h -- */
michael@0 293 int ZEXPORT gzputs(file, str)
michael@0 294 gzFile file;
michael@0 295 const char *str;
michael@0 296 {
michael@0 297 int ret;
michael@0 298 unsigned len;
michael@0 299
michael@0 300 /* write string */
michael@0 301 len = (unsigned)strlen(str);
michael@0 302 ret = gzwrite(file, str, len);
michael@0 303 return ret == 0 && len != 0 ? -1 : ret;
michael@0 304 }
michael@0 305
michael@0 306 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
michael@0 307 #include <stdarg.h>
michael@0 308
michael@0 309 /* -- see zlib.h -- */
michael@0 310 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
michael@0 311 {
michael@0 312 int size, len;
michael@0 313 gz_statep state;
michael@0 314 z_streamp strm;
michael@0 315
michael@0 316 /* get internal structure */
michael@0 317 if (file == NULL)
michael@0 318 return -1;
michael@0 319 state = (gz_statep)file;
michael@0 320 strm = &(state->strm);
michael@0 321
michael@0 322 /* check that we're writing and that there's no error */
michael@0 323 if (state->mode != GZ_WRITE || state->err != Z_OK)
michael@0 324 return 0;
michael@0 325
michael@0 326 /* make sure we have some buffer space */
michael@0 327 if (state->size == 0 && gz_init(state) == -1)
michael@0 328 return 0;
michael@0 329
michael@0 330 /* check for seek request */
michael@0 331 if (state->seek) {
michael@0 332 state->seek = 0;
michael@0 333 if (gz_zero(state, state->skip) == -1)
michael@0 334 return 0;
michael@0 335 }
michael@0 336
michael@0 337 /* consume whatever's left in the input buffer */
michael@0 338 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 339 return 0;
michael@0 340
michael@0 341 /* do the printf() into the input buffer, put length in len */
michael@0 342 size = (int)(state->size);
michael@0 343 state->in[size - 1] = 0;
michael@0 344 #ifdef NO_vsnprintf
michael@0 345 # ifdef HAS_vsprintf_void
michael@0 346 (void)vsprintf((char *)(state->in), format, va);
michael@0 347 for (len = 0; len < size; len++)
michael@0 348 if (state->in[len] == 0) break;
michael@0 349 # else
michael@0 350 len = vsprintf((char *)(state->in), format, va);
michael@0 351 # endif
michael@0 352 #else
michael@0 353 # ifdef HAS_vsnprintf_void
michael@0 354 (void)vsnprintf((char *)(state->in), size, format, va);
michael@0 355 len = strlen((char *)(state->in));
michael@0 356 # else
michael@0 357 len = vsnprintf((char *)(state->in), size, format, va);
michael@0 358 # endif
michael@0 359 #endif
michael@0 360
michael@0 361 /* check that printf() results fit in buffer */
michael@0 362 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
michael@0 363 return 0;
michael@0 364
michael@0 365 /* update buffer and position, defer compression until needed */
michael@0 366 strm->avail_in = (unsigned)len;
michael@0 367 strm->next_in = state->in;
michael@0 368 state->x.pos += len;
michael@0 369 return len;
michael@0 370 }
michael@0 371
michael@0 372 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
michael@0 373 {
michael@0 374 va_list va;
michael@0 375 int ret;
michael@0 376
michael@0 377 va_start(va, format);
michael@0 378 ret = gzvprintf(file, format, va);
michael@0 379 va_end(va);
michael@0 380 return ret;
michael@0 381 }
michael@0 382
michael@0 383 #else /* !STDC && !Z_HAVE_STDARG_H */
michael@0 384
michael@0 385 /* -- see zlib.h -- */
michael@0 386 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
michael@0 387 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
michael@0 388 gzFile file;
michael@0 389 const char *format;
michael@0 390 int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
michael@0 391 a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
michael@0 392 {
michael@0 393 int size, len;
michael@0 394 gz_statep state;
michael@0 395 z_streamp strm;
michael@0 396
michael@0 397 /* get internal structure */
michael@0 398 if (file == NULL)
michael@0 399 return -1;
michael@0 400 state = (gz_statep)file;
michael@0 401 strm = &(state->strm);
michael@0 402
michael@0 403 /* check that can really pass pointer in ints */
michael@0 404 if (sizeof(int) != sizeof(void *))
michael@0 405 return 0;
michael@0 406
michael@0 407 /* check that we're writing and that there's no error */
michael@0 408 if (state->mode != GZ_WRITE || state->err != Z_OK)
michael@0 409 return 0;
michael@0 410
michael@0 411 /* make sure we have some buffer space */
michael@0 412 if (state->size == 0 && gz_init(state) == -1)
michael@0 413 return 0;
michael@0 414
michael@0 415 /* check for seek request */
michael@0 416 if (state->seek) {
michael@0 417 state->seek = 0;
michael@0 418 if (gz_zero(state, state->skip) == -1)
michael@0 419 return 0;
michael@0 420 }
michael@0 421
michael@0 422 /* consume whatever's left in the input buffer */
michael@0 423 if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
michael@0 424 return 0;
michael@0 425
michael@0 426 /* do the printf() into the input buffer, put length in len */
michael@0 427 size = (int)(state->size);
michael@0 428 state->in[size - 1] = 0;
michael@0 429 #ifdef NO_snprintf
michael@0 430 # ifdef HAS_sprintf_void
michael@0 431 sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
michael@0 432 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
michael@0 433 for (len = 0; len < size; len++)
michael@0 434 if (state->in[len] == 0) break;
michael@0 435 # else
michael@0 436 len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
michael@0 437 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
michael@0 438 # endif
michael@0 439 #else
michael@0 440 # ifdef HAS_snprintf_void
michael@0 441 snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
michael@0 442 a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
michael@0 443 len = strlen((char *)(state->in));
michael@0 444 # else
michael@0 445 len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
michael@0 446 a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
michael@0 447 a19, a20);
michael@0 448 # endif
michael@0 449 #endif
michael@0 450
michael@0 451 /* check that printf() results fit in buffer */
michael@0 452 if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
michael@0 453 return 0;
michael@0 454
michael@0 455 /* update buffer and position, defer compression until needed */
michael@0 456 strm->avail_in = (unsigned)len;
michael@0 457 strm->next_in = state->in;
michael@0 458 state->x.pos += len;
michael@0 459 return len;
michael@0 460 }
michael@0 461
michael@0 462 #endif
michael@0 463
michael@0 464 /* -- see zlib.h -- */
michael@0 465 int ZEXPORT gzflush(file, flush)
michael@0 466 gzFile file;
michael@0 467 int flush;
michael@0 468 {
michael@0 469 gz_statep state;
michael@0 470
michael@0 471 /* get internal structure */
michael@0 472 if (file == NULL)
michael@0 473 return -1;
michael@0 474 state = (gz_statep)file;
michael@0 475
michael@0 476 /* check that we're writing and that there's no error */
michael@0 477 if (state->mode != GZ_WRITE || state->err != Z_OK)
michael@0 478 return Z_STREAM_ERROR;
michael@0 479
michael@0 480 /* check flush parameter */
michael@0 481 if (flush < 0 || flush > Z_FINISH)
michael@0 482 return Z_STREAM_ERROR;
michael@0 483
michael@0 484 /* check for seek request */
michael@0 485 if (state->seek) {
michael@0 486 state->seek = 0;
michael@0 487 if (gz_zero(state, state->skip) == -1)
michael@0 488 return -1;
michael@0 489 }
michael@0 490
michael@0 491 /* compress remaining data with requested flush */
michael@0 492 gz_comp(state, flush);
michael@0 493 return state->err;
michael@0 494 }
michael@0 495
michael@0 496 /* -- see zlib.h -- */
michael@0 497 int ZEXPORT gzsetparams(file, level, strategy)
michael@0 498 gzFile file;
michael@0 499 int level;
michael@0 500 int strategy;
michael@0 501 {
michael@0 502 gz_statep state;
michael@0 503 z_streamp strm;
michael@0 504
michael@0 505 /* get internal structure */
michael@0 506 if (file == NULL)
michael@0 507 return Z_STREAM_ERROR;
michael@0 508 state = (gz_statep)file;
michael@0 509 strm = &(state->strm);
michael@0 510
michael@0 511 /* check that we're writing and that there's no error */
michael@0 512 if (state->mode != GZ_WRITE || state->err != Z_OK)
michael@0 513 return Z_STREAM_ERROR;
michael@0 514
michael@0 515 /* if no change is requested, then do nothing */
michael@0 516 if (level == state->level && strategy == state->strategy)
michael@0 517 return Z_OK;
michael@0 518
michael@0 519 /* check for seek request */
michael@0 520 if (state->seek) {
michael@0 521 state->seek = 0;
michael@0 522 if (gz_zero(state, state->skip) == -1)
michael@0 523 return -1;
michael@0 524 }
michael@0 525
michael@0 526 /* change compression parameters for subsequent input */
michael@0 527 if (state->size) {
michael@0 528 /* flush previous input with previous parameters before changing */
michael@0 529 if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
michael@0 530 return state->err;
michael@0 531 deflateParams(strm, level, strategy);
michael@0 532 }
michael@0 533 state->level = level;
michael@0 534 state->strategy = strategy;
michael@0 535 return Z_OK;
michael@0 536 }
michael@0 537
michael@0 538 /* -- see zlib.h -- */
michael@0 539 int ZEXPORT gzclose_w(file)
michael@0 540 gzFile file;
michael@0 541 {
michael@0 542 int ret = Z_OK;
michael@0 543 gz_statep state;
michael@0 544
michael@0 545 /* get internal structure */
michael@0 546 if (file == NULL)
michael@0 547 return Z_STREAM_ERROR;
michael@0 548 state = (gz_statep)file;
michael@0 549
michael@0 550 /* check that we're writing */
michael@0 551 if (state->mode != GZ_WRITE)
michael@0 552 return Z_STREAM_ERROR;
michael@0 553
michael@0 554 /* check for seek request */
michael@0 555 if (state->seek) {
michael@0 556 state->seek = 0;
michael@0 557 if (gz_zero(state, state->skip) == -1)
michael@0 558 ret = state->err;
michael@0 559 }
michael@0 560
michael@0 561 /* flush, free memory, and close file */
michael@0 562 if (gz_comp(state, Z_FINISH) == -1)
michael@0 563 ret = state->err;
michael@0 564 if (state->size) {
michael@0 565 if (!state->direct) {
michael@0 566 (void)deflateEnd(&(state->strm));
michael@0 567 free(state->out);
michael@0 568 }
michael@0 569 free(state->in);
michael@0 570 }
michael@0 571 gz_error(state, Z_OK, NULL);
michael@0 572 free(state->path);
michael@0 573 if (close(state->fd) == -1)
michael@0 574 ret = Z_ERRNO;
michael@0 575 free(state);
michael@0 576 return ret;
michael@0 577 }

mercurial