From 2303ca5846ab9821c71098a3943b24d874d3f7fa Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 5 Jan 2007 14:36:39 +0000 Subject: [PATCH] * Implemented BSD fgetln(). Untested yet. --- configure.ac | 2 +- src/libzzuf.c | 7 +++++++ src/libzzuf.h | 3 +++ src/load-stream.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index fe3a059..43eb477 100644 --- a/configure.ac +++ b/configure.ac @@ -27,7 +27,7 @@ if test "$build" != "$host" -a "${PKG_CONFIG_LIBDIR}" = ""; then fi AC_CHECK_HEADERS(inttypes.h stdint.h getopt.h) -AC_CHECK_FUNCS(open64 lseek64 fopen64 getline getdelim __getdelim) +AC_CHECK_FUNCS(open64 lseek64 fopen64 getline getdelim __getdelim fgetln) AC_CHECK_TYPES(sighandler_t, [], [], [#define _GNU_SOURCE #include ]) diff --git a/src/libzzuf.c b/src/libzzuf.c index 08fda32..d516fbb 100644 --- a/src/libzzuf.c +++ b/src/libzzuf.c @@ -290,6 +290,9 @@ void _zz_register(int fd) files[i].pos = 0; files[i].fuzz.cur = -1; files[i].fuzz.data = malloc(CHUNKBYTES); +#ifdef HAVE_FGETLN + files[i].fuzz.tmp = NULL; +#endif fds[fd] = i; } @@ -301,6 +304,10 @@ void _zz_unregister(int fd) files[fds[fd]].managed = 0; free(files[fds[fd]].fuzz.data); +#ifdef HAVE_FGETLN + if(files[fds[fd]].fuzz.tmp) + free(files[fds[fd]].fuzz.tmp); +#endif fds[fd] = -1; } diff --git a/src/libzzuf.h b/src/libzzuf.h index dacd02c..7d76321 100644 --- a/src/libzzuf.h +++ b/src/libzzuf.h @@ -29,6 +29,9 @@ struct fuzz { int cur; uint8_t *data; +#ifdef HAVE_FGETLN + char *tmp; +#endif }; /* Internal variables */ diff --git a/src/load-stream.c b/src/load-stream.c index 8dd7bf0..6a142fc 100644 --- a/src/load-stream.c +++ b/src/load-stream.c @@ -62,6 +62,11 @@ static ssize_t (*__getdelim_orig) (char **lineptr, size_t *n, int delim, FILE *stream); #endif +/* Additional BSDisms */ +#ifdef HAVE_FGETLN +static char * (*fgetln_orig) (FILE *stream, size_t *len); +#endif + void _zz_load_stream(void) { LOADSYM(fopen); @@ -84,6 +89,9 @@ void _zz_load_stream(void) #ifdef HAVE___GETDELIM LOADSYM(__getdelim); #endif +#ifdef HAVE_FGETLN + LOADSYM(fgetln); +#endif } /* Our function wrappers */ @@ -383,3 +391,45 @@ ssize_t __getdelim(char **lineptr, size_t *n, int delim, FILE *stream) } #endif +#ifdef HAVE_FGETLN +char *fgetln(FILE *stream, size_t *len) +{ + struct fuzz *fuzz; + char *ret; + size_t i, size; + int fd; + + if(!_zz_ready) + LOADSYM(fgetln); + fd = fileno(stream); + if(!_zz_ready || !_zz_iswatched(fd)) + return fgetln_orig(stream, len); + + fuzz = _zz_getfuzz(fd); + + for(i = size = 0; fuzz.tmp[i] != '\n'; i++) + { + int ch; + + if(i >= size) + fuzz.tmp = realloc(fuzz.tmp, (size += 80)); + + _zz_disabled = 1; + ch = fgetc_orig(stream); + _zz_disabled = 0; + + if(ch == EOF) + break; + + fuzz.tmp[i] = (char)(unsigned char)ch; + _zz_fuzz(fd, (uint8_t *)fuzz.tmp + i, 1); /* rather inefficient */ + _zz_addpos(fd, 1); + } + + *len = size; + + debug("fgetln([%i], &%li) = %p", fd, (long int)*len, ret); + return ret; +} +#endif +