aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2012-09-28 20:11:09 +0300
committerLasse Collin <lasse.collin@tukaani.org>2012-09-28 20:11:09 +0300
commit3d93b6354927247a1569caf22ad27b07e97ee904 (patch)
tree10a4f20b99c0f7f145bff1bca7099e028420c5f5 /src
parentA few typo fixes to comments and the xz man page. (diff)
downloadxz-3d93b6354927247a1569caf22ad27b07e97ee904.tar.xz
xz: Improve handling of failed realloc in xrealloc.
Thanks to Jim Meyering.
Diffstat (limited to 'src')
-rw-r--r--src/xz/util.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/xz/util.c b/src/xz/util.c
index 987b4430..35850f4c 100644
--- a/src/xz/util.c
+++ b/src/xz/util.c
@@ -26,9 +26,19 @@ xrealloc(void *ptr, size_t size)
{
assert(size > 0);
+ // Save ptr so that we can free it if realloc fails.
+ // The point is that message_fatal ends up calling stdio functions
+ // which in some libc implementations might allocate memory from
+ // the heap. Freeing ptr improves the chances that there's free
+ // memory for stdio functions if they need it.
+ void *p = ptr;
ptr = realloc(ptr, size);
- if (ptr == NULL)
- message_fatal("%s", strerror(errno));
+
+ if (ptr == NULL) {
+ const int saved_errno = errno;
+ free(p);
+ message_fatal("%s", strerror(saved_errno));
+ }
return ptr;
}