From a8cd4836451373f56b719cf3b80fb3344a3422db Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 18 Jul 2013 02:55:00 -0700 Subject: [PATCH] * doc.c: Fix minor memory and file descriptor leaks. * doc.c (get_doc_string): Fix memory leak when doc file absent. (get_doc_string, Fsnarf_documentation): Fix file descriptor leak on error. --- src/ChangeLog | 5 +++++ src/doc.c | 33 +++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6c9cfaa741..cdc56419f6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2013-07-18 Paul Eggert + * doc.c: Fix minor memory and file descriptor leaks. + * doc.c (get_doc_string): Fix memory leak when doc file absent. + (get_doc_string, Fsnarf_documentation): + Fix file descriptor leak on error. + * term.c: Fix minor fdopen-related file descriptor leaks. * term.c (Fresume_tty) [!MSDOS]: Close fd if fdopen (fd) fails. (init_tty) [!DOS_NT]: Likewise. Also close fd if isatty (fd) fails. diff --git a/src/doc.c b/src/doc.c index 168af6da94..009616f4f8 100644 --- a/src/doc.c +++ b/src/doc.c @@ -85,6 +85,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) int offset; EMACS_INT position; Lisp_Object file, tem, pos; + ptrdiff_t count; USE_SAFE_ALLOCA; if (INTEGERP (filepos)) @@ -144,9 +145,14 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) } #endif if (fd < 0) - return concat3 (build_string ("Cannot open doc string file \""), - file, build_string ("\"\n")); + { + SAFE_FREE (); + return concat3 (build_string ("Cannot open doc string file \""), + file, build_string ("\"\n")); + } } + count = SPECPDL_INDEX (); + record_unwind_protect_int (close_file_unwind, fd); /* Seek only to beginning of disk block. */ /* Make sure we read at least 1024 bytes before `position' @@ -154,13 +160,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) offset = min (position, max (1024, position % (8 * 1024))); if (TYPE_MAXIMUM (off_t) < position || lseek (fd, position - offset, 0) < 0) - { - emacs_close (fd); - error ("Position %"pI"d out of range in doc string file \"%s\"", - position, name); - } - - SAFE_FREE (); + error ("Position %"pI"d out of range in doc string file \"%s\"", + position, name); /* Read the doc string into get_doc_string_buffer. P points beyond the data just read. */ @@ -190,10 +191,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) space_left = 1024 * 8; nread = emacs_read (fd, p, space_left); if (nread < 0) - { - emacs_close (fd); - error ("Read error on documentation file"); - } + report_file_error ("Read error on documentation file", file); p[nread] = 0; if (!nread) break; @@ -209,7 +207,8 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) } p += nread; } - emacs_close (fd); + unbind_to (count, Qnil); + SAFE_FREE (); /* Sanity checking. */ if (CONSP (filepos)) @@ -574,6 +573,7 @@ the same file name is found in the `doc-directory'. */) Lisp_Object sym; char *p, *name; bool skip_file = 0; + ptrdiff_t count; CHECK_STRING (filename); @@ -615,6 +615,8 @@ the same file name is found in the `doc-directory'. */) report_file_errno ("Opening doc string file", build_string (name), open_errno); } + count = SPECPDL_INDEX (); + record_unwind_protect_int (close_file_unwind, fd); Vdoc_file_name = filename; filled = 0; pos = 0; @@ -692,8 +694,7 @@ the same file name is found in the `doc-directory'. */) filled -= end - buf; memmove (buf, end, filled); } - emacs_close (fd); - return Qnil; + return unbind_to (count, Qnil); } DEFUN ("substitute-command-keys", Fsubstitute_command_keys, -- 2.20.1