diff options
author | Nikola Pajkovsky <npajkovs@redhat.com> | 2010-11-25 11:59:47 +0100 |
---|---|---|
committer | Nikola Pajkovsky <npajkovs@redhat.com> | 2010-11-25 11:59:47 +0100 |
commit | c10a64020b11dac3438210a067ef73e674fea2ca (patch) | |
tree | d4f1948a0ab4b414d2db77d0fbc750a15f8fedb3 | |
parent | 3ecab4513b98f34ce9185d91e378f2911b994afb (diff) | |
download | abrt-c10a64020b11dac3438210a067ef73e674fea2ca.tar.gz abrt-c10a64020b11dac3438210a067ef73e674fea2ca.tar.xz abrt-c10a64020b11dac3438210a067ef73e674fea2ca.zip |
backport xmalloc_fgets and xmalloc_fgetline
Signed-off-by: Nikola Pajkovsky <npajkovs@redhat.com>
-rw-r--r-- | inc/abrtlib.h | 4 | ||||
-rw-r--r-- | lib/Utils/Makefile.am | 1 | ||||
-rw-r--r-- | lib/Utils/stdio_helpers.cpp | 69 |
3 files changed, 74 insertions, 0 deletions
diff --git a/inc/abrtlib.h b/inc/abrtlib.h index 0e650059..fdf22643 100644 --- a/inc/abrtlib.h +++ b/inc/abrtlib.h @@ -99,6 +99,10 @@ extern int g_verbose; char* skip_whitespace(const char *s); char* skip_non_whitespace(const char *s); +/* A-la fgets, but malloced and of unlimited size */ +char *xmalloc_fgets(FILE *file); +/* Similar, but removes trailing \n */ +char *xmalloc_fgetline(FILE *file); #ifdef __cplusplus extern "C" { diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index 2951958f..b22e1177 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -12,6 +12,7 @@ AM_YFLAGS = --verbose libABRTUtils_la_SOURCES = \ xfuncs.cpp \ encbase64.cpp \ + stdio_helpers.cpp \ read_write.cpp \ logging.cpp \ copyfd.cpp \ diff --git a/lib/Utils/stdio_helpers.cpp b/lib/Utils/stdio_helpers.cpp new file mode 100644 index 00000000..6fc5f558 --- /dev/null +++ b/lib/Utils/stdio_helpers.cpp @@ -0,0 +1,69 @@ +/* + * Utility routines. + * + * Copyright (C) 2001 Matt Krai + * Copyright (C) 2004 Erik Andersen <andersen@codepoet.org> + * Copyright (C) 2005, 2006 Rob Landley <rob@landley.net> + * Copyright (C) 2010 ABRT Team + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +#include "abrtlib.h" + +//TODO: add sanitizing upper limit (e.g 64K, 1M, or configurable). +//This is why we don't use GNU's getline: it doesn't have +//any upper sanity bound on line size. + +static char *xmalloc_fgets_internal(FILE *file, int *sizep) +{ + unsigned idx = 0; + char *linebuf = NULL; + + while (1) { + char *r; + + linebuf = (char *)xrealloc(linebuf, idx + 0x100); + r = fgets(&linebuf[idx], 0x100, file); + if (!r) { + /* need to terminate the line */ + linebuf[idx] = '\0'; + break; + } + + /* stupid. fgets knows the len, it should report it somehow */ + unsigned len = strlen(&linebuf[idx]); + + idx += len; + if (len < 0xff || linebuf[idx - 1] == '\n') + break; /* we found \n or EOF */ + } + + *sizep = idx; + + if (!idx) { + /* The very first fgets returned NULL. It's EOF (or error) */ + free(linebuf); + linebuf = NULL; + } + return linebuf; +} + +char *xmalloc_fgets(FILE *file) +{ + int sz; + char *r = (char *)xmalloc_fgets_internal(file, &sz); + if (!r) + return r; + return (char *)xrealloc(r, sz + 1); +} + +char *xmalloc_fgetline(FILE *file) +{ + int sz; + char *r = (char *)xmalloc_fgets_internal(file, &sz); + if (!r) + return r; + if (r[sz - 1] == '\n') + r[--sz] = '\0'; + return (char *)xrealloc(r, sz + 1); +} |