diff --git a/gzguts.h b/gzguts.h index eefdca0..07c7ac3 100644 --- a/gzguts.h +++ b/gzguts.h @@ -155,9 +155,10 @@ typedef struct { unsigned char *out; /* output buffer (double-sized when reading) */ int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ - int eof; /* true if end of input file reached */ - z_off64_t start; /* where the gzip data started, for rewinding */ int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ /* just for writing */ int level; /* compression level */ int strategy; /* compression strategy */ diff --git a/gzlib.c b/gzlib.c index e53b6ab..d998d07 100644 --- a/gzlib.c +++ b/gzlib.c @@ -78,6 +78,7 @@ local void gz_reset(state) state->x.have = 0; /* no output data available */ if (state->mode == GZ_READ) { /* for reading ... */ state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ state->how = LOOK; /* look for gzip header */ } state->seek = 0; /* no seek request pending */ @@ -331,6 +332,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence) return -1; state->x.have = 0; state->eof = 0; + state->past = 0; state->seek = 0; gz_error(state, Z_OK, NULL); state->strm.avail_in = 0; @@ -453,8 +455,7 @@ int ZEXPORT gzeof(file) return 0; /* return end-of-file state */ - return state->mode == GZ_READ ? - (state->eof && state->strm.avail_in == 0 && state->x.have == 0) : 0; + return state->mode == GZ_READ ? state->past : 0; } /* -- see zlib.h -- */ @@ -491,8 +492,10 @@ void ZEXPORT gzclearerr(file) return; /* clear error and end-of-file */ - if (state->mode == GZ_READ) + if (state->mode == GZ_READ) { state->eof = 0; + state->past = 0; + } gz_error(state, Z_OK, NULL); } diff --git a/gzread.c b/gzread.c index 521e26f..cda7935 100644 --- a/gzread.c +++ b/gzread.c @@ -329,8 +329,10 @@ int ZEXPORT gzread(file, buf, len) } /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) + else if (state->eof && strm->avail_in == 0) { + state->past = 1; /* tried to read past end */ break; + } /* need output data -- for small len or new stream load up our output buffer */ @@ -437,6 +439,7 @@ int ZEXPORT gzungetc(c, file) state->x.next = state->out + (state->size << 1) - 1; state->x.next[0] = c; state->x.pos--; + state->past = 0; return c; } @@ -458,6 +461,7 @@ int ZEXPORT gzungetc(c, file) state->x.next--; state->x.next[0] = c; state->x.pos--; + state->past = 0; return c; } @@ -499,9 +503,8 @@ char * ZEXPORT gzgets(file, buf, len) if (state->x.have == 0 && gz_fetch(state) == -1) return NULL; /* error */ if (state->x.have == 0) { /* end of file */ - if (buf == str) /* got bupkus */ - return NULL; - break; /* got something -- return it */ + state->past = 1; /* read past end */ + break; /* return what we have */ } /* look for end-of-line in current output buffer */ @@ -519,7 +522,9 @@ char * ZEXPORT gzgets(file, buf, len) buf += n; } while (left && eol == NULL); - /* found end-of-line or out of space -- terminate string and return it */ + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; buf[0] = 0; return str; }