From c7ddc792b747fdf4fde822df0cf9c7b712be4219 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 16 Jul 2013 00:05:41 -0700 Subject: Fix porting bug to older POSIXish platforms. * sysdep.c (emacs_pipe): New function, that implements pipe2 (fd, O_CLOEXEC) even on hosts that lack O_CLOEXEC. This should port better to CentOS 5 and to Mac OS X 10.6. All calls to pipe2 changed. Fixes: debbugs:14862 --- src/alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/alloc.c') diff --git a/src/alloc.c b/src/alloc.c index b71cdb98d78..b52e3de0494 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4741,7 +4741,7 @@ valid_pointer_p (void *p) Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may not validate p in that case. */ - if (pipe2 (fd, O_CLOEXEC) == 0) + if (emacs_pipe (fd) == 0) { bool valid = emacs_write (fd[1], (char *) p, 16) == 16; emacs_close (fd[1]); -- cgit v1.2.1 From 27e498e6e5fea8ac64c90ac13678b537b7b12302 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 16 Jul 2013 14:35:45 -0700 Subject: New unwind-protect flavors to better type-check C callbacks. This also lessens the need to write wrappers for callbacks, and the need for make_save_pointer. * alloca.c (free_save_value): * atimer.c (run_all_atimers): Now extern. * alloc.c (safe_alloca_unwind): * atimer.c (unwind_stop_other_atimers): * keyboard.c (cancel_hourglass_unwind) [HAVE_WINDOW_SYSTEM]: * menu.c (cleanup_popup_menu) [HAVE_NS]: * minibuf.c (choose_minibuf_frame_1): * process.c (make_serial_process_unwind): * xdisp.h (pop_message_unwind): * xselect.c (queue_selection_requests_unwind): Remove no-longer-needed wrapper. All uses replaced by the wrappee. * alloca.c (record_xmalloc): Prefer record_unwind_protect_ptr to record_unwind_protect with make_save_pointer. * alloca.c (Fgarbage_collect): Prefer record_unwind_protect_void to passing a dummy. * buffer.c (restore_buffer): * window.c (restore_window_configuration): * xfns.c, w32fns.c (do_unwind_create_frame) New wrapper. All record-unwind uses of wrappee changed. * buffer.c (set_buffer_if_live): * callproc.c (call_process_cleanup, delete_temp_file): * coding.c (code_conversion_restore): * dired.c (directory_files_internal_w32_unwind) [WINDOWSNT]: * editfns.c (save_excursion_restore) (subst_char_in_region_unwind, subst_char_in_region_unwind_1) (save_restriction_restore): * eval.c (restore_stack_limits, un_autoload): * fns.c (require_unwind): * keyboard.c (recursive_edit_unwind, tracking_off): * lread.c (record_load_unwind, load_warn_old_style_backquotes): * macros.c (pop_kbd_macro, restore_menu_items): * nsfns.m (unwind_create_frame): * print.c (print_unwind): * process.c (start_process_unwind): * search.c (unwind_set_match_data): * window.c (select_window_norecord, select_frame_norecord): * xdisp.c (unwind_with_echo_area_buffer, unwind_format_mode_line) (fast_set_selected_frame): * xfns.c, w32fns.c (unwind_create_tip_frame): Return void, not a dummy Lisp_Object. All uses changed. * buffer.h (set_buffer_if_live): Move decl here from lisp.h. * callproc.c (call_process_kill): * fileio.c (restore_point_unwind, decide_coding_unwind) (build_annotations_unwind): * insdel.c (Fcombine_after_change_execute_1): * keyboard.c (read_char_help_form_unwind): * menu.c (unuse_menu_items): * minibuf.c (run_exit_minibuf_hook, read_minibuf_unwind): * sound.c (sound_cleanup): * xdisp.c (unwind_redisplay): * xfns.c (clean_up_dialog): * xselect.c (x_selection_request_lisp_error, x_catch_errors_unwind): Accept no args and return void, instead of accepting and returning a dummy Lisp_Object. All uses changed. * cygw32.c (fchdir_unwind): * fileio.c (close_file_unwind): * keyboard.c (restore_kboard_configuration): * lread.c (readevalllop_1): * process.c (wait_reading_process_output_unwind): Accept int and return void, rather than accepting an Emacs integer and returning a dummy object. In some cases this fixes an unlikely bug when the corresponding int is outside Emacs integer range. All uses changed. * dired.c (directory_files_internal_unwind): * fileio.c (do_auto_save_unwind): * gtkutil.c (pop_down_dialog): * insdel.c (reset_var_on_error): * lread.c (load_unwind): * xfns.c (clean_up_file_dialog): * xmenu.c, nsmenu.m (pop_down_menu): * xmenu.c (cleanup_widget_value_tree): * xselect.c (wait_for_property_change_unwind): Accept pointer and return void, rather than accepting an Emacs save value encapsulating the pointer and returning a dummy object. All uses changed. * editfns.c (Fformat): Update the saved pointer directly via set_unwind_protect_ptr rather than indirectly via make_save_pointer. * eval.c (specpdl_func): Remove. All uses replaced by definiens. (unwind_body): New function. (record_unwind_protect): First arg is now a function returning void, not a dummy Lisp_Object. (record_unwind_protect_ptr, record_unwind_protect_int) (record_unwind_protect_void): New functions. (unbind_to): Support SPECPDL_UNWIND_PTR etc. * fileio.c (struct auto_save_unwind): New type. (do_auto_save_unwind): Use it. (do_auto_save_unwind_1): Remove; subsumed by new do_auto_save_unwind. * insdel.c (struct rvoe_arg): New type. (reset_var_on_error): Use it. * lisp.h (SPECPDL_UNWIND_PTR, SPECPDL_UNWIND_INT, SPECPDL_UNWIND_VOID): New constants. (specbinding_func): Remove; there are now several such functions. (union specbinding): New members unwind_ptr, unwind_int, unwind_void. (set_unwind_protect_ptr): New function. * xselect.c: Remove unnecessary forward decls, to simplify maintenance. --- src/alloc.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'src/alloc.c') diff --git a/src/alloc.c b/src/alloc.c index b52e3de0494..39f6a82b138 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -209,7 +209,6 @@ Lisp_Object Qchar_table_extra_slots; static Lisp_Object Qpost_gc_hook; -static void free_save_value (Lisp_Object); static void mark_terminals (void); static void gc_sweep (void); static Lisp_Object make_pure_vector (ptrdiff_t); @@ -813,22 +812,13 @@ xputenv (char const *string) memory_full (0); } -/* Unwind for SAFE_ALLOCA */ - -Lisp_Object -safe_alloca_unwind (Lisp_Object arg) -{ - free_save_value (arg); - return Qnil; -} - /* Return a newly allocated memory block of SIZE bytes, remembering to free it when unwinding. */ void * record_xmalloc (size_t size) { void *p = xmalloc (size); - record_unwind_protect (safe_alloca_unwind, make_save_pointer (p)); + record_unwind_protect_ptr (xfree, p); return p; } @@ -3397,7 +3387,9 @@ make_save_value (enum Lisp_Save_Type save_type, ...) return val; } -/* The most common task it to save just one C pointer. */ +/* Save just one C pointer. record_unwind_protect_ptr is simpler and + faster than combining this with record_unwind_protect, but + occasionally this function is useful for other reasons. */ Lisp_Object make_save_pointer (void *pointer) @@ -3412,7 +3404,7 @@ make_save_pointer (void *pointer) /* Free a Lisp_Save_Value object. Do not use this function if SAVE contains pointer other than returned by xmalloc. */ -static void +void free_save_value (Lisp_Object save) { xfree (XSAVE_POINTER (save, 0)); @@ -5227,7 +5219,7 @@ See Info node `(elisp)Garbage Collection'. */) /* Save what's currently displayed in the echo area. */ message_p = push_message (); - record_unwind_protect (pop_message_unwind, Qnil); + record_unwind_protect_void (pop_message_unwind); /* Save a copy of the contents of the stack, for debugging. */ #if MAX_SAVE_STACK > 0 -- cgit v1.2.1 From 1396ac86dea5fccab800e4b25fdb5319381891eb Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Thu, 18 Jul 2013 18:24:35 -0700 Subject: Fix obscure porting bug with varargs functions. The code assumed that int is treated like ptrdiff_t in a vararg function, which is not a portable assumption. There was a similar -- though these days less likely -- porting problem with various assumptions that pointers of different types all smell the same as far as vararg functions is conserved. To make this problem less likely in the future, redo the API to use varargs functions. * alloc.c (make_save_value): Remove this vararg function. All uses changed to ... (make_save_int_int_int, make_save_obj_obj_obj_obj) (make_save_ptr_int, make_save_funcptr_ptr_obj, make_save_memory): New functions. (make_save_ptr): Rename from make_save_pointer, for consistency with the above. Define only on platforms that need it. All uses changed. --- src/alloc.c | 97 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 39 deletions(-) (limited to 'src/alloc.c') diff --git a/src/alloc.c b/src/alloc.c index 39f6a82b138..11245741bd5 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -3342,62 +3342,81 @@ verify (((SAVE_INTEGER | SAVE_POINTER | SAVE_FUNCPOINTER | SAVE_OBJECT) >> SAVE_SLOT_BITS) == 0); -/* Return a Lisp_Save_Value object with the data saved according to - DATA_TYPE. DATA_TYPE should be one of SAVE_TYPE_INT_INT, etc. */ +/* Return Lisp_Save_Value objects for the various combinations + that callers need. */ Lisp_Object -make_save_value (enum Lisp_Save_Type save_type, ...) +make_save_int_int_int (ptrdiff_t a, ptrdiff_t b, ptrdiff_t c) { - va_list ap; - int i; Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); struct Lisp_Save_Value *p = XSAVE_VALUE (val); + p->save_type = SAVE_TYPE_INT_INT_INT; + p->data[0].integer = a; + p->data[1].integer = b; + p->data[2].integer = c; + return val; +} - eassert (0 < save_type - && (save_type < 1 << (SAVE_TYPE_BITS - 1) - || save_type == SAVE_TYPE_MEMORY)); - p->save_type = save_type; - va_start (ap, save_type); - save_type &= ~ (1 << (SAVE_TYPE_BITS - 1)); - - for (i = 0; save_type; i++, save_type >>= SAVE_SLOT_BITS) - switch (save_type & ((1 << SAVE_SLOT_BITS) - 1)) - { - case SAVE_POINTER: - p->data[i].pointer = va_arg (ap, void *); - break; - - case SAVE_FUNCPOINTER: - p->data[i].funcpointer = va_arg (ap, voidfuncptr); - break; - - case SAVE_INTEGER: - p->data[i].integer = va_arg (ap, ptrdiff_t); - break; +Lisp_Object +make_save_obj_obj_obj_obj (Lisp_Object a, Lisp_Object b, Lisp_Object c, + Lisp_Object d) +{ + Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); + struct Lisp_Save_Value *p = XSAVE_VALUE (val); + p->save_type = SAVE_TYPE_OBJ_OBJ_OBJ_OBJ; + p->data[0].object = a; + p->data[1].object = b; + p->data[2].object = c; + p->data[3].object = d; + return val; +} - case SAVE_OBJECT: - p->data[i].object = va_arg (ap, Lisp_Object); - break; +#if defined HAVE_NS || defined DOS_NT +Lisp_Object +make_save_ptr (void *a) +{ + Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); + struct Lisp_Save_Value *p = XSAVE_VALUE (val); + p->save_type = SAVE_POINTER; + p->data[0].pointer = a; + return val; +} +#endif - default: - emacs_abort (); - } +Lisp_Object +make_save_ptr_int (void *a, ptrdiff_t b) +{ + Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); + struct Lisp_Save_Value *p = XSAVE_VALUE (val); + p->save_type = SAVE_TYPE_PTR_INT; + p->data[0].pointer = a; + p->data[1].integer = b; + return val; +} - va_end (ap); +Lisp_Object +make_save_funcptr_ptr_obj (void (*a) (void), void *b, Lisp_Object c) +{ + Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); + struct Lisp_Save_Value *p = XSAVE_VALUE (val); + p->save_type = SAVE_TYPE_FUNCPTR_PTR_OBJ; + p->data[0].funcpointer = a; + p->data[1].pointer = b; + p->data[2].object = c; return val; } -/* Save just one C pointer. record_unwind_protect_ptr is simpler and - faster than combining this with record_unwind_protect, but - occasionally this function is useful for other reasons. */ +/* Return a Lisp_Save_Value object that represents an array A + of N Lisp objects. */ Lisp_Object -make_save_pointer (void *pointer) +make_save_memory (Lisp_Object *a, ptrdiff_t n) { Lisp_Object val = allocate_misc (Lisp_Misc_Save_Value); struct Lisp_Save_Value *p = XSAVE_VALUE (val); - p->save_type = SAVE_POINTER; - p->data[0].pointer = pointer; + p->save_type = SAVE_TYPE_MEMORY; + p->data[0].pointer = a; + p->data[1].integer = n; return val; } -- cgit v1.2.1 From 4195afc389bb0e5ed5aa749e7606a710e07a72d1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 19 Jul 2013 10:54:26 -0700 Subject: * alloc.c (staticpro): Avoid buffer overrun on repeated calls. (NSTATICS): Now a constant; doesn't need to be a macro. --- src/alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/alloc.c') diff --git a/src/alloc.c b/src/alloc.c index 11245741bd5..4c924f72384 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -341,7 +341,7 @@ struct gcpro *gcprolist; /* Addresses of staticpro'd variables. Initialize it to a nonzero value; otherwise some compilers put it into BSS. */ -#define NSTATICS 0x800 +enum { NSTATICS = 2048 }; static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag}; /* Index of next unused slot in staticvec. */ @@ -5136,9 +5136,9 @@ Does not copy symbols. Copies strings without text properties. */) void staticpro (Lisp_Object *varaddress) { - staticvec[staticidx++] = varaddress; if (staticidx >= NSTATICS) fatal ("NSTATICS too small; try increasing and recompiling Emacs."); + staticvec[staticidx++] = varaddress; } -- cgit v1.2.1