[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)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] trunk r113444: * charset.c: Fix file descriptor leaks and errno issues.,
Paul Eggert <=