2004-11-22 Stepan Kasal This is a variant of Jim Meyering's patch: When grep runs out of memory, don't abort the entire command, but rather just the affected command line argument(s). * src/grep.c (reset): Allocate a new buffer whenever buffer == NULL. (buffer, pagesize): Initialize, so that the code in reset works. (fillbuf): If the size of the buffer overflows size_t, free the buffer and exit with errno=ENOMEM; if malloc fails, exit with the errno it gave us, freeing the buffer first. Index: src/grep.c =================================================================== RCS file: /cvsroot/grep/grep/src/grep.c,v retrieving revision 1.85 diff -u -p -r1.85 grep.c --- src/grep.c 22 Nov 2004 09:53:26 -0000 1.85 +++ src/grep.c 22 Nov 2004 16:01:52 -0000 @@ -211,13 +211,13 @@ context_length_arg (char const *str, int all reads aligned on a page boundary and multiples of the page size, unless a read yields a partial page. */ -static char *buffer; /* Base of buffer. */ +static char *buffer = NULL; /* Base of buffer. */ static size_t bufalloc; /* Allocated buffer size, counting slop. */ #define INITIAL_BUFSIZE 32768 /* Initial buffer size, not counting slop. */ static int bufdesc; /* File descriptor. */ static char *bufbeg; /* Beginning of user-visible stuff. */ static char *buflim; /* Limit of user-visible stuff. */ -static size_t pagesize; /* alignment of memory pages */ +static size_t pagesize = 0; /* alignment of memory pages */ static off_t bufoffset; /* Read offset; defined on regular files. */ static off_t after_last_match; /* Pointer after last matching line that would have been output if we were @@ -242,11 +242,14 @@ static off_t initial_bufoffset; /* Initi static int reset (int fd, char const *file, struct stats *stats) { - if (! pagesize) + if (buffer == NULL) { - pagesize = getpagesize (); - if (pagesize == 0 || 2 * pagesize + 1 <= pagesize) - abort (); + if (pagesize == 0) + { + pagesize = getpagesize (); + if (pagesize == 0 || 2 * pagesize + 1 <= pagesize) + abort (); + } bufalloc = ALIGN_TO (INITIAL_BUFSIZE, pagesize) + pagesize + 1; buffer = xmalloc (bufalloc); } @@ -313,7 +316,12 @@ fillbuf (size_t save, struct stats const /* Grow newsize until it is at least as great as minsize. */ for (newsize = bufalloc - pagesize - 1; newsize < minsize; newsize *= 2) if (newsize * 2 < newsize || newsize * 2 + pagesize + 1 < newsize * 2) - xalloc_die (); + { + free (buffer); + buffer = NULL; + errno = ENOMEM; + return 0; + } /* Try not to allocate more memory than the file size indicates, as that might cause unnecessary memory exhaustion if the file @@ -335,7 +343,15 @@ fillbuf (size_t save, struct stats const for byte sentinels fore and aft. */ newalloc = newsize + pagesize + 1; - newbuf = bufalloc < newalloc ? xmalloc (bufalloc = newalloc) : buffer; + newbuf = bufalloc < newalloc ? malloc (bufalloc = newalloc) : buffer; + if (newbuf == NULL) + { + int saved_errno = errno; + free (buffer); + buffer = NULL; + errno = saved_errno; + return 0; + } readbuf = ALIGN_TO (newbuf + 1 + save, pagesize); bufbeg = readbuf - save; memmove (bufbeg, buffer + saved_offset, save);