annotate src/zlib-1.2.7/gzwrite.c @ 83:ae30d91d2ffe

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