gzwrite.c revision 205305
1205194Sdelphij/* gzwrite.c -- zlib functions for writing gzip files 2205194Sdelphij * Copyright (C) 2004, 2005, 2010 Mark Adler 3205194Sdelphij * For conditions of distribution and use, see copyright notice in zlib.h 4205194Sdelphij */ 5205194Sdelphij 6205194Sdelphij#include "gzguts.h" 7205305Sdelphij#include <unistd.h> 8205194Sdelphij 9205194Sdelphij/* Local functions */ 10205194Sdelphijlocal int gz_init OF((gz_statep)); 11205194Sdelphijlocal int gz_comp OF((gz_statep, int)); 12205194Sdelphijlocal int gz_zero OF((gz_statep, z_off64_t)); 13205194Sdelphij 14205194Sdelphij/* Initialize state for writing a gzip file. Mark initialization by setting 15205194Sdelphij state->size to non-zero. Return -1 on failure or 0 on success. */ 16205194Sdelphijlocal int gz_init(state) 17205194Sdelphij gz_statep state; 18205194Sdelphij{ 19205194Sdelphij int ret; 20205194Sdelphij z_streamp strm = &(state->strm); 21205194Sdelphij 22205194Sdelphij /* allocate input and output buffers */ 23205194Sdelphij state->in = malloc(state->want); 24205194Sdelphij state->out = malloc(state->want); 25205194Sdelphij if (state->in == NULL || state->out == NULL) { 26205194Sdelphij if (state->out != NULL) 27205194Sdelphij free(state->out); 28205194Sdelphij if (state->in != NULL) 29205194Sdelphij free(state->in); 30205194Sdelphij gz_error(state, Z_MEM_ERROR, "out of memory"); 31205194Sdelphij return -1; 32205194Sdelphij } 33205194Sdelphij 34205194Sdelphij /* allocate deflate memory, set up for gzip compression */ 35205194Sdelphij strm->zalloc = Z_NULL; 36205194Sdelphij strm->zfree = Z_NULL; 37205194Sdelphij strm->opaque = Z_NULL; 38205194Sdelphij ret = deflateInit2(strm, state->level, Z_DEFLATED, 39205194Sdelphij 15 + 16, 8, state->strategy); 40205194Sdelphij if (ret != Z_OK) { 41205194Sdelphij free(state->in); 42205194Sdelphij gz_error(state, Z_MEM_ERROR, "out of memory"); 43205194Sdelphij return -1; 44205194Sdelphij } 45205194Sdelphij 46205194Sdelphij /* mark state as initialized */ 47205194Sdelphij state->size = state->want; 48205194Sdelphij 49205194Sdelphij /* initialize write buffer */ 50205194Sdelphij strm->avail_out = state->size; 51205194Sdelphij strm->next_out = state->out; 52205194Sdelphij state->next = strm->next_out; 53205194Sdelphij return 0; 54205194Sdelphij} 55205194Sdelphij 56205194Sdelphij/* Compress whatever is at avail_in and next_in and write to the output file. 57205194Sdelphij Return -1 if there is an error writing to the output file, otherwise 0. 58205194Sdelphij flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, 59205194Sdelphij then the deflate() state is reset to start a new gzip stream. */ 60205194Sdelphijlocal int gz_comp(state, flush) 61205194Sdelphij gz_statep state; 62205194Sdelphij int flush; 63205194Sdelphij{ 64205194Sdelphij int ret, got; 65205194Sdelphij unsigned have; 66205194Sdelphij z_streamp strm = &(state->strm); 67205194Sdelphij 68205194Sdelphij /* allocate memory if this is the first time through */ 69205194Sdelphij if (state->size == 0 && gz_init(state) == -1) 70205194Sdelphij return -1; 71205194Sdelphij 72205194Sdelphij /* run deflate() on provided input until it produces no more output */ 73205194Sdelphij ret = Z_OK; 74205194Sdelphij do { 75205194Sdelphij /* write out current buffer contents if full, or if flushing, but if 76205194Sdelphij doing Z_FINISH then don't write until we get to Z_STREAM_END */ 77205194Sdelphij if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && 78205194Sdelphij (flush != Z_FINISH || ret == Z_STREAM_END))) { 79205194Sdelphij have = (unsigned)(strm->next_out - state->next); 80205194Sdelphij if (have && ((got = write(state->fd, state->next, have)) < 0 || 81205194Sdelphij (unsigned)got != have)) { 82205194Sdelphij gz_error(state, Z_ERRNO, zstrerror()); 83205194Sdelphij return -1; 84205194Sdelphij } 85205194Sdelphij if (strm->avail_out == 0) { 86205194Sdelphij strm->avail_out = state->size; 87205194Sdelphij strm->next_out = state->out; 88205194Sdelphij } 89205194Sdelphij state->next = strm->next_out; 90205194Sdelphij } 91205194Sdelphij 92205194Sdelphij /* compress */ 93205194Sdelphij have = strm->avail_out; 94205194Sdelphij ret = deflate(strm, flush); 95205194Sdelphij if (ret == Z_STREAM_ERROR) { 96205194Sdelphij gz_error(state, Z_STREAM_ERROR, 97205194Sdelphij "internal error: deflate stream corrupt"); 98205194Sdelphij return -1; 99205194Sdelphij } 100205194Sdelphij have -= strm->avail_out; 101205194Sdelphij } while (have); 102205194Sdelphij 103205194Sdelphij /* if that completed a deflate stream, allow another to start */ 104205194Sdelphij if (flush == Z_FINISH) 105205194Sdelphij deflateReset(strm); 106205194Sdelphij 107205194Sdelphij /* all done, no errors */ 108205194Sdelphij return 0; 109205194Sdelphij} 110205194Sdelphij 111205194Sdelphij/* Compress len zeros to output. Return -1 on error, 0 on success. */ 112205194Sdelphijlocal int gz_zero(state, len) 113205194Sdelphij gz_statep state; 114205194Sdelphij z_off64_t len; 115205194Sdelphij{ 116205194Sdelphij int first; 117205194Sdelphij unsigned n; 118205194Sdelphij z_streamp strm = &(state->strm); 119205194Sdelphij 120205194Sdelphij /* consume whatever's left in the input buffer */ 121205194Sdelphij if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 122205194Sdelphij return -1; 123205194Sdelphij 124205194Sdelphij /* compress len zeros (len guaranteed > 0) */ 125205194Sdelphij first = 1; 126205194Sdelphij while (len) { 127205194Sdelphij n = GT_OFF(state->size) || (z_off64_t)state->size > len ? 128205194Sdelphij (unsigned)len : state->size; 129205194Sdelphij if (first) { 130205194Sdelphij memset(state->in, 0, n); 131205194Sdelphij first = 0; 132205194Sdelphij } 133205194Sdelphij strm->avail_in = n; 134205194Sdelphij strm->next_in = state->in; 135205194Sdelphij state->pos += n; 136205194Sdelphij if (gz_comp(state, Z_NO_FLUSH) == -1) 137205194Sdelphij return -1; 138205194Sdelphij len -= n; 139205194Sdelphij } 140205194Sdelphij return 0; 141205194Sdelphij} 142205194Sdelphij 143205194Sdelphij/* -- see zlib.h -- */ 144205194Sdelphijint ZEXPORT gzwrite(file, buf, len) 145205194Sdelphij gzFile file; 146205194Sdelphij voidpc buf; 147205194Sdelphij unsigned len; 148205194Sdelphij{ 149205194Sdelphij unsigned put = len; 150205194Sdelphij unsigned n; 151205194Sdelphij gz_statep state; 152205194Sdelphij z_streamp strm; 153205194Sdelphij 154205194Sdelphij /* get internal structure */ 155205194Sdelphij if (file == NULL) 156205194Sdelphij return 0; 157205194Sdelphij state = (gz_statep)file; 158205194Sdelphij strm = &(state->strm); 159205194Sdelphij 160205194Sdelphij /* check that we're writing and that there's no error */ 161205194Sdelphij if (state->mode != GZ_WRITE || state->err != Z_OK) 162205194Sdelphij return 0; 163205194Sdelphij 164205194Sdelphij /* since an int is returned, make sure len fits in one, otherwise return 165205194Sdelphij with an error (this avoids the flaw in the interface) */ 166205194Sdelphij if ((int)len < 0) { 167205194Sdelphij gz_error(state, Z_BUF_ERROR, "requested length does not fit in int"); 168205194Sdelphij return 0; 169205194Sdelphij } 170205194Sdelphij 171205194Sdelphij /* if len is zero, avoid unnecessary operations */ 172205194Sdelphij if (len == 0) 173205194Sdelphij return 0; 174205194Sdelphij 175205194Sdelphij /* allocate memory if this is the first time through */ 176205194Sdelphij if (state->size == 0 && gz_init(state) == -1) 177205194Sdelphij return 0; 178205194Sdelphij 179205194Sdelphij /* check for seek request */ 180205194Sdelphij if (state->seek) { 181205194Sdelphij state->seek = 0; 182205194Sdelphij if (gz_zero(state, state->skip) == -1) 183205194Sdelphij return 0; 184205194Sdelphij } 185205194Sdelphij 186205194Sdelphij /* for small len, copy to input buffer, otherwise compress directly */ 187205194Sdelphij if (len < state->size) { 188205194Sdelphij /* copy to input buffer, compress when full */ 189205194Sdelphij do { 190205194Sdelphij if (strm->avail_in == 0) 191205194Sdelphij strm->next_in = state->in; 192205194Sdelphij n = state->size - strm->avail_in; 193205194Sdelphij if (n > len) 194205194Sdelphij n = len; 195205194Sdelphij memcpy(strm->next_in + strm->avail_in, buf, n); 196205194Sdelphij strm->avail_in += n; 197205194Sdelphij state->pos += n; 198205194Sdelphij buf = (char *)buf + n; 199205194Sdelphij len -= n; 200205194Sdelphij if (len && gz_comp(state, Z_NO_FLUSH) == -1) 201205194Sdelphij return 0; 202205194Sdelphij } while (len); 203205194Sdelphij } 204205194Sdelphij else { 205205194Sdelphij /* consume whatever's left in the input buffer */ 206205194Sdelphij if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 207205194Sdelphij return 0; 208205194Sdelphij 209205194Sdelphij /* directly compress user buffer to file */ 210205194Sdelphij strm->avail_in = len; 211205194Sdelphij strm->next_in = (voidp)buf; 212205194Sdelphij state->pos += len; 213205194Sdelphij if (gz_comp(state, Z_NO_FLUSH) == -1) 214205194Sdelphij return 0; 215205194Sdelphij } 216205194Sdelphij 217205194Sdelphij /* input was all buffered or compressed (put will fit in int) */ 218205194Sdelphij return (int)put; 219205194Sdelphij} 220205194Sdelphij 221205194Sdelphij/* -- see zlib.h -- */ 222205194Sdelphijint ZEXPORT gzputc(file, c) 223205194Sdelphij gzFile file; 224205194Sdelphij int c; 225205194Sdelphij{ 226205194Sdelphij unsigned char buf[1]; 227205194Sdelphij gz_statep state; 228205194Sdelphij z_streamp strm; 229205194Sdelphij 230205194Sdelphij /* get internal structure */ 231205194Sdelphij if (file == NULL) 232205194Sdelphij return -1; 233205194Sdelphij state = (gz_statep)file; 234205194Sdelphij strm = &(state->strm); 235205194Sdelphij 236205194Sdelphij /* check that we're writing and that there's no error */ 237205194Sdelphij if (state->mode != GZ_WRITE || state->err != Z_OK) 238205194Sdelphij return -1; 239205194Sdelphij 240205194Sdelphij /* check for seek request */ 241205194Sdelphij if (state->seek) { 242205194Sdelphij state->seek = 0; 243205194Sdelphij if (gz_zero(state, state->skip) == -1) 244205194Sdelphij return -1; 245205194Sdelphij } 246205194Sdelphij 247205194Sdelphij /* try writing to input buffer for speed (state->size == 0 if buffer not 248205194Sdelphij initialized) */ 249205194Sdelphij if (strm->avail_in < state->size) { 250205194Sdelphij if (strm->avail_in == 0) 251205194Sdelphij strm->next_in = state->in; 252205194Sdelphij strm->next_in[strm->avail_in++] = c; 253205194Sdelphij state->pos++; 254205194Sdelphij return c; 255205194Sdelphij } 256205194Sdelphij 257205194Sdelphij /* no room in buffer or not initialized, use gz_write() */ 258205194Sdelphij buf[0] = c; 259205194Sdelphij if (gzwrite(file, buf, 1) != 1) 260205194Sdelphij return -1; 261205194Sdelphij return c; 262205194Sdelphij} 263205194Sdelphij 264205194Sdelphij/* -- see zlib.h -- */ 265205194Sdelphijint ZEXPORT gzputs(file, str) 266205194Sdelphij gzFile file; 267205194Sdelphij const char *str; 268205194Sdelphij{ 269205194Sdelphij int ret; 270205194Sdelphij unsigned len; 271205194Sdelphij 272205194Sdelphij /* write string */ 273205194Sdelphij len = (unsigned)strlen(str); 274205194Sdelphij ret = gzwrite(file, str, len); 275205194Sdelphij return ret == 0 && len != 0 ? -1 : ret; 276205194Sdelphij} 277205194Sdelphij 278205194Sdelphij#ifdef STDC 279205194Sdelphij#include <stdarg.h> 280205194Sdelphij 281205194Sdelphij/* -- see zlib.h -- */ 282205194Sdelphijint ZEXPORTVA gzprintf (gzFile file, const char *format, ...) 283205194Sdelphij{ 284205194Sdelphij int size, len; 285205194Sdelphij gz_statep state; 286205194Sdelphij z_streamp strm; 287205194Sdelphij va_list va; 288205194Sdelphij 289205194Sdelphij /* get internal structure */ 290205194Sdelphij if (file == NULL) 291205194Sdelphij return -1; 292205194Sdelphij state = (gz_statep)file; 293205194Sdelphij strm = &(state->strm); 294205194Sdelphij 295205194Sdelphij /* check that we're writing and that there's no error */ 296205194Sdelphij if (state->mode != GZ_WRITE || state->err != Z_OK) 297205194Sdelphij return 0; 298205194Sdelphij 299205194Sdelphij /* make sure we have some buffer space */ 300205194Sdelphij if (state->size == 0 && gz_init(state) == -1) 301205194Sdelphij return 0; 302205194Sdelphij 303205194Sdelphij /* check for seek request */ 304205194Sdelphij if (state->seek) { 305205194Sdelphij state->seek = 0; 306205194Sdelphij if (gz_zero(state, state->skip) == -1) 307205194Sdelphij return 0; 308205194Sdelphij } 309205194Sdelphij 310205194Sdelphij /* consume whatever's left in the input buffer */ 311205194Sdelphij if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 312205194Sdelphij return 0; 313205194Sdelphij 314205194Sdelphij /* do the printf() into the input buffer, put length in len */ 315205194Sdelphij size = (int)(state->size); 316205194Sdelphij state->in[size - 1] = 0; 317205194Sdelphij va_start(va, format); 318205194Sdelphij#ifdef NO_vsnprintf 319205194Sdelphij# ifdef HAS_vsprintf_void 320205194Sdelphij (void)vsprintf(state->in, format, va); 321205194Sdelphij va_end(va); 322205194Sdelphij for (len = 0; len < size; len++) 323205194Sdelphij if (state->in[len] == 0) break; 324205194Sdelphij# else 325205194Sdelphij len = vsprintf(state->in, format, va); 326205194Sdelphij va_end(va); 327205194Sdelphij# endif 328205194Sdelphij#else 329205194Sdelphij# ifdef HAS_vsnprintf_void 330205194Sdelphij (void)vsnprintf(state->in, size, format, va); 331205194Sdelphij va_end(va); 332205194Sdelphij len = strlen(state->in); 333205194Sdelphij# else 334205194Sdelphij len = vsnprintf((char *)(state->in), size, format, va); 335205194Sdelphij va_end(va); 336205194Sdelphij# endif 337205194Sdelphij#endif 338205194Sdelphij 339205194Sdelphij /* check that printf() results fit in buffer */ 340205194Sdelphij if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 341205194Sdelphij return 0; 342205194Sdelphij 343205194Sdelphij /* update buffer and position, defer compression until needed */ 344205194Sdelphij strm->avail_in = (unsigned)len; 345205194Sdelphij strm->next_in = state->in; 346205194Sdelphij state->pos += len; 347205194Sdelphij return len; 348205194Sdelphij} 349205194Sdelphij 350205194Sdelphij#else /* !STDC */ 351205194Sdelphij 352205194Sdelphij/* -- see zlib.h -- */ 353205194Sdelphijint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 354205194Sdelphij a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) 355205194Sdelphij gzFile file; 356205194Sdelphij const char *format; 357205194Sdelphij int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, 358205194Sdelphij a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; 359205194Sdelphij{ 360205194Sdelphij int size, len; 361205194Sdelphij gz_statep state; 362205194Sdelphij z_streamp strm; 363205194Sdelphij 364205194Sdelphij /* get internal structure */ 365205194Sdelphij if (file == NULL) 366205194Sdelphij return -1; 367205194Sdelphij state = (gz_statep)file; 368205194Sdelphij strm = &(state->strm); 369205194Sdelphij 370205194Sdelphij /* check that we're writing and that there's no error */ 371205194Sdelphij if (state->mode != GZ_WRITE || state->err != Z_OK) 372205194Sdelphij return 0; 373205194Sdelphij 374205194Sdelphij /* make sure we have some buffer space */ 375205194Sdelphij if (state->size == 0 && gz_init(state) == -1) 376205194Sdelphij return 0; 377205194Sdelphij 378205194Sdelphij /* check for seek request */ 379205194Sdelphij if (state->seek) { 380205194Sdelphij state->seek = 0; 381205194Sdelphij if (gz_zero(state, state->skip) == -1) 382205194Sdelphij return 0; 383205194Sdelphij } 384205194Sdelphij 385205194Sdelphij /* consume whatever's left in the input buffer */ 386205194Sdelphij if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 387205194Sdelphij return 0; 388205194Sdelphij 389205194Sdelphij /* do the printf() into the input buffer, put length in len */ 390205194Sdelphij size = (int)(state->size); 391205194Sdelphij state->in[size - 1] = 0; 392205194Sdelphij#ifdef NO_snprintf 393205194Sdelphij# ifdef HAS_sprintf_void 394205194Sdelphij sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, 395205194Sdelphij a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 396205194Sdelphij for (len = 0; len < size; len++) 397205194Sdelphij if (state->in[len] == 0) break; 398205194Sdelphij# else 399205194Sdelphij len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8, 400205194Sdelphij a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 401205194Sdelphij# endif 402205194Sdelphij#else 403205194Sdelphij# ifdef HAS_snprintf_void 404205194Sdelphij snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, 405205194Sdelphij a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 406205194Sdelphij len = strlen(state->in); 407205194Sdelphij# else 408205194Sdelphij len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8, 409205194Sdelphij a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 410205194Sdelphij# endif 411205194Sdelphij#endif 412205194Sdelphij 413205194Sdelphij /* check that printf() results fit in buffer */ 414205194Sdelphij if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) 415205194Sdelphij return 0; 416205194Sdelphij 417205194Sdelphij /* update buffer and position, defer compression until needed */ 418205194Sdelphij strm->avail_in = (unsigned)len; 419205194Sdelphij strm->next_in = state->in; 420205194Sdelphij state->pos += len; 421205194Sdelphij return len; 422205194Sdelphij} 423205194Sdelphij 424205194Sdelphij#endif 425205194Sdelphij 426205194Sdelphij/* -- see zlib.h -- */ 427205194Sdelphijint ZEXPORT gzflush(file, flush) 428205194Sdelphij gzFile file; 429205194Sdelphij int flush; 430205194Sdelphij{ 431205194Sdelphij gz_statep state; 432205194Sdelphij 433205194Sdelphij /* get internal structure */ 434205194Sdelphij if (file == NULL) 435205194Sdelphij return -1; 436205194Sdelphij state = (gz_statep)file; 437205194Sdelphij 438205194Sdelphij /* check that we're writing and that there's no error */ 439205194Sdelphij if (state->mode != GZ_WRITE || state->err != Z_OK) 440205194Sdelphij return Z_STREAM_ERROR; 441205194Sdelphij 442205194Sdelphij /* check flush parameter */ 443205194Sdelphij if (flush < 0 || flush > Z_FINISH) 444205194Sdelphij return Z_STREAM_ERROR; 445205194Sdelphij 446205194Sdelphij /* check for seek request */ 447205194Sdelphij if (state->seek) { 448205194Sdelphij state->seek = 0; 449205194Sdelphij if (gz_zero(state, state->skip) == -1) 450205194Sdelphij return -1; 451205194Sdelphij } 452205194Sdelphij 453205194Sdelphij /* compress remaining data with requested flush */ 454205194Sdelphij gz_comp(state, flush); 455205194Sdelphij return state->err; 456205194Sdelphij} 457205194Sdelphij 458205194Sdelphij/* -- see zlib.h -- */ 459205194Sdelphijint ZEXPORT gzsetparams(file, level, strategy) 460205194Sdelphij gzFile file; 461205194Sdelphij int level; 462205194Sdelphij int strategy; 463205194Sdelphij{ 464205194Sdelphij gz_statep state; 465205194Sdelphij z_streamp strm; 466205194Sdelphij 467205194Sdelphij /* get internal structure */ 468205194Sdelphij if (file == NULL) 469205194Sdelphij return Z_STREAM_ERROR; 470205194Sdelphij state = (gz_statep)file; 471205194Sdelphij strm = &(state->strm); 472205194Sdelphij 473205194Sdelphij /* check that we're writing and that there's no error */ 474205194Sdelphij if (state->mode != GZ_WRITE || state->err != Z_OK) 475205194Sdelphij return Z_STREAM_ERROR; 476205194Sdelphij 477205194Sdelphij /* if no change is requested, then do nothing */ 478205194Sdelphij if (level == state->level && strategy == state->strategy) 479205194Sdelphij return Z_OK; 480205194Sdelphij 481205194Sdelphij /* check for seek request */ 482205194Sdelphij if (state->seek) { 483205194Sdelphij state->seek = 0; 484205194Sdelphij if (gz_zero(state, state->skip) == -1) 485205194Sdelphij return -1; 486205194Sdelphij } 487205194Sdelphij 488205194Sdelphij /* change compression parameters for subsequent input */ 489205194Sdelphij if (state->size) { 490205194Sdelphij /* flush previous input with previous parameters before changing */ 491205194Sdelphij if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) 492205194Sdelphij return state->err; 493205194Sdelphij deflateParams(strm, level, strategy); 494205194Sdelphij } 495205194Sdelphij state->level = level; 496205194Sdelphij state->strategy = strategy; 497205194Sdelphij return Z_OK; 498205194Sdelphij} 499205194Sdelphij 500205194Sdelphij/* -- see zlib.h -- */ 501205194Sdelphijint ZEXPORT gzclose_w(file) 502205194Sdelphij gzFile file; 503205194Sdelphij{ 504205194Sdelphij int ret = 0; 505205194Sdelphij gz_statep state; 506205194Sdelphij 507205194Sdelphij /* get internal structure */ 508205194Sdelphij if (file == NULL) 509205194Sdelphij return Z_STREAM_ERROR; 510205194Sdelphij state = (gz_statep)file; 511205194Sdelphij 512205194Sdelphij /* check that we're writing */ 513205194Sdelphij if (state->mode != GZ_WRITE) 514205194Sdelphij return Z_STREAM_ERROR; 515205194Sdelphij 516205194Sdelphij /* check for seek request */ 517205194Sdelphij if (state->seek) { 518205194Sdelphij state->seek = 0; 519205194Sdelphij ret += gz_zero(state, state->skip); 520205194Sdelphij } 521205194Sdelphij 522205194Sdelphij /* flush, free memory, and close file */ 523205194Sdelphij ret += gz_comp(state, Z_FINISH); 524205194Sdelphij (void)deflateEnd(&(state->strm)); 525205194Sdelphij free(state->out); 526205194Sdelphij free(state->in); 527205194Sdelphij gz_error(state, Z_OK, NULL); 528205194Sdelphij free(state->path); 529205194Sdelphij ret += close(state->fd); 530205194Sdelphij free(state); 531205194Sdelphij return ret ? Z_ERRNO : Z_OK; 532205194Sdelphij} 533