diff options
| author | Paul Eggert | 2011-05-30 09:47:35 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-05-30 09:47:35 -0700 |
| commit | 531b01656f89e093b9fa35959fa41e534b025320 (patch) | |
| tree | 190b5a279e0e8e0130b6ba070fa217ce1282e2f3 /lib | |
| parent | de677ace77fa48962be80b668662a7009498e5d6 (diff) | |
| download | emacs-531b01656f89e093b9fa35959fa41e534b025320.tar.gz emacs-531b01656f89e093b9fa35959fa41e534b025320.zip | |
[ChangeLog]
Malloc failure behavior now depends on size of allocation.
* lib/allocator.h (struct allocator.die): New size arg.
* lib/careadlinkat.c (careadlinkat): Pass size to 'die' function.
If the actual problem is an ssize_t limitation, not a size_t or
malloc failure, fail with errno == ENAMETOOLONG instead of calling 'die'.
[src/ChangeLog]
Malloc failure behavior now depends on size of allocation.
* alloc.c (buffer_memory_full, memory_full): New arg NBYTES.
* lisp.h: Change signatures accordingly.
* alloc.c, buffer.c, editfns.c, menu.c, minibuf.c, xterm.c:
All callers changed.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/allocator.h | 9 | ||||
| -rw-r--r-- | lib/careadlinkat.c | 8 |
2 files changed, 12 insertions, 5 deletions
diff --git a/lib/allocator.h b/lib/allocator.h index 953117da83f..b8de95c0f50 100644 --- a/lib/allocator.h +++ b/lib/allocator.h | |||
| @@ -45,10 +45,11 @@ struct allocator | |||
| 45 | /* Call FREE to free memory, like 'free'. */ | 45 | /* Call FREE to free memory, like 'free'. */ |
| 46 | void (*free) (void *); | 46 | void (*free) (void *); |
| 47 | 47 | ||
| 48 | /* If nonnull, call DIE if MALLOC or REALLOC fails. DIE should not | 48 | /* If nonnull, call DIE (SIZE) if MALLOC (SIZE) or REALLOC (..., |
| 49 | return. DIE can be used by code that detects memory overflow | 49 | SIZE) fails. DIE should not return. SIZE should equal SIZE_MAX |
| 50 | while calculating sizes to be passed to MALLOC or REALLOC. */ | 50 | if size_t overflow was detected while calculating sizes to be |
| 51 | void (*die) (void); | 51 | passed to MALLOC or REALLOC. */ |
| 52 | void (*die) (size_t); | ||
| 52 | }; | 53 | }; |
| 53 | 54 | ||
| 54 | /* An allocator using the stdlib functions and a null DIE function. */ | 55 | /* An allocator using the stdlib functions and a null DIE function. */ |
diff --git a/lib/careadlinkat.c b/lib/careadlinkat.c index e2909c766d5..6e4aa1395ff 100644 --- a/lib/careadlinkat.c +++ b/lib/careadlinkat.c | |||
| @@ -135,6 +135,7 @@ careadlinkat (int fd, char const *filename, | |||
| 135 | if (buf == stack_buf) | 135 | if (buf == stack_buf) |
| 136 | { | 136 | { |
| 137 | char *b = (char *) alloc->allocate (link_size); | 137 | char *b = (char *) alloc->allocate (link_size); |
| 138 | buf_size = link_size; | ||
| 138 | if (! b) | 139 | if (! b) |
| 139 | break; | 140 | break; |
| 140 | memcpy (b, buf, link_size); | 141 | memcpy (b, buf, link_size); |
| @@ -158,6 +159,11 @@ careadlinkat (int fd, char const *filename, | |||
| 158 | buf_size *= 2; | 159 | buf_size *= 2; |
| 159 | else if (buf_size < buf_size_max) | 160 | else if (buf_size < buf_size_max) |
| 160 | buf_size = buf_size_max; | 161 | buf_size = buf_size_max; |
| 162 | else if (buf_size_max < SIZE_MAX) | ||
| 163 | { | ||
| 164 | errno = ENAMETOOLONG; | ||
| 165 | return NULL; | ||
| 166 | } | ||
| 161 | else | 167 | else |
| 162 | break; | 168 | break; |
| 163 | buf = (char *) alloc->allocate (buf_size); | 169 | buf = (char *) alloc->allocate (buf_size); |
| @@ -165,7 +171,7 @@ careadlinkat (int fd, char const *filename, | |||
| 165 | while (buf); | 171 | while (buf); |
| 166 | 172 | ||
| 167 | if (alloc->die) | 173 | if (alloc->die) |
| 168 | alloc->die (); | 174 | alloc->die (buf_size); |
| 169 | errno = ENOMEM; | 175 | errno = ENOMEM; |
| 170 | return NULL; | 176 | return NULL; |
| 171 | } | 177 | } |