summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2009-06-25 22:45:12 +0200
committerLudovic Courtès <ludo@gnu.org>2009-06-25 22:45:12 +0200
commit376b6bd7a2d2484f5579645becc26c40a97c31a6 (patch)
tree0751d39d630b340b4059ca4edb0cb49055f27c1b
parent60ed31d28bd2d27efd98bf25556b7c785c46da52 (diff)
downloadguile-376b6bd7a2d2484f5579645becc26c40a97c31a6.tar.gz
Fix `load-objcode' FD/mapping leak occurring upon failure.
* libguile/objcodes.c (make_objcode_by_mmap): Close FD and unmap ADDR upon failure.
-rw-r--r--libguile/objcodes.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/libguile/objcodes.c b/libguile/objcodes.c
index fc59c09a4..03ea0b8d8 100644
--- a/libguile/objcodes.c
+++ b/libguile/objcodes.c
@@ -63,19 +63,31 @@ make_objcode_by_mmap (int fd)
addr = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED)
- SCM_SYSERROR;
+ {
+ (void) close (fd);
+ SCM_SYSERROR;
+ }
if (memcmp (addr, OBJCODE_COOKIE, strlen (OBJCODE_COOKIE)))
- scm_misc_error (FUNC_NAME, "bad header on object file: ~s",
- scm_list_1 (scm_from_locale_stringn
- (addr, strlen (OBJCODE_COOKIE))));
+ {
+ (void) close (fd);
+ (void) munmap (addr, st.st_size);
+ scm_misc_error (FUNC_NAME, "bad header on object file: ~s",
+ scm_list_1 (scm_from_locale_stringn
+ (addr, strlen (OBJCODE_COOKIE))));
+ }
data = (struct scm_objcode*)(addr + strlen (OBJCODE_COOKIE));
if (data->len + data->metalen != (st.st_size - sizeof (*data) - strlen (OBJCODE_COOKIE)))
- scm_misc_error (FUNC_NAME, "bad length header (~a, ~a)",
- scm_list_2 (scm_from_size_t (st.st_size),
- scm_from_uint32 (sizeof (*data) + data->len + data->metalen)));
+ {
+ (void) close (fd);
+ (void) munmap (addr, st.st_size);
+ scm_misc_error (FUNC_NAME, "bad length header (~a, ~a)",
+ scm_list_2 (scm_from_size_t (st.st_size),
+ scm_from_uint32 (sizeof (*data) + data->len
+ + data->metalen)));
+ }
SCM_NEWSMOB3 (sret, scm_tc16_objcode, addr + strlen (OBJCODE_COOKIE),
SCM_PACK (SCM_BOOL_F), fd);