emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r113444: * charset.c: Fix file descriptor leaks and


From: Paul Eggert
Subject: [Emacs-diffs] trunk r113444: * charset.c: Fix file descriptor leaks and errno issues.
Date: Thu, 18 Jul 2013 02:13:04 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 113444
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Wed 2013-07-17 19:12:59 -0700
message:
  * charset.c: Fix file descriptor leaks and errno issues.
  
  Include <errno.h>.
  (load_charset_map_from_file): Don't leak file descriptor on error.
  Use plain record_xmalloc since the allocation is larger than
  MAX_ALLOCA; that's simpler here.  Simplify test for exhaustion
  of entries.
  * eval.c (record_unwind_protect_nothing):
  * fileio.c (fclose_unwind):
  New functions.
  * lread.c (load_unwind): Remove.  All uses replaced by fclose_unwind.
  The replacement doesn't block input, but that no longer seems
  necessary.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/charset.c                  charset.c-20091113204419-o5vbwnq5f7feedwu-1075
  src/eval.c                     eval.c-20091113204419-o5vbwnq5f7feedwu-237
  src/fileio.c                   fileio.c-20091113204419-o5vbwnq5f7feedwu-210
  src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
  src/lread.c                    lread.c-20091113204419-o5vbwnq5f7feedwu-266
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-07-17 17:24:54 +0000
+++ b/src/ChangeLog     2013-07-18 02:12:59 +0000
@@ -1,3 +1,18 @@
+2013-07-18  Paul Eggert  <address@hidden>
+
+       * charset.c: Fix file descriptor leaks and errno issues.
+       Include <errno.h>.
+       (load_charset_map_from_file): Don't leak file descriptor on error.
+       Use plain record_xmalloc since the allocation is larger than
+       MAX_ALLOCA; that's simpler here.  Simplify test for exhaustion
+       of entries.
+       * eval.c (record_unwind_protect_nothing):
+       * fileio.c (fclose_unwind):
+       New functions.
+       * lread.c (load_unwind): Remove.  All uses replaced by fclose_unwind.
+       The replacement doesn't block input, but that no longer seems
+       necessary.
+
 2013-07-17  Paul Eggert  <address@hidden>
 
        * lread.c: Fix file descriptor leaks and errno issues.

=== modified file 'src/charset.c'
--- a/src/charset.c     2013-07-16 06:39:49 +0000
+++ b/src/charset.c     2013-07-18 02:12:59 +0000
@@ -28,6 +28,7 @@
 
 #define CHARSET_INLINE EXTERN_INLINE
 
+#include <errno.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <limits.h>
@@ -477,7 +478,8 @@
    `file-name-handler-alist' to avoid running any Lisp code.  */
 
 static void
-load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int 
control_flag)
+load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile,
+                           int control_flag)
 {
   unsigned min_code = CHARSET_MIN_CODE (charset);
   unsigned max_code = CHARSET_MAX_CODE (charset);
@@ -487,21 +489,26 @@
   struct charset_map_entries *head, *entries;
   int n_entries;
   ptrdiff_t count;
-  USE_SAFE_ALLOCA;
 
   suffixes = list2 (build_string (".map"), build_string (".TXT"));
 
   count = SPECPDL_INDEX ();
+  record_unwind_protect_nothing ();
   specbind (Qfile_name_handler_alist, Qnil);
   fd = openp (Vcharset_map_path, mapfile, suffixes, NULL, Qnil);
-  unbind_to (count, Qnil);
-  if (fd < 0
-      || ! (fp = fdopen (fd, "r")))
-    error ("Failure in loading charset map: %s", SDATA (mapfile));
+  fp = fd < 0 ? 0 : fdopen (fd, "r");
+  if (!fp)
+    {
+      int open_errno = errno;
+      emacs_close (fd);
+      report_file_errno ("Loading charset map", mapfile, open_errno);
+    }
+  set_unwind_protect_ptr (count, fclose_unwind, fp);
+  unbind_to (count + 1, Qnil);
 
-  /* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
+  /* Use record_xmalloc, as `charset_map_entries' is
      large (larger than MAX_ALLOCA).  */
-  head = SAFE_ALLOCA (sizeof *head);
+  head = record_xmalloc (sizeof *head);
   entries = head;
   memset (entries, 0, sizeof (struct charset_map_entries));
 
@@ -530,9 +537,9 @@
       if (from < min_code || to > max_code || from > to || c > MAX_CHAR)
        continue;
 
-      if (n_entries > 0 && (n_entries % 0x10000) == 0)
+      if (n_entries == 0x10000)
        {
-         entries->next = SAFE_ALLOCA (sizeof *entries->next);
+         entries->next = record_xmalloc (sizeof *entries->next);
          entries = entries->next;
          memset (entries, 0, sizeof (struct charset_map_entries));
          n_entries = 0;
@@ -544,9 +551,10 @@
       n_entries++;
     }
   fclose (fp);
+  clear_unwind_protect (count);
 
   load_charset_map (charset, head, n_entries, control_flag);
-  SAFE_FREE ();
+  unbind_to (count, Qnil);
 }
 
 static void

=== modified file 'src/eval.c'
--- a/src/eval.c        2013-07-17 17:24:54 +0000
+++ b/src/eval.c        2013-07-18 02:12:59 +0000
@@ -3190,6 +3190,8 @@
     }
 }
 
+/* Push unwind-protect entries of various types.  */
+
 void
 record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg)
 {
@@ -3229,6 +3231,18 @@
 do_nothing (void)
 {}
 
+/* Push an unwind-protect entry that does nothing, so that
+   set_unwind_protect_ptr can overwrite it later.  */
+
+void
+record_unwind_protect_nothing (void)
+{
+  record_unwind_protect_void (do_nothing);
+}
+
+/* Clear the unwind-protect entry COUNT, so that it does nothing.
+   It need not be at the top of the stack.  */
+
 void
 clear_unwind_protect (ptrdiff_t count)
 {
@@ -3237,6 +3251,10 @@
   p->unwind_void.func = do_nothing;
 }
 
+/* Set the unwind-protect entry COUNT so that it invokes FUNC (ARG).
+   It need not be at the top of the stack.  Discard the entry's
+   previous value without invoking it.  */
+
 void
 set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg)
 {
@@ -3246,6 +3264,9 @@
   p->unwind_ptr.arg = arg;
 }
 
+/* Pop and execute entries from the unwind-protect stack until the
+   depth COUNT is reached.  Return VALUE.  */
+
 Lisp_Object
 unbind_to (ptrdiff_t count, Lisp_Object value)
 {

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2013-07-17 17:24:54 +0000
+++ b/src/fileio.c      2013-07-18 02:12:59 +0000
@@ -220,6 +220,13 @@
   emacs_close (fd);
 }
 
+void
+fclose_unwind (void *arg)
+{
+  FILE *stream = arg;
+  fclose (stream);
+}
+
 /* Restore point, having saved it as a marker.  */
 
 void

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2013-07-17 17:24:54 +0000
+++ b/src/lisp.h        2013-07-18 02:12:59 +0000
@@ -3743,6 +3743,7 @@
 extern void record_unwind_protect_int (void (*) (int), int);
 extern void record_unwind_protect_ptr (void (*) (void *), void *);
 extern void record_unwind_protect_void (void (*) (void));
+extern void record_unwind_protect_nothing (void);
 extern void clear_unwind_protect (ptrdiff_t);
 extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
 extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
@@ -3827,6 +3828,7 @@
 extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
 EXFUN (Fread_file_name, 6);     /* Not a normal DEFUN.  */
 extern void close_file_unwind (int);
+extern void fclose_unwind (void *);
 extern void restore_point_unwind (Lisp_Object);
 extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
 extern _Noreturn void report_file_error (const char *, Lisp_Object);

=== modified file 'src/lread.c'
--- a/src/lread.c       2013-07-17 17:24:54 +0000
+++ b/src/lread.c       2013-07-18 02:12:59 +0000
@@ -145,7 +145,6 @@
 static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool,
                           Lisp_Object, Lisp_Object,
                           Lisp_Object, Lisp_Object);
-static void load_unwind (void *);
 
 /* Functions that read one byte from the current source READCHARFUN
    or unreads one byte.  If the integer argument C is -1, it returns
@@ -1317,7 +1316,7 @@
     }
   if (! stream)
     report_file_error ("Opening stdio stream", file);
-  set_unwind_protect_ptr (fd_index, load_unwind, stream);
+  set_unwind_protect_ptr (fd_index, fclose_unwind, stream);
 
   if (! NILP (Vpurify_flag))
     Vpreloaded_file_list = Fcons (Fpurecopy (file), Vpreloaded_file_list);
@@ -1387,18 +1386,6 @@
 
   return Qt;
 }
-
-static void
-load_unwind (void *arg)
-{
-  FILE *stream = arg;
-  if (stream != NULL)
-    {
-      block_input ();
-      fclose (stream);
-      unblock_input ();
-    }
-}
 
 static bool
 complete_filename_p (Lisp_Object pathname)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]