summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sort.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/sort.c b/src/sort.c
index 952bfe8aa..d6b46f5df 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -698,12 +698,23 @@ sort_buffer_size (FILE *const *fps, int nfps,
static void
initbuf (struct buffer *buf, size_t line_bytes, size_t alloc)
{
- /* Ensure that the line array is properly aligned. */
- alloc += sizeof (struct line) - alloc % sizeof (struct line);
+ /* Ensure that the line array is properly aligned. If the desired
+ size cannot be allocated, repeatedly halve it until allocation
+ succeeds. The smaller allocation may hurt overall performance,
+ but that's better than failing. */
+ for (;;)
+ {
+ alloc += sizeof (struct line) - alloc % sizeof (struct line);
+ buf->buf = malloc (alloc);
+ if (buf->buf)
+ break;
+ alloc /= 2;
+ if (alloc <= line_bytes + 1)
+ xalloc_die ();
+ }
buf->line_bytes = line_bytes;
buf->alloc = alloc;
- buf->buf = xmalloc (buf->alloc);
buf->used = buf->left = buf->nlines = 0;
buf->eof = 0;
}