aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Adler <git@madler.net>2025-05-25 19:01:36 -0700
committerMark Adler <git@madler.net>2025-12-08 03:52:25 -0800
commit81cc0bebedd935daeb81b0b6e475d8786b51af3d (patch)
treedbd05e0ccc349d0ab90d20374716fb400d383e68
parent598130fd078f7b712498d348cf94b4b9806c4435 (diff)
downloadzlib-81cc0bebedd935daeb81b0b6e475d8786b51af3d.tar.gz
zlib-81cc0bebedd935daeb81b0b6e475d8786b51af3d.tar.bz2
zlib-81cc0bebedd935daeb81b0b6e475d8786b51af3d.zip
Support non-blocking devices in the gz* routines.
-rw-r--r--gzguts.h1
-rw-r--r--gzlib.c34
-rw-r--r--gzread.c117
-rw-r--r--gzwrite.c167
-rw-r--r--zlib.h73
5 files changed, 276 insertions, 116 deletions
diff --git a/gzguts.h b/gzguts.h
index b460912..c3d473a 100644
--- a/gzguts.h
+++ b/gzguts.h
@@ -185,6 +185,7 @@ typedef struct {
185 /* just for reading */ 185 /* just for reading */
186 int junk; /* -1 = start, 1 = junk candidate, 0 = in gzip */ 186 int junk; /* -1 = start, 1 = junk candidate, 0 = in gzip */
187 int how; /* 0: get header, 1: copy, 2: decompress */ 187 int how; /* 0: get header, 1: copy, 2: decompress */
188 int again; /* true if EAGAIN or EWOULDBLOCK on last i/o */
188 z_off64_t start; /* where the gzip data started, for rewinding */ 189 z_off64_t start; /* where the gzip data started, for rewinding */
189 int eof; /* true if end of input file reached */ 190 int eof; /* true if end of input file reached */
190 int past; /* true if read requested past end */ 191 int past; /* true if read requested past end */
diff --git a/gzlib.c b/gzlib.c
index 3c50aff..65a0b49 100644
--- a/gzlib.c
+++ b/gzlib.c
@@ -52,7 +52,7 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
52 msgbuf[chars] = 0; 52 msgbuf[chars] = 0;
53 } 53 }
54 54
55 wcstombs(buf, msgbuf, chars + 1); // assumes buf is big enough 55 wcstombs(buf, msgbuf, chars + 1); /* assumes buf is big enough */
56 LocalFree(msgbuf); 56 LocalFree(msgbuf);
57 } 57 }
58 else { 58 else {
@@ -76,6 +76,7 @@ local void gz_reset(gz_statep state) {
76 } 76 }
77 else /* for writing ... */ 77 else /* for writing ... */
78 state->reset = 0; /* no deflateReset pending */ 78 state->reset = 0; /* no deflateReset pending */
79 state->again = 0; /* no stalled i/o yet */
79 state->skip = 0; /* no seek request pending */ 80 state->skip = 0; /* no seek request pending */
80 gz_error(state, Z_OK, NULL); /* clear error */ 81 gz_error(state, Z_OK, NULL); /* clear error */
81 state->x.pos = 0; /* no uncompressed data yet */ 82 state->x.pos = 0; /* no uncompressed data yet */
@@ -86,10 +87,7 @@ local void gz_reset(gz_statep state) {
86local gzFile gz_open(const void *path, int fd, const char *mode) { 87local gzFile gz_open(const void *path, int fd, const char *mode) {
87 gz_statep state; 88 gz_statep state;
88 z_size_t len; 89 z_size_t len;
89 int oflag; 90 int oflag = 0;
90#ifdef O_CLOEXEC
91 int cloexec = 0;
92#endif
93#ifdef O_EXCL 91#ifdef O_EXCL
94 int exclusive = 0; 92 int exclusive = 0;
95#endif 93#endif
@@ -135,7 +133,7 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
135 break; 133 break;
136#ifdef O_CLOEXEC 134#ifdef O_CLOEXEC
137 case 'e': 135 case 'e':
138 cloexec = 1; 136 oflag |= O_CLOEXEC;
139 break; 137 break;
140#endif 138#endif
141#ifdef O_EXCL 139#ifdef O_EXCL
@@ -158,6 +156,11 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
158 case 'G': 156 case 'G':
159 state->direct = -1; 157 state->direct = -1;
160 break; 158 break;
159#ifdef O_NONBLOCK
160 case 'N':
161 oflag |= O_NONBLOCK;
162 break;
163#endif
161 case 'T': 164 case 'T':
162 state->direct = 1; 165 state->direct = 1;
163 break; 166 break;
@@ -223,16 +226,13 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
223 } 226 }
224 227
225 /* compute the flags for open() */ 228 /* compute the flags for open() */
226 oflag = 229 oflag |=
227#ifdef O_LARGEFILE 230#ifdef O_LARGEFILE
228 O_LARGEFILE | 231 O_LARGEFILE |
229#endif 232#endif
230#ifdef O_BINARY 233#ifdef O_BINARY
231 O_BINARY | 234 O_BINARY |
232#endif 235#endif
233#ifdef O_CLOEXEC
234 (cloexec ? O_CLOEXEC : 0) |
235#endif
236 (state->mode == GZ_READ ? 236 (state->mode == GZ_READ ?
237 O_RDONLY : 237 O_RDONLY :
238 (O_WRONLY | O_CREAT | 238 (O_WRONLY | O_CREAT |
@@ -250,8 +250,17 @@ local gzFile gz_open(const void *path, int fd, const char *mode) {
250 else if (fd == -2) 250 else if (fd == -2)
251 state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE); 251 state->fd = _wopen(path, oflag, _S_IREAD | _S_IWRITE);
252#endif 252#endif
253 else 253 else {
254#ifdef O_NONBLOCK
255 if (oflag & O_NONBLOCK)
256 fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
257#endif
258#ifdef O_CLOEXEC
259 if (oflag & O_CLOEXEC)
260 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | O_CLOEXEC);
261#endif
254 state->fd = fd; 262 state->fd = fd;
263 }
255 if (state->fd == -1) { 264 if (state->fd == -1) {
256 free(state->path); 265 free(state->path);
257 free(state); 266 free(state);
@@ -552,7 +561,7 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
552 } 561 }
553 562
554 /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 563 /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
555 if (err != Z_OK && err != Z_BUF_ERROR) 564 if (err != Z_OK && err != Z_BUF_ERROR && !state->again)
556 state->x.have = 0; 565 state->x.have = 0;
557 566
558 /* set error code, and if no message, then done */ 567 /* set error code, and if no message, then done */
@@ -589,6 +598,7 @@ unsigned ZLIB_INTERNAL gz_intmax(void) {
589 return INT_MAX; 598 return INT_MAX;
590#else 599#else
591 unsigned p = 1, q; 600 unsigned p = 1, q;
601
592 do { 602 do {
593 q = p; 603 q = p;
594 p <<= 1; 604 p <<= 1;
diff --git a/gzread.c b/gzread.c
index aca4186..025657a 100644
--- a/gzread.c
+++ b/gzread.c
@@ -8,12 +8,20 @@
8/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from 8/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
9 state->fd, and update state->eof, state->err, and state->msg as appropriate. 9 state->fd, and update state->eof, state->err, and state->msg as appropriate.
10 This function needs to loop on read(), since read() is not guaranteed to 10 This function needs to loop on read(), since read() is not guaranteed to
11 read the number of bytes requested, depending on the type of descriptor. */ 11 read the number of bytes requested, depending on the type of descriptor. It
12 also needs to loop to manage the fact that read() returns an int. If the
13 descriptor is non-blocking and read() returns with no data in order to avoid
14 blocking, then gz_load() will return 0 if some data has been read, or -1 if
15 no data has been read. Either way, state->again is set true to indicate a
16 non-blocking event. If errno is non-zero on return, then there was an error
17 signaled from read(). *have is set to the number of bytes read. */
12local int gz_load(gz_statep state, unsigned char *buf, unsigned len, 18local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
13 unsigned *have) { 19 unsigned *have) {
14 int ret; 20 int ret;
15 unsigned get, max = ((unsigned)-1 >> 2) + 1; 21 unsigned get, max = ((unsigned)-1 >> 2) + 1;
16 22
23 state->again = 0;
24 errno = 0;
17 *have = 0; 25 *have = 0;
18 do { 26 do {
19 get = len - *have; 27 get = len - *have;
@@ -25,6 +33,11 @@ local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
25 *have += (unsigned)ret; 33 *have += (unsigned)ret;
26 } while (*have < len); 34 } while (*have < len);
27 if (ret < 0) { 35 if (ret < 0) {
36 if (errno == EAGAIN || errno == EWOULDBLOCK) {
37 state->again = 1;
38 if (*have != 0)
39 return 0;
40 }
28 gz_error(state, Z_ERRNO, zstrerror()); 41 gz_error(state, Z_ERRNO, zstrerror());
29 return -1; 42 return -1;
30 } 43 }
@@ -50,8 +63,10 @@ local int gz_avail(gz_statep state) {
50 if (strm->avail_in) { /* copy what's there to the start */ 63 if (strm->avail_in) { /* copy what's there to the start */
51 unsigned char *p = state->in; 64 unsigned char *p = state->in;
52 unsigned const char *q = strm->next_in; 65 unsigned const char *q = strm->next_in;
66
53 if (q != p) { 67 if (q != p) {
54 unsigned n = strm->avail_in; 68 unsigned n = strm->avail_in;
69
55 do { 70 do {
56 *p++ = *q++; 71 *p++ = *q++;
57 } while (--n); 72 } while (--n);
@@ -125,7 +140,9 @@ local int gz_look(gz_statep state) {
125 then it's not an error as this is a transparent read of zero bytes */ 140 then it's not an error as this is a transparent read of zero bytes */
126 if (gz_avail(state) == -1) 141 if (gz_avail(state) == -1)
127 return -1; 142 return -1;
128 if (strm->avail_in == 0) 143 if (strm->avail_in == 0 || (state->again && strm->avail_in < 4))
144 /* if non-blocking input stalled before getting four bytes, then
145 return and wait until a later call has accumulated enough */
129 return 0; 146 return 0;
130 147
131 /* see if this is (likely) gzip input -- if the first four bytes are 148 /* see if this is (likely) gzip input -- if the first four bytes are
@@ -154,9 +171,12 @@ local int gz_look(gz_statep state) {
154 171
155/* Decompress from input to the provided next_out and avail_out in the state. 172/* Decompress from input to the provided next_out and avail_out in the state.
156 On return, state->x.have and state->x.next point to the just decompressed 173 On return, state->x.have and state->x.next point to the just decompressed
157 data. If the gzip stream completes, state->how is reset to LOOK to look for 174 data. If the gzip stream completes, state->how is reset to LOOK to look for
158 the next gzip stream or raw data, once state->x.have is depleted. Returns 0 175 the next gzip stream or raw data, once state->x.have is depleted. Returns 0
159 on success, -1 on failure. */ 176 on success, -1 on failure. If EOF is reached when looking for more input to
177 complete the gzip member, then an unexpected end of file error is raised.
178 If there is no more input, but state->again is true, then EOF has not been
179 reached, and no error is raised. */
160local int gz_decomp(gz_statep state) { 180local int gz_decomp(gz_statep state) {
161 int ret = Z_OK; 181 int ret = Z_OK;
162 unsigned had; 182 unsigned had;
@@ -171,7 +191,8 @@ local int gz_decomp(gz_statep state) {
171 break; 191 break;
172 } 192 }
173 if (strm->avail_in == 0) { 193 if (strm->avail_in == 0) {
174 gz_error(state, Z_BUF_ERROR, "unexpected end of file"); 194 if (!state->again)
195 gz_error(state, Z_BUF_ERROR, "unexpected end of file");
175 break; 196 break;
176 } 197 }
177 198
@@ -371,15 +392,17 @@ local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
371int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) { 392int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
372 gz_statep state; 393 gz_statep state;
373 394
374 /* get internal structure */ 395 /* get internal structure and check that it's for reading */
375 if (file == NULL) 396 if (file == NULL)
376 return -1; 397 return -1;
377 state = (gz_statep)file; 398 state = (gz_statep)file;
399 if (state->mode != GZ_READ)
400 return -1;
378 401
379 /* check that we're reading and that there's no (serious) error */ 402 /* check that there was no (serious) error */
380 if (state->mode != GZ_READ || 403 if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
381 (state->err != Z_OK && state->err != Z_BUF_ERROR))
382 return -1; 404 return -1;
405 gz_error(state, Z_OK, NULL);
383 406
384 /* since an int is returned, make sure len fits in one, otherwise return 407 /* since an int is returned, make sure len fits in one, otherwise return
385 with an error (this avoids a flaw in the interface) */ 408 with an error (this avoids a flaw in the interface) */
@@ -389,13 +412,22 @@ int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
389 } 412 }
390 413
391 /* read len or fewer bytes to buf */ 414 /* read len or fewer bytes to buf */
392 len = (unsigned)gz_read(state, buf, len); 415 len = gz_read(state, buf, len);
393 416
394 /* check for an error */ 417 /* check for an error */
395 if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) 418 if (len == 0) {
396 return -1; 419 if (state->err != Z_OK && state->err != Z_BUF_ERROR)
420 return -1;
421 if (state->again) {
422 /* non-blocking input stalled after some input was read, but no
423 uncompressed bytes were produced -- let the application know
424 this isn't EOF */
425 gz_error(state, Z_ERRNO, zstrerror());
426 return -1;
427 }
428 }
397 429
398 /* return the number of bytes read (this is assured to fit in an int) */ 430 /* return the number of bytes read */
399 return (int)len; 431 return (int)len;
400} 432}
401 433
@@ -405,15 +437,17 @@ z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
405 z_size_t len; 437 z_size_t len;
406 gz_statep state; 438 gz_statep state;
407 439
408 /* get internal structure */ 440 /* get internal structure and check that it's for reading */
409 if (file == NULL) 441 if (file == NULL)
410 return 0; 442 return 0;
411 state = (gz_statep)file; 443 state = (gz_statep)file;
444 if (state->mode != GZ_READ)
445 return 0;
412 446
413 /* check that we're reading and that there's no (serious) error */ 447 /* check that there was no (serious) error */
414 if (state->mode != GZ_READ || 448 if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
415 (state->err != Z_OK && state->err != Z_BUF_ERROR))
416 return 0; 449 return 0;
450 gz_error(state, Z_OK, NULL);
417 451
418 /* compute bytes to read -- error on overflow */ 452 /* compute bytes to read -- error on overflow */
419 len = nitems * size; 453 len = nitems * size;
@@ -436,15 +470,17 @@ int ZEXPORT gzgetc(gzFile file) {
436 unsigned char buf[1]; 470 unsigned char buf[1];
437 gz_statep state; 471 gz_statep state;
438 472
439 /* get internal structure */ 473 /* get internal structure and check that it's for reading */
440 if (file == NULL) 474 if (file == NULL)
441 return -1; 475 return -1;
442 state = (gz_statep)file; 476 state = (gz_statep)file;
477 if (state->mode != GZ_READ)
478 return -1;
443 479
444 /* check that we're reading and that there's no (serious) error */ 480 /* check that there was no (serious) error */
445 if (state->mode != GZ_READ || 481 if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
446 (state->err != Z_OK && state->err != Z_BUF_ERROR))
447 return -1; 482 return -1;
483 gz_error(state, Z_OK, NULL);
448 484
449 /* try output buffer (no need to check for skip request) */ 485 /* try output buffer (no need to check for skip request) */
450 if (state->x.have) { 486 if (state->x.have) {
@@ -465,19 +501,21 @@ int ZEXPORT gzgetc_(gzFile file) {
465int ZEXPORT gzungetc(int c, gzFile file) { 501int ZEXPORT gzungetc(int c, gzFile file) {
466 gz_statep state; 502 gz_statep state;
467 503
468 /* get internal structure */ 504 /* get internal structure and check that it's for reading */
469 if (file == NULL) 505 if (file == NULL)
470 return -1; 506 return -1;
471 state = (gz_statep)file; 507 state = (gz_statep)file;
508 if (state->mode != GZ_READ)
509 return -1;
472 510
473 /* in case this was just opened, set up the input buffer */ 511 /* in case this was just opened, set up the input buffer */
474 if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) 512 if (state->how == LOOK && state->x.have == 0)
475 (void)gz_look(state); 513 (void)gz_look(state);
476 514
477 /* check that we're reading and that there's no (serious) error */ 515 /* check that there was no (serious) error */
478 if (state->mode != GZ_READ || 516 if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
479 (state->err != Z_OK && state->err != Z_BUF_ERROR))
480 return -1; 517 return -1;
518 gz_error(state, Z_OK, NULL);
481 519
482 /* process a skip request */ 520 /* process a skip request */
483 if (state->skip && gz_skip(state) == -1) 521 if (state->skip && gz_skip(state) == -1)
@@ -507,6 +545,7 @@ int ZEXPORT gzungetc(int c, gzFile file) {
507 if (state->x.next == state->out) { 545 if (state->x.next == state->out) {
508 unsigned char *src = state->out + state->x.have; 546 unsigned char *src = state->out + state->x.have;
509 unsigned char *dest = state->out + (state->size << 1); 547 unsigned char *dest = state->out + (state->size << 1);
548
510 while (src > state->out) 549 while (src > state->out)
511 *--dest = *--src; 550 *--dest = *--src;
512 state->x.next = dest; 551 state->x.next = dest;
@@ -526,23 +565,25 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
526 unsigned char *eol; 565 unsigned char *eol;
527 gz_statep state; 566 gz_statep state;
528 567
529 /* check parameters and get internal structure */ 568 /* check parameters, get internal structure, and check that it's for
569 reading */
530 if (file == NULL || buf == NULL || len < 1) 570 if (file == NULL || buf == NULL || len < 1)
531 return NULL; 571 return NULL;
532 state = (gz_statep)file; 572 state = (gz_statep)file;
573 if (state->mode != GZ_READ)
574 return NULL;
533 575
534 /* check that we're reading and that there's no (serious) error */ 576 /* check that there was no (serious) error */
535 if (state->mode != GZ_READ || 577 if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
536 (state->err != Z_OK && state->err != Z_BUF_ERROR))
537 return NULL; 578 return NULL;
579 gz_error(state, Z_OK, NULL);
538 580
539 /* process a skip request */ 581 /* process a skip request */
540 if (state->skip && gz_skip(state) == -1) 582 if (state->skip && gz_skip(state) == -1)
541 return NULL; 583 return NULL;
542 584
543 /* copy output bytes up to new line or len - 1, whichever comes first -- 585 /* copy output up to a new line, len-1 bytes, or there is no more output,
544 append a terminating zero to the string (we don't check for a zero in 586 whichever comes first */
545 the contents, let the user worry about that) */
546 str = buf; 587 str = buf;
547 left = (unsigned)len - 1; 588 left = (unsigned)len - 1;
548 if (left) do { 589 if (left) do {
@@ -569,7 +610,9 @@ char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
569 buf += n; 610 buf += n;
570 } while (left && eol == NULL); 611 } while (left && eol == NULL);
571 612
572 /* return terminated string, or if nothing, end of file */ 613 /* append a terminating zero to the string (we don't check for a zero in
614 the contents, let the user worry about that) -- return the terminated
615 string, or if nothing was read, NULL */
573 if (buf == str) 616 if (buf == str)
574 return NULL; 617 return NULL;
575 buf[0] = 0; 618 buf[0] = 0;
@@ -599,12 +642,10 @@ int ZEXPORT gzclose_r(gzFile file) {
599 int ret, err; 642 int ret, err;
600 gz_statep state; 643 gz_statep state;
601 644
602 /* get internal structure */ 645 /* get internal structure and check that it's for reading */
603 if (file == NULL) 646 if (file == NULL)
604 return Z_STREAM_ERROR; 647 return Z_STREAM_ERROR;
605 state = (gz_statep)file; 648 state = (gz_statep)file;
606
607 /* check that we're reading */
608 if (state->mode != GZ_READ) 649 if (state->mode != GZ_READ)
609 return Z_STREAM_ERROR; 650 return Z_STREAM_ERROR;
610 651
diff --git a/gzwrite.c b/gzwrite.c
index ab29bf4..e7864cb 100644
--- a/gzwrite.c
+++ b/gzwrite.c
@@ -74,9 +74,13 @@ local int gz_comp(gz_statep state, int flush) {
74 /* write directly if requested */ 74 /* write directly if requested */
75 if (state->direct) { 75 if (state->direct) {
76 while (strm->avail_in) { 76 while (strm->avail_in) {
77 errno = 0;
78 state->again = 0;
77 put = strm->avail_in > max ? max : strm->avail_in; 79 put = strm->avail_in > max ? max : strm->avail_in;
78 writ = write(state->fd, strm->next_in, put); 80 writ = write(state->fd, strm->next_in, put);
79 if (writ < 0) { 81 if (writ < 0) {
82 if (errno == EAGAIN || errno == EWOULDBLOCK)
83 state->again = 1;
80 gz_error(state, Z_ERRNO, zstrerror()); 84 gz_error(state, Z_ERRNO, zstrerror());
81 return -1; 85 return -1;
82 } 86 }
@@ -104,10 +108,14 @@ local int gz_comp(gz_statep state, int flush) {
104 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && 108 if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
105 (flush != Z_FINISH || ret == Z_STREAM_END))) { 109 (flush != Z_FINISH || ret == Z_STREAM_END))) {
106 while (strm->next_out > state->x.next) { 110 while (strm->next_out > state->x.next) {
111 errno = 0;
112 state->again = 0;
107 put = strm->next_out - state->x.next > (int)max ? max : 113 put = strm->next_out - state->x.next > (int)max ? max :
108 (unsigned)(strm->next_out - state->x.next); 114 (unsigned)(strm->next_out - state->x.next);
109 writ = write(state->fd, state->x.next, put); 115 writ = write(state->fd, state->x.next, put);
110 if (writ < 0) { 116 if (writ < 0) {
117 if (errno == EAGAIN || errno == EWOULDBLOCK)
118 state->again = 1;
111 gz_error(state, Z_ERRNO, zstrerror()); 119 gz_error(state, Z_ERRNO, zstrerror());
112 return -1; 120 return -1;
113 } 121 }
@@ -140,9 +148,11 @@ local int gz_comp(gz_statep state, int flush) {
140} 148}
141 149
142/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or 150/* Compress state->skip (> 0) zeros to output. Return -1 on a write error or
143 memory allocation failure by gz_comp(), or 0 on success. */ 151 memory allocation failure by gz_comp(), or 0 on success. state->skip is
152 updated with the number of successfully written zeros, in case there is a
153 stall on a non-blocking write destination. */
144local int gz_zero(gz_statep state) { 154local int gz_zero(gz_statep state) {
145 int first; 155 int first, ret;
146 unsigned n; 156 unsigned n;
147 z_streamp strm = &(state->strm); 157 z_streamp strm = &(state->strm);
148 158
@@ -161,18 +171,23 @@ local int gz_zero(gz_statep state) {
161 } 171 }
162 strm->avail_in = n; 172 strm->avail_in = n;
163 strm->next_in = state->in; 173 strm->next_in = state->in;
174 ret = gz_comp(state, Z_NO_FLUSH);
175 n -= strm->avail_in;
164 state->x.pos += n; 176 state->x.pos += n;
165 if (gz_comp(state, Z_NO_FLUSH) == -1)
166 return -1;
167 state->skip -= n; 177 state->skip -= n;
178 if (ret == -1)
179 return -1;
168 } while (state->skip); 180 } while (state->skip);
169 return 0; 181 return 0;
170} 182}
171 183
172/* Write len bytes from buf to file. Return the number of bytes written. If 184/* Write len bytes from buf to file. Return the number of bytes written. If
173 the returned value is less than len, then there was an error. */ 185 the returned value is less than len, then there was an error. If the error
186 was a non-blocking stall, then the number of bytes consumed is returned.
187 For any other error, 0 is returned. */
174local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) { 188local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
175 z_size_t put = len; 189 z_size_t put = len;
190 int ret;
176 191
177 /* if len is zero, avoid unnecessary operations */ 192 /* if len is zero, avoid unnecessary operations */
178 if (len == 0) 193 if (len == 0)
@@ -189,7 +204,7 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
189 /* for small len, copy to input buffer, otherwise compress directly */ 204 /* for small len, copy to input buffer, otherwise compress directly */
190 if (len < state->size) { 205 if (len < state->size) {
191 /* copy to input buffer, compress when full */ 206 /* copy to input buffer, compress when full */
192 do { 207 for (;;) {
193 unsigned have, copy; 208 unsigned have, copy;
194 209
195 if (state->strm.avail_in == 0) 210 if (state->strm.avail_in == 0)
@@ -204,9 +219,11 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
204 state->x.pos += copy; 219 state->x.pos += copy;
205 buf = (const char *)buf + copy; 220 buf = (const char *)buf + copy;
206 len -= copy; 221 len -= copy;
207 if (len && gz_comp(state, Z_NO_FLUSH) == -1) 222 if (len == 0)
208 return 0; 223 break;
209 } while (len); 224 if (gz_comp(state, Z_NO_FLUSH) == -1)
225 return state->again ? put - len : 0;
226 }
210 } 227 }
211 else { 228 else {
212 /* consume whatever's left in the input buffer */ 229 /* consume whatever's left in the input buffer */
@@ -217,13 +234,16 @@ local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
217 state->strm.next_in = (z_const Bytef *)buf; 234 state->strm.next_in = (z_const Bytef *)buf;
218 do { 235 do {
219 unsigned n = (unsigned)-1; 236 unsigned n = (unsigned)-1;
237
220 if (n > len) 238 if (n > len)
221 n = (unsigned)len; 239 n = (unsigned)len;
222 state->strm.avail_in = n; 240 state->strm.avail_in = n;
241 ret = gz_comp(state, Z_NO_FLUSH);
242 n -= state->strm.avail_in;
223 state->x.pos += n; 243 state->x.pos += n;
224 if (gz_comp(state, Z_NO_FLUSH) == -1)
225 return 0;
226 len -= n; 244 len -= n;
245 if (ret == -1)
246 return state->again ? put - len : 0;
227 } while (len); 247 } while (len);
228 } 248 }
229 249
@@ -240,9 +260,10 @@ int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
240 return 0; 260 return 0;
241 state = (gz_statep)file; 261 state = (gz_statep)file;
242 262
243 /* check that we're writing and that there's no error */ 263 /* check that we're writing and that there's no (serious) error */
244 if (state->mode != GZ_WRITE || state->err != Z_OK) 264 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
245 return 0; 265 return 0;
266 gz_error(state, Z_OK, NULL);
246 267
247 /* since an int is returned, make sure len fits in one, otherwise return 268 /* since an int is returned, make sure len fits in one, otherwise return
248 with an error (this avoids a flaw in the interface) */ 269 with an error (this avoids a flaw in the interface) */
@@ -266,9 +287,10 @@ z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
266 return 0; 287 return 0;
267 state = (gz_statep)file; 288 state = (gz_statep)file;
268 289
269 /* check that we're writing and that there's no error */ 290 /* check that we're writing and that there's no (serious) error */
270 if (state->mode != GZ_WRITE || state->err != Z_OK) 291 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
271 return 0; 292 return 0;
293 gz_error(state, Z_OK, NULL);
272 294
273 /* compute bytes to read -- error on overflow */ 295 /* compute bytes to read -- error on overflow */
274 len = nitems * size; 296 len = nitems * size;
@@ -294,9 +316,10 @@ int ZEXPORT gzputc(gzFile file, int c) {
294 state = (gz_statep)file; 316 state = (gz_statep)file;
295 strm = &(state->strm); 317 strm = &(state->strm);
296 318
297 /* check that we're writing and that there's no error */ 319 /* check that we're writing and that there's no (serious) error */
298 if (state->mode != GZ_WRITE || state->err != Z_OK) 320 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
299 return -1; 321 return -1;
322 gz_error(state, Z_OK, NULL);
300 323
301 /* check for seek request */ 324 /* check for seek request */
302 if (state->skip && gz_zero(state) == -1) 325 if (state->skip && gz_zero(state) == -1)
@@ -333,9 +356,10 @@ int ZEXPORT gzputs(gzFile file, const char *s) {
333 return -1; 356 return -1;
334 state = (gz_statep)file; 357 state = (gz_statep)file;
335 358
336 /* check that we're writing and that there's no error */ 359 /* check that we're writing and that there's no (serious) error */
337 if (state->mode != GZ_WRITE || state->err != Z_OK) 360 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
338 return -1; 361 return -1;
362 gz_error(state, Z_OK, NULL);
339 363
340 /* write string */ 364 /* write string */
341 len = strlen(s); 365 len = strlen(s);
@@ -344,7 +368,28 @@ int ZEXPORT gzputs(gzFile file, const char *s) {
344 return -1; 368 return -1;
345 } 369 }
346 put = gz_write(state, s, len); 370 put = gz_write(state, s, len);
347 return put < len ? -1 : (int)len; 371 return len && put == 0 ? -1 : (int)put;
372}
373
374/* If the second half of the input buffer is occupied, write out the contents.
375 If there is any input remaining due to a non-blocking stall on write, move
376 it to the start of the buffer. Return true if this did not open up the
377 second half of the buffer. state->err should be checked after this to
378 handle a gz_comp() error. */
379local int gz_vacate(gz_statep state) {
380 z_streamp strm;
381
382 strm = &(state->strm);
383 if ((strm->next_in + strm->avail_in) - state->in <= state->size)
384 return 0;
385 (void)gz_comp(state, Z_NO_FLUSH);
386 if (strm->avail_in == 0) {
387 strm->next_in = state->in;
388 return 0;
389 }
390 memmove(state->in, strm->next_in, strm->avail_in);
391 strm->next_in = state->in;
392 return strm->avail_in > state->size;
348} 393}
349 394
350#if defined(STDC) || defined(Z_HAVE_STDARG_H) 395#if defined(STDC) || defined(Z_HAVE_STDARG_H)
@@ -352,8 +397,7 @@ int ZEXPORT gzputs(gzFile file, const char *s) {
352 397
353/* -- see zlib.h -- */ 398/* -- see zlib.h -- */
354int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { 399int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
355 int len; 400 int len, ret;
356 unsigned left;
357 char *next; 401 char *next;
358 gz_statep state; 402 gz_statep state;
359 z_streamp strm; 403 z_streamp strm;
@@ -364,9 +408,10 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
364 state = (gz_statep)file; 408 state = (gz_statep)file;
365 strm = &(state->strm); 409 strm = &(state->strm);
366 410
367 /* check that we're writing and that there's no error */ 411 /* check that we're writing and that there's no (serious) error */
368 if (state->mode != GZ_WRITE || state->err != Z_OK) 412 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
369 return Z_STREAM_ERROR; 413 return Z_STREAM_ERROR;
414 gz_error(state, Z_OK, NULL);
370 415
371 /* make sure we have some buffer space */ 416 /* make sure we have some buffer space */
372 if (state->size == 0 && gz_init(state) == -1) 417 if (state->size == 0 && gz_init(state) == -1)
@@ -377,8 +422,20 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
377 return state->err; 422 return state->err;
378 423
379 /* do the printf() into the input buffer, put length in len -- the input 424 /* do the printf() into the input buffer, put length in len -- the input
380 buffer is double-sized just for this function, so there is guaranteed to 425 buffer is double-sized just for this function, so there should be
381 be state->size bytes available after the current contents */ 426 state->size bytes available after the current contents */
427 ret = gz_vacate(state);
428 if (state->err) {
429 if (ret && state->again) {
430 /* There was a non-blocking stall on write, resulting in the part
431 of the second half of the output buffer being occupied. Return
432 a Z_BUF_ERROR to let the application know that this gzprintf()
433 needs to be retried. */
434 gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf");
435 }
436 if (!state->again)
437 return state->err;
438 }
382 if (strm->avail_in == 0) 439 if (strm->avail_in == 0)
383 strm->next_in = state->in; 440 strm->next_in = state->in;
384 next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); 441 next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
@@ -404,18 +461,14 @@ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
404 if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) 461 if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
405 return 0; 462 return 0;
406 463
407 /* update buffer and position, compress first half if past that */ 464 /* update buffer and position */
408 strm->avail_in += (unsigned)len; 465 strm->avail_in += (unsigned)len;
409 state->x.pos += len; 466 state->x.pos += len;
410 if (strm->avail_in >= state->size) { 467
411 left = strm->avail_in - state->size; 468 /* write out buffer if more than half is occupied */
412 strm->avail_in = state->size; 469 ret = gz_vacate(state);
413 if (gz_comp(state, Z_NO_FLUSH) == -1) 470 if (state->err && !state->again)
414 return state->err; 471 return state->err;
415 memmove(state->in, state->in + state->size, left);
416 strm->next_in = state->in;
417 strm->avail_in = left;
418 }
419 return len; 472 return len;
420} 473}
421 474
@@ -451,9 +504,10 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
451 if (sizeof(int) != sizeof(void *)) 504 if (sizeof(int) != sizeof(void *))
452 return Z_STREAM_ERROR; 505 return Z_STREAM_ERROR;
453 506
454 /* check that we're writing and that there's no error */ 507 /* check that we're writing and that there's no (serious) error */
455 if (state->mode != GZ_WRITE || state->err != Z_OK) 508 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
456 return Z_STREAM_ERROR; 509 return Z_STREAM_ERROR;
510 gz_error(state, Z_OK, NULL);
457 511
458 /* make sure we have some buffer space */ 512 /* make sure we have some buffer space */
459 if (state->size == 0 && gz_init(state) == -1) 513 if (state->size == 0 && gz_init(state) == -1)
@@ -466,6 +520,18 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
466 /* do the printf() into the input buffer, put length in len -- the input 520 /* do the printf() into the input buffer, put length in len -- the input
467 buffer is double-sized just for this function, so there is guaranteed to 521 buffer is double-sized just for this function, so there is guaranteed to
468 be state->size bytes available after the current contents */ 522 be state->size bytes available after the current contents */
523 ret = gz_vacate(state);
524 if (state->err) {
525 if (ret && state->again) {
526 /* There was a non-blocking stall on write, resulting in the part
527 of the second half of the output buffer being occupied. Return
528 a Z_BUF_ERROR to let the application know that this gzprintf()
529 needs to be retried. */
530 gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf");
531 }
532 if (!state->again)
533 return state->err;
534 }
469 if (strm->avail_in == 0) 535 if (strm->avail_in == 0)
470 strm->next_in = state->in; 536 strm->next_in = state->in;
471 next = (char *)(strm->next_in + strm->avail_in); 537 next = (char *)(strm->next_in + strm->avail_in);
@@ -499,15 +565,11 @@ int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
499 /* update buffer and position, compress first half if past that */ 565 /* update buffer and position, compress first half if past that */
500 strm->avail_in += len; 566 strm->avail_in += len;
501 state->x.pos += len; 567 state->x.pos += len;
502 if (strm->avail_in >= state->size) { 568
503 left = strm->avail_in - state->size; 569 /* write out buffer if more than half is occupied */
504 strm->avail_in = state->size; 570 ret = gz_vacate(state);
505 if (gz_comp(state, Z_NO_FLUSH) == -1) 571 if (state->err && !state->again)
506 return state->err; 572 return state->err;
507 memmove(state->in, state->in + state->size, left);
508 strm->next_in = state->in;
509 strm->avail_in = left;
510 }
511 return (int)len; 573 return (int)len;
512} 574}
513 575
@@ -522,9 +584,10 @@ int ZEXPORT gzflush(gzFile file, int flush) {
522 return Z_STREAM_ERROR; 584 return Z_STREAM_ERROR;
523 state = (gz_statep)file; 585 state = (gz_statep)file;
524 586
525 /* check that we're writing and that there's no error */ 587 /* check that we're writing and that there's no (serious) error */
526 if (state->mode != GZ_WRITE || state->err != Z_OK) 588 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
527 return Z_STREAM_ERROR; 589 return Z_STREAM_ERROR;
590 gz_error(state, Z_OK, NULL);
528 591
529 /* check flush parameter */ 592 /* check flush parameter */
530 if (flush < 0 || flush > Z_FINISH) 593 if (flush < 0 || flush > Z_FINISH)
@@ -550,9 +613,11 @@ int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
550 state = (gz_statep)file; 613 state = (gz_statep)file;
551 strm = &(state->strm); 614 strm = &(state->strm);
552 615
553 /* check that we're writing and that there's no error */ 616 /* check that we're compressing and that there's no (serious) error */
554 if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) 617 if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) ||
618 state->direct)
555 return Z_STREAM_ERROR; 619 return Z_STREAM_ERROR;
620 gz_error(state, Z_OK, NULL);
556 621
557 /* if no change is requested, then do nothing */ 622 /* if no change is requested, then do nothing */
558 if (level == state->level && strategy == state->strategy) 623 if (level == state->level && strategy == state->strategy)
diff --git a/zlib.h b/zlib.h
index fa8b3d4..842caa8 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1349,13 +1349,13 @@ ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode);
1349 used to force transparent reading. Transparent reading is automatically 1349 used to force transparent reading. Transparent reading is automatically
1350 performed if there is no gzip header at the start. Transparent reading can 1350 performed if there is no gzip header at the start. Transparent reading can
1351 be disabled with the 'G' option, which will instead return an error if there 1351 be disabled with the 'G' option, which will instead return an error if there
1352 is no gzip header. 1352 is no gzip header. 'N' will open the file in non-blocking mode.
1353 1353
1354 "a" can be used instead of "w" to request that the gzip stream that will 1354 'a' can be used instead of 'w' to request that the gzip stream that will
1355 be written be appended to the file. "+" will result in an error, since 1355 be written be appended to the file. '+' will result in an error, since
1356 reading and writing to the same gzip file is not supported. The addition of 1356 reading and writing to the same gzip file is not supported. The addition of
1357 "x" when writing will create the file exclusively, which fails if the file 1357 'x' when writing will create the file exclusively, which fails if the file
1358 already exists. On systems that support it, the addition of "e" when 1358 already exists. On systems that support it, the addition of 'e' when
1359 reading or writing will set the flag to close the file on an execve() call. 1359 reading or writing will set the flag to close the file on an execve() call.
1360 1360
1361 These functions, as well as gzip, will read and decode a sequence of gzip 1361 These functions, as well as gzip, will read and decode a sequence of gzip
@@ -1374,14 +1374,22 @@ ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode);
1374 insufficient memory to allocate the gzFile state, or if an invalid mode was 1374 insufficient memory to allocate the gzFile state, or if an invalid mode was
1375 specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). 1375 specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
1376 errno can be checked to determine if the reason gzopen failed was that the 1376 errno can be checked to determine if the reason gzopen failed was that the
1377 file could not be opened. 1377 file could not be opened. Note that if 'N' is in mode for non-blocking, the
1378 open() itself can fail in order to not block. In that case gzopen() will
1379 return NULL and errno will be EAGAIN or ENONBLOCK. The call to gzopen() can
1380 then be re-tried. If the application would like to block on opening the
1381 file, then it can use open() without O_NONBLOCK, and then gzdopen() with the
1382 resulting file descriptor and 'N' in the mode, which will set it to non-
1383 blocking.
1378*/ 1384*/
1379 1385
1380ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); 1386ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode);
1381/* 1387/*
1382 Associate a gzFile with the file descriptor fd. File descriptors are 1388 Associate a gzFile with the file descriptor fd. File descriptors are
1383 obtained from calls like open, dup, creat, pipe or fileno (if the file has 1389 obtained from calls like open, dup, creat, pipe or fileno (if the file has
1384 been previously opened with fopen). The mode parameter is as in gzopen. 1390 been previously opened with fopen). The mode parameter is as in gzopen. An
1391 'e' in mode will set fd's flag to close the file on an execve() call. An 'N'
1392 in mode will set fd's non-blocking flag.
1385 1393
1386 The next call of gzclose on the returned gzFile will also close the file 1394 The next call of gzclose on the returned gzFile will also close the file
1387 descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor 1395 descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
@@ -1451,6 +1459,11 @@ ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len);
1451 stream. Alternatively, gzerror can be used before gzclose to detect this 1459 stream. Alternatively, gzerror can be used before gzclose to detect this
1452 case. 1460 case.
1453 1461
1462 gzread can be used to read a gzip file on a non-blocking device. If the
1463 input stalls and there is no uncompressed data to return, then gzread() will
1464 return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be
1465 called again.
1466
1454 gzread returns the number of uncompressed bytes actually read, less than 1467 gzread returns the number of uncompressed bytes actually read, less than
1455 len for end of file, or -1 for error. If len is too large to fit in an int, 1468 len for end of file, or -1 for error. If len is too large to fit in an int,
1456 then nothing is read, -1 is returned, and the error state is set to 1469 then nothing is read, -1 is returned, and the error state is set to
@@ -1479,15 +1492,20 @@ ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
1479 multiple of size, then the final partial item is nevertheless read into buf 1492 multiple of size, then the final partial item is nevertheless read into buf
1480 and the end-of-file flag is set. The length of the partial item read is not 1493 and the end-of-file flag is set. The length of the partial item read is not
1481 provided, but could be inferred from the result of gztell(). This behavior 1494 provided, but could be inferred from the result of gztell(). This behavior
1482 is the same as the behavior of fread() implementations in common libraries, 1495 is the same as that of fread() implementations in common libraries. This
1483 but it prevents the direct use of gzfread() to read a concurrently written 1496 could result in data loss if used with size != 1 when reading a concurrently
1484 file, resetting and retrying on end-of-file, when size is not 1. 1497 written file or a non-blocking file. In that case, use size == 1 or gzread()
1498 instead.
1485*/ 1499*/
1486 1500
1487ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); 1501ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len);
1488/* 1502/*
1489 Compress and write the len uncompressed bytes at buf to file. gzwrite 1503 Compress and write the len uncompressed bytes at buf to file. gzwrite
1490 returns the number of uncompressed bytes written or 0 in case of error. 1504 returns the number of uncompressed bytes written, or 0 in case of error or
1505 if len is 0. If the write destination is non-blocking, then gzwrite() may
1506 return a number of bytes written that is not 0 and less than len.
1507
1508 If len does not fit in an int, then 0 is returned and nothing is written.
1491*/ 1509*/
1492 1510
1493ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, 1511ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size,
@@ -1502,6 +1520,11 @@ ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size,
1502 if there was an error. If the multiplication of size and nitems overflows, 1520 if there was an error. If the multiplication of size and nitems overflows,
1503 i.e. the product does not fit in a z_size_t, then nothing is written, zero 1521 i.e. the product does not fit in a z_size_t, then nothing is written, zero
1504 is returned, and the error state is set to Z_STREAM_ERROR. 1522 is returned, and the error state is set to Z_STREAM_ERROR.
1523
1524 If writing a concurrently read file or a non-blocking file with size != 1,
1525 a partial item could be written, with no way of knowing how much of it was
1526 not written, resulting in data loss. In that case, use size == 1 or
1527 gzwrite() instead.
1505*/ 1528*/
1506 1529
1507ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); 1530ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...);
@@ -1517,6 +1540,9 @@ ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...);
1517 zlib was compiled with the insecure functions sprintf() or vsprintf(), 1540 zlib was compiled with the insecure functions sprintf() or vsprintf(),
1518 because the secure snprintf() or vsnprintf() functions were not available. 1541 because the secure snprintf() or vsnprintf() functions were not available.
1519 This can be determined using zlibCompileFlags(). 1542 This can be determined using zlibCompileFlags().
1543
1544 If a Z_BUF_ERROR is returned, then nothing was written due to a stall on
1545 the non-blocking write destination.
1520*/ 1546*/
1521 1547
1522ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); 1548ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s);
@@ -1525,6 +1551,11 @@ ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s);
1525 the terminating null character. 1551 the terminating null character.
1526 1552
1527 gzputs returns the number of characters written, or -1 in case of error. 1553 gzputs returns the number of characters written, or -1 in case of error.
1554 The number of characters written may be less than the length of the string
1555 if the write destination is non-blocking.
1556
1557 If the length of the string does not fit in an int, then -1 is returned
1558 and nothing is written.
1528*/ 1559*/
1529 1560
1530ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); 1561ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len);
@@ -1540,6 +1571,10 @@ ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len);
1540 for end-of-file or in case of error. If some data was read before an error, 1571 for end-of-file or in case of error. If some data was read before an error,
1541 then that data is returned until exhausted, after which the next call will 1572 then that data is returned until exhausted, after which the next call will
1542 return NULL to signal the error. 1573 return NULL to signal the error.
1574
1575 gzgets can be used on a file being concurrently written, and on a non-
1576 blocking device, both as for gzread(). However lines may be broken in the
1577 middle, leaving it up to the application to reassemble them as needed.
1543*/ 1578*/
1544 1579
1545ZEXTERN int ZEXPORT gzputc(gzFile file, int c); 1580ZEXTERN int ZEXPORT gzputc(gzFile file, int c);
@@ -1550,14 +1585,19 @@ ZEXTERN int ZEXPORT gzputc(gzFile file, int c);
1550 1585
1551ZEXTERN int ZEXPORT gzgetc(gzFile file); 1586ZEXTERN int ZEXPORT gzgetc(gzFile file);
1552/* 1587/*
1553 Read and decompress one byte from file. gzgetc returns this byte or -1 in 1588 Read and decompress one byte from file. gzgetc returns this byte or -1 in
1554 case of end of file or error. If some data was read before an error, then 1589 case of end of file or error. If some data was read before an error, then
1555 that data is returned until exhausted, after which the next call will return 1590 that data is returned until exhausted, after which the next call will return
1556 -1 to signal the error. 1591 -1 to signal the error.
1557 1592
1558 This is implemented as a macro for speed. As such, it does not do all of 1593 This is implemented as a macro for speed. As such, it does not do all of
1559 the checking the other functions do. I.e. it does not check to see if file 1594 the checking the other functions do. I.e. it does not check to see if file
1560 is NULL, nor whether the structure file points to has been clobbered or not. 1595 is NULL, nor whether the structure file points to has been clobbered or not.
1596
1597 gzgetc can be used to read a gzip file on a non-blocking device. If the
1598 input stalls and there is no uncompressed data to return, then gzgetc() will
1599 return -1, and errno will be EAGAIN or EWOULDBLOCK. gzread() can then be
1600 called again.
1561*/ 1601*/
1562 1602
1563ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); 1603ZEXTERN int ZEXPORT gzungetc(int c, gzFile file);
@@ -1666,8 +1706,11 @@ ZEXTERN int ZEXPORT gzdirect(gzFile file);
1666 1706
1667 If gzdirect() is used immediately after gzopen() or gzdopen() it will 1707 If gzdirect() is used immediately after gzopen() or gzdopen() it will
1668 cause buffers to be allocated to allow reading the file to determine if it 1708 cause buffers to be allocated to allow reading the file to determine if it
1669 is a gzip file. Therefore if gzbuffer() is used, it should be called before 1709 is a gzip file. Therefore if gzbuffer() is used, it should be called before
1670 gzdirect(). 1710 gzdirect(). If the input is being written concurrently or the device is non-
1711 blocking, then gzdirect() may give a different answer once four bytes of
1712 input have been accumulated, which is what is needed to confirm or deny a
1713 gzip header. Before this, gzdirect() will return true (1).
1671 1714
1672 When writing, gzdirect() returns true (1) if transparent writing was 1715 When writing, gzdirect() returns true (1) if transparent writing was
1673 requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: 1716 requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: