diff options
| author | Bill Wohler | 2012-12-08 17:19:00 -0800 |
|---|---|---|
| committer | Bill Wohler | 2012-12-08 17:19:00 -0800 |
| commit | e1b489df7af8f7034f8c2ef275b786e93a39df31 (patch) | |
| tree | 2edc9307185e2c77b98fe75f6d7eb0476c58c7e3 /src | |
| parent | ce974958f93ffa2e1bd01b4dd85dcb8ec1395787 (diff) | |
| parent | c6c08d3f8fe4d2c9e588189e46d60a30ef3e8d20 (diff) | |
| download | emacs-e1b489df7af8f7034f8c2ef275b786e93a39df31.tar.gz emacs-e1b489df7af8f7034f8c2ef275b786e93a39df31.zip | |
Merge from trunk; up to 2012-12-09T01:04:43Z!rgm@gnu.org.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 377 | ||||
| -rw-r--r-- | src/alloc.c | 41 | ||||
| -rw-r--r-- | src/buffer.c | 25 | ||||
| -rw-r--r-- | src/buffer.h | 5 | ||||
| -rw-r--r-- | src/bytecode.c | 4 | ||||
| -rw-r--r-- | src/callproc.c | 363 | ||||
| -rw-r--r-- | src/casefiddle.c | 2 | ||||
| -rw-r--r-- | src/charset.c | 4 | ||||
| -rw-r--r-- | src/data.c | 8 | ||||
| -rw-r--r-- | src/dbusbind.c | 2 | ||||
| -rw-r--r-- | src/dired.c | 46 | ||||
| -rw-r--r-- | src/dispextern.h | 12 | ||||
| -rw-r--r-- | src/doc.c | 8 | ||||
| -rw-r--r-- | src/doprnt.c | 5 | ||||
| -rw-r--r-- | src/editfns.c | 302 | ||||
| -rw-r--r-- | src/emacs.c | 9 | ||||
| -rw-r--r-- | src/fileio.c | 28 | ||||
| -rw-r--r-- | src/font.c | 15 | ||||
| -rw-r--r-- | src/fontset.c | 2 | ||||
| -rw-r--r-- | src/frame.c | 188 | ||||
| -rw-r--r-- | src/frame.h | 10 | ||||
| -rw-r--r-- | src/gmalloc.c | 8 | ||||
| -rw-r--r-- | src/gnutls.c | 14 | ||||
| -rw-r--r-- | src/gtkutil.c | 15 | ||||
| -rw-r--r-- | src/insdel.c | 21 | ||||
| -rw-r--r-- | src/keyboard.c | 14 | ||||
| -rw-r--r-- | src/lisp.h | 16 | ||||
| -rw-r--r-- | src/lread.c | 2 | ||||
| -rw-r--r-- | src/nsfns.m | 14 | ||||
| -rw-r--r-- | src/nsterm.m | 1 | ||||
| -rw-r--r-- | src/process.c | 354 | ||||
| -rw-r--r-- | src/process.h | 23 | ||||
| -rw-r--r-- | src/sysdep.c | 113 | ||||
| -rw-r--r-- | src/syssignal.h | 20 | ||||
| -rw-r--r-- | src/syswait.h | 7 | ||||
| -rw-r--r-- | src/term.c | 4 | ||||
| -rw-r--r-- | src/termchar.h | 20 | ||||
| -rw-r--r-- | src/textprop.c | 24 | ||||
| -rw-r--r-- | src/unexcoff.c | 6 | ||||
| -rw-r--r-- | src/vm-limit.c | 75 | ||||
| -rw-r--r-- | src/w32.c | 52 | ||||
| -rw-r--r-- | src/w32common.h | 2 | ||||
| -rw-r--r-- | src/w32fns.c | 19 | ||||
| -rw-r--r-- | src/w32proc.c | 43 | ||||
| -rw-r--r-- | src/w32term.c | 35 | ||||
| -rw-r--r-- | src/w32term.h | 2 | ||||
| -rw-r--r-- | src/window.c | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 118 | ||||
| -rw-r--r-- | src/xfns.c | 14 | ||||
| -rw-r--r-- | src/xterm.c | 51 |
50 files changed, 1362 insertions, 1185 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c612c4dd365..222be9575b8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,380 @@ | |||
| 1 | 2012-12-08 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * w32.c (unsetenv): Return 0 if the input string is too long. | ||
| 4 | |||
| 5 | 2012-12-08 Paul Eggert <eggert@cs.ucla.edu> | ||
| 6 | |||
| 7 | Use putenv+unsetenv instead of modifying environ directly (Bug#13070). | ||
| 8 | * alloc.c (xputenv): New function. | ||
| 9 | * dbusbind.c (Fdbus_init_bus): | ||
| 10 | * emacs.c (main): | ||
| 11 | * xterm.c (x_term_init): | ||
| 12 | Use xputenv instead of setenv or putenv, to detect memory exhaustion. | ||
| 13 | * editfns.c (initial_tz): Move static var decl up. | ||
| 14 | (tzvalbuf_in_environ): New static var. | ||
| 15 | (init_editfns): Initialize these two static vars. | ||
| 16 | (Fencode_time): Don't assume arbitrary limit on EMACS_INT width. | ||
| 17 | Save old TZ value on stack, if it's small. | ||
| 18 | (Fencode_time, set_time_zone_rule): Don't modify 'environ' directly; | ||
| 19 | instead, use xputenv+unsetenv to set and restore TZ. | ||
| 20 | (environbuf): Remove static var. All uses removed. | ||
| 21 | (Fset_time_zone_rule): Do not save TZ and environ; | ||
| 22 | no longer needed here. | ||
| 23 | (set_time_zone_rule_tz1, set_time_zone_rule_tz2) [LOCALTIME_CACHE]: | ||
| 24 | Move to inside set_time_zone_rule; they don't need file scope any more. | ||
| 25 | (set_time_zone_rule): Maintain the TZ=value string separately. | ||
| 26 | (syms_of_editfns): Don't initialize initial_tz; | ||
| 27 | init_editfns now does it. | ||
| 28 | * emacs.c (dump_tz) [HAVE_TZSET]: Now const. | ||
| 29 | * lisp.h (xputenv): New decl. | ||
| 30 | |||
| 31 | 2012-12-08 Fabrice Popineau <fabrice.popineau@gmail.com> | ||
| 32 | |||
| 33 | * w32fns.c (emacs_abort): Don't do arithmetics on void pointers. | ||
| 34 | |||
| 35 | 2012-12-08 Eli Zaretskii <eliz@gnu.org> | ||
| 36 | |||
| 37 | * w32.c (unsetenv, sys_putenv): New functions. | ||
| 38 | |||
| 39 | 2012-12-08 Chong Yidong <cyd@gnu.org> | ||
| 40 | |||
| 41 | * editfns.c (Finsert_char): Make the error message more | ||
| 42 | informative (Bug#12992). | ||
| 43 | |||
| 44 | 2012-12-08 Paul Eggert <eggert@cs.ucla.edu> | ||
| 45 | |||
| 46 | Simplify get_lim_data. | ||
| 47 | * vm-limit.c (get_lim_data): Combine RLIMIT_AS and RLIMIT_DATA methods. | ||
| 48 | Remove USG and vlimit methods; no longer used these days. | ||
| 49 | Add #error catchall just in case. | ||
| 50 | |||
| 51 | Assume POSIX 1003.1-1988 or later for signal.h (Bug#13026). | ||
| 52 | Exceptions: do not assume SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, | ||
| 53 | SIGTTOU, SIGUSR1, SIGUSR2, as Microsoft platforms lack these. | ||
| 54 | * process.c [subprocesses]: Include <c-ctype.h>, <sig2str.h>. | ||
| 55 | (deleted_pid_list, Fdelete_process, create_process) | ||
| 56 | (record_child_status_change, handle_child_signal, deliver_child_signal) | ||
| 57 | (init_process_emacs, syms_of_process): | ||
| 58 | Assume SIGCHLD is defined. | ||
| 59 | (parse_signal): Remove. All uses removed. | ||
| 60 | (abbr_to_signal): New static function. | ||
| 61 | (Fsignal_process): Use it to convert signal names to ints. | ||
| 62 | * sysdep.c (sys_suspend) [!DOS_NT]: Use kill (0, ...) rather than | ||
| 63 | kill (getpgrp (), ...). | ||
| 64 | (emacs_sigaction_init): Assume SIGCHLD is defined. | ||
| 65 | (init_signals): Assume SIGALRM, SIGCHLD, SIGHUP, SIGKILL, | ||
| 66 | SIGPIPE, and SIGQUIT are defined. Do not worry about SIGCLD any more. | ||
| 67 | * syssignal.h (EMACS_KILLPG): Remove. | ||
| 68 | All uses replaced by 'kill' with a negative pid. | ||
| 69 | (SIGCHLD): Remove definition, as we now assume SIGCHLD. | ||
| 70 | * w32proc.c (sys_kill): Support negative pids compatibly with POSIX. | ||
| 71 | |||
| 72 | 2012-12-07 Paul Eggert <eggert@cs.ucla.edu> | ||
| 73 | |||
| 74 | * sysdep.c (get_child_status): Abort on internal error (Bug#13086). | ||
| 75 | This will cause a production Emacs to dump core instead of | ||
| 76 | infinite-looping. | ||
| 77 | |||
| 78 | 2012-12-07 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 79 | |||
| 80 | * frame.c (make_frame): Do not set window's buffer to t. | ||
| 81 | * window.c (Fsplit_window_internal): Likewise. Previously it was | ||
| 82 | used to indicate that the window is being set up. Now we use | ||
| 83 | set_window_buffer for all new windows, so the condition in ... | ||
| 84 | (Fset_window_buffer): ... is always true and can be removed. | ||
| 85 | |||
| 86 | 2012-12-07 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 87 | |||
| 88 | Convenient macro to check whether the buffer is hidden. | ||
| 89 | * buffer.h (BUFFER_HIDDEN_P): New macro. | ||
| 90 | * frame.c (make_frame): Use it. Adjust comment. | ||
| 91 | * buffer.c (candidate_buffer): New function. | ||
| 92 | (Fother_buffer, other_buffer_safely): Use it. | ||
| 93 | |||
| 94 | 2012-12-06 Eli Zaretskii <eliz@gnu.org> | ||
| 95 | |||
| 96 | * w32proc.c (waitpid): Avoid busy-waiting when called with WNOHANG | ||
| 97 | if the child process is still running. Instead, exit the wait | ||
| 98 | loop and return zero. (Bug#13086) | ||
| 99 | |||
| 100 | 2012-12-06 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 101 | |||
| 102 | * frame.h (x_char_width, x_char_height): Remove prototypes. | ||
| 103 | * w32term.h (x_char_width, x_char_height): Likewise. | ||
| 104 | * xfns.c (x_char_width, x_char_height): Remove. | ||
| 105 | * w32fns.c (x_char_width, x_char_height): Likewise. | ||
| 106 | * nsfns.c (x_char_width, x_char_height): Likewise. | ||
| 107 | * frame.c (Fframe_char_width): Use FRAME_COLUMN_WIDTH for | ||
| 108 | all window frames. | ||
| 109 | (Fframe_char_height): Likewise with FRAME_LINE_HEIGHT. | ||
| 110 | * keyboard.c (command_loop_1): Remove prototype. | ||
| 111 | (command_loop_2, top_level_1): Add static to match prototype. | ||
| 112 | |||
| 113 | 2012-12-06 Paul Eggert <eggert@cs.ucla.edu> | ||
| 114 | |||
| 115 | Fix a recently-introduced delete-process race condition. | ||
| 116 | * callproc.c, process.h (record_kill_process): | ||
| 117 | New function, containing part of the old call_process_kill. | ||
| 118 | (call_process_kill): Use it. | ||
| 119 | This does not change call_process_kill's behavior. | ||
| 120 | * process.c (Fdelete_process): Use record_kill_process to fix a | ||
| 121 | race condition that could cause Emacs to lose track of a child. | ||
| 122 | |||
| 123 | 2012-12-06 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 124 | |||
| 125 | Avoid code duplication between prev_frame and next_frame. | ||
| 126 | * frame.c (candidate_frame): New function. Add comment. | ||
| 127 | (prev_frame, next_frame): Use it. Adjust comment. | ||
| 128 | |||
| 129 | 2012-12-06 Eli Zaretskii <eliz@gnu.org> | ||
| 130 | |||
| 131 | * callproc.c (Fcall_process_region) [!HAVE_MKSTEMP]: If mktemp | ||
| 132 | fails, signal an error instead of continuing with an empty | ||
| 133 | string. (Bug#13079) | ||
| 134 | Encode expanded temp file pattern before passing it to mkstemp or | ||
| 135 | mktemp. | ||
| 136 | |||
| 137 | * fileio.c (file_name_as_directory, directory_file_name) [DOS_NT]: | ||
| 138 | Encode the file name before passing it to dostounix_filename, in | ||
| 139 | case it will downcase it (under w32-downcase-file-names). | ||
| 140 | (Bug#12933) | ||
| 141 | |||
| 142 | 2012-12-05 Paul Eggert <eggert@cs.ucla.edu> | ||
| 143 | |||
| 144 | Minor call-process cleanups. | ||
| 145 | * callproc.c (Fcall_process): Do record-unwind-protect on MSDOS | ||
| 146 | at the same time as other platforms, to simplify analysis. | ||
| 147 | No need for fd0_volatile since we have synch_process_fd. | ||
| 148 | Avoid needless emacs_close; arg is always negative. | ||
| 149 | |||
| 150 | 2012-12-04 Andreas Schwab <schwab@linux-m68k.org> | ||
| 151 | |||
| 152 | * callproc.c (Fcall_process): Fix specpdl nesting for asynchronous | ||
| 153 | processes. | ||
| 154 | |||
| 155 | 2012-12-04 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 156 | |||
| 157 | * lisp.h (Mouse_HLInfo): Remove set-but-unused mouse_face_image_state | ||
| 158 | member. Adjust users. Convert mouse_face_past_end, mouse_face_defer | ||
| 159 | and mouse_face_hidden members to a bitfields. | ||
| 160 | * frame.h (struct frame): Remove set-but-not-used space_width member. | ||
| 161 | (FRAME_SPACE_WIDTH): Remove. | ||
| 162 | * nsterm.m, w32term.c, xterm.c: Adjust users. | ||
| 163 | * termchar.h (struct tty_display_info): Remove set-but-unused se_is_so | ||
| 164 | member. Adjust users. Convert term_initted, delete_in_insert_mode, | ||
| 165 | costs_set, insert_mode, standout_mode, cursor_hidden and flow_control | ||
| 166 | members to a bitfields. | ||
| 167 | |||
| 168 | 2012-12-03 Paul Eggert <eggert@cs.ucla.edu> | ||
| 169 | |||
| 170 | Don't let call-process be a zombie factory (Bug#12980). | ||
| 171 | Fixing this bug required some cleanup of the signal-handling code. | ||
| 172 | As a side effect, this change also fixes a longstanding rare race | ||
| 173 | condition whereby Emacs could mistakenly kill unrelated processes, | ||
| 174 | and it fixes a bug where a second C-g does not kill a recalcitrant | ||
| 175 | synchronous process in GNU/Linux and similar platforms. | ||
| 176 | The patch should also fix the last vestiges of Bug#9488, | ||
| 177 | a bug which has mostly been fixed on the trunk by other changes. | ||
| 178 | * callproc.c, process.h (synch_process_alive, synch_process_death) | ||
| 179 | (synch_process_termsig, sync_process_retcode): | ||
| 180 | Remove. All uses removed, to simplify analysis and so that | ||
| 181 | less consing is done inside critical sections. | ||
| 182 | * callproc.c (call_process_exited): Remove. All uses replaced | ||
| 183 | with !synch_process_pid. | ||
| 184 | * callproc.c (synch_process_pid, synch_process_fd): New static vars. | ||
| 185 | These take the role of what used to be in unwind-protect arg. | ||
| 186 | All uses changed. | ||
| 187 | (block_child_signal, unblock_child_signal): | ||
| 188 | New functions, to avoid races that could kill innocent-victim processes. | ||
| 189 | (call_process_kill, call_process_cleanup, Fcall_process): Use them. | ||
| 190 | (call_process_kill): Record killed processes as deleted, so that | ||
| 191 | zombies do not clutter up the system. Do this inside a critical | ||
| 192 | section, to avoid a race that would allow the clutter. | ||
| 193 | (call_process_cleanup): Fix code so that the second C-g works again | ||
| 194 | on common platforms such as GNU/Linux. | ||
| 195 | (Fcall_process): Create the child process in a critical section, | ||
| 196 | to fix a race condition. If creating an asynchronous process, | ||
| 197 | record it as deleted so that zombies do not clutter up the system. | ||
| 198 | Do unwind-protect for WINDOWSNT too, as that's simpler in the | ||
| 199 | light of these changes. Omit unnecessary call to emacs_close | ||
| 200 | before failure, as the unwind-protect code does that. | ||
| 201 | * callproc.c (call_process_cleanup): | ||
| 202 | * w32proc.c (waitpid): Simplify now that synch_process_alive is gone. | ||
| 203 | * process.c (record_deleted_pid): New function, containing | ||
| 204 | code refactored out of Fdelete_process. | ||
| 205 | (Fdelete_process): Use it. | ||
| 206 | (process_status_retrieved): Remove. All callers changed to use | ||
| 207 | child_status_change. | ||
| 208 | (record_child_status_change): Remove, folding its contents into ... | ||
| 209 | (handle_child_signal): ... this signal handler. Now, this | ||
| 210 | function is purely a handler for SIGCHLD, and is not called after | ||
| 211 | a synchronous waitpid returns; the synchronous code is moved to | ||
| 212 | wait_for_termination. There is no need to worry about reaping | ||
| 213 | more than one child now. | ||
| 214 | * sysdep.c (get_child_status, child_status_changed): New functions. | ||
| 215 | (wait_for_termination): Now takes int * status and bool | ||
| 216 | interruptible arguments, too. Do not record child status change; | ||
| 217 | that's now the caller's responsibility. All callers changed. | ||
| 218 | Reimplement in terms of get_child_status. | ||
| 219 | (wait_for_termination_1, interruptible_wait_for_termination): | ||
| 220 | Remove. All callers changed to use wait_for_termination. | ||
| 221 | * syswait.h: Include <stdbool.h>, for bool. | ||
| 222 | (record_child_status_change, interruptible_wait_for_termination): | ||
| 223 | Remove decls. | ||
| 224 | (record_deleted_pid, child_status_changed): New decls. | ||
| 225 | (wait_for_termination): Adjust to API changes noted above. | ||
| 226 | |||
| 227 | * bytecode.c, lisp.h (Qbytecode): Remove. | ||
| 228 | No longer needed after 2012-11-20 interactive-p changes. | ||
| 229 | |||
| 230 | 2012-12-03 Eli Zaretskii <eliz@gnu.org> | ||
| 231 | |||
| 232 | * xdisp.c (redisplay_window): If the cursor is visible, but inside | ||
| 233 | the scroll margin, move point outside the margin. (Bug#13055) | ||
| 234 | |||
| 235 | 2012-12-03 Jan Djärv <jan.h.d@swipnet.se> | ||
| 236 | |||
| 237 | * gtkutil.c (my_log_handler): New function. | ||
| 238 | (xg_set_geometry): Set log handler to my_log_handler (Bug#11177). | ||
| 239 | |||
| 240 | 2012-12-03 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 241 | |||
| 242 | * lisp.h (modify_region): Rename to... | ||
| 243 | (modify_region_1): ...new prototype. | ||
| 244 | * textprop.c (modify_region): Now static. Adjust users. | ||
| 245 | * insdel.c (modify_region): Rename to... | ||
| 246 | (modify_region_1): ...new function to work with current buffer. | ||
| 247 | Adjust comment and users. Use true and false for booleans. | ||
| 248 | |||
| 249 | 2012-12-03 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 250 | |||
| 251 | * alloc.c (free_save_value): New function. | ||
| 252 | (safe_alloca_unwind): Use it. | ||
| 253 | * lisp.h (free_save_value): New prototype. | ||
| 254 | * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value. | ||
| 255 | Add comment. | ||
| 256 | (save_excursion_restore): Adjust to match saved data structure. | ||
| 257 | Use free_save_value to offload some work from GC. Drop obsolete | ||
| 258 | #if 0 code. | ||
| 259 | |||
| 260 | 2012-12-03 Chong Yidong <cyd@gnu.org> | ||
| 261 | |||
| 262 | * fileio.c (Vauto_save_list_file_name): Doc fix. | ||
| 263 | |||
| 264 | 2012-12-03 Fabrice Popineau <fabrice.popineau@gmail.com> | ||
| 265 | |||
| 266 | * w32fns.c: Remove prototype of atof. | ||
| 267 | (syspage_mask): Declared DWORD_PTR, for compatibility with 64-bit | ||
| 268 | builds. | ||
| 269 | (file_dialog_callback): Declared UINT_PTR. | ||
| 270 | |||
| 271 | * w32common.h (syspage_mask): Declare DWORD_PTR, for compatibility | ||
| 272 | with 64-bit builds. | ||
| 273 | |||
| 274 | * w32.c (FILE_DEVICE_FILE_SYSTEM, METHOD_BUFFERED) | ||
| 275 | (FILE_ANY_ACCESS, CTL_CODE) [_MSC_VER]: Define only if not already | ||
| 276 | defined. | ||
| 277 | |||
| 278 | 2012-12-03 Glenn Morris <rgm@gnu.org> | ||
| 279 | |||
| 280 | * data.c (Fboundp, Fsymbol_value): Doc fix re lexical-binding. | ||
| 281 | |||
| 282 | 2012-12-02 Paul Eggert <eggert@cs.ucla.edu> | ||
| 283 | |||
| 284 | Fix xpalloc confusion after memory is exhausted. | ||
| 285 | * alloc.c (xpalloc): Comment fix. | ||
| 286 | * charset.c (Fdefine_charset_internal): If xpalloc exhausts memory | ||
| 287 | and signals an error, do not clear charset_table_size, as | ||
| 288 | charset_table is still valid. | ||
| 289 | * doprnt.c (evxprintf): Clear *BUF after freeing it. | ||
| 290 | |||
| 291 | Use execve to avoid need to munge environ (Bug#13054). | ||
| 292 | * callproc.c (Fcall_process): | ||
| 293 | * process.c (create_process): | ||
| 294 | Don't save and restore environ; no longer needed. | ||
| 295 | * callproc.c (child_setup): | ||
| 296 | Use execve, not execvp, to preserve environ. | ||
| 297 | |||
| 298 | 2012-12-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 299 | |||
| 300 | * xterm.c (x_draw_image_relief): Remove unused locals (Bug#10500). | ||
| 301 | |||
| 302 | 2012-12-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 303 | |||
| 304 | * xterm.c (x_draw_relief_rect, x_draw_image_relief): Fix relief | ||
| 305 | display for sliced images (Bug#10500). | ||
| 306 | |||
| 307 | * w32term.c (w32_draw_relief_rect, x_draw_image_relief): Likewise. | ||
| 308 | |||
| 309 | 2012-11-30 Juanma Barranquero <lekktu@gmail.com> | ||
| 310 | |||
| 311 | * doc.c (Fdocumentation): Re-add handling of function-documentation, | ||
| 312 | accidentally removed in 2012-11-09T04:10:16Z!monnier@iro.umontreal.ca (bug#13034). | ||
| 313 | |||
| 314 | 2012-11-29 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 315 | |||
| 316 | * xdisp.c (window_outdated): Remove eassert since it hits | ||
| 317 | some suspicious corner cases (see Bug#13007 and Bug#13012). | ||
| 318 | (mode_line_update_needed): New function. | ||
| 319 | (redisplay_internal, redisplay_window): Use it. | ||
| 320 | (ensure_selected_frame): New function. | ||
| 321 | (redisplay_internal, unwind_redisplay): Use it. | ||
| 322 | (redisplay_internal): Move comment about buffer_shared... | ||
| 323 | (buffer_shared_and_changed): ...near to its real use. | ||
| 324 | |||
| 325 | 2012-11-29 Paul Eggert <eggert@cs.ucla.edu> | ||
| 326 | |||
| 327 | * callproc.c (Fcall_process): Don't misreport vfork failure. | ||
| 328 | |||
| 329 | 2012-11-28 Paul Eggert <eggert@cs.ucla.edu> | ||
| 330 | |||
| 331 | * callproc.c (Fcall_process): Fix vfork portability problems. | ||
| 332 | Do not assume that fd[0], count, filefd, and save_environ survive | ||
| 333 | vfork. Fix bug whereby wrong errno value could be reported for | ||
| 334 | pipe failure. Some minor cleanups, too, as follows. Move buf and | ||
| 335 | bufsize to the context where they're needed. Change new_argv to | ||
| 336 | be of type char **, as this is more convenient and avoids casts. | ||
| 337 | (CALLPROC_BUFFER_SIZE_MIN, CALLPROC_BUFFER_SIZE_MAX): | ||
| 338 | Now local constants, not macros. | ||
| 339 | |||
| 340 | 2012-11-18 Kenichi Handa <handa@gnu.org> | ||
| 341 | |||
| 342 | * font.c (font_unparse_xlfd): Fix previous change. Keep "const" | ||
| 343 | for the variable "f". | ||
| 344 | |||
| 345 | 2012-11-13 Kenichi Handa <handa@gnu.org> | ||
| 346 | |||
| 347 | * font.c (font_unparse_xlfd): Exclude special characters from the | ||
| 348 | generating XLFD name. | ||
| 349 | |||
| 350 | 2012-11-27 Paul Eggert <eggert@cs.ucla.edu> | ||
| 351 | |||
| 352 | Assume POSIX 1003.1-1988 or later for grp.h, pwd.h. | ||
| 353 | * dired.c (stat_uname, stat_gname): | ||
| 354 | * fileio.c (Fexpand_file_name): Remove no-longer-needed casts. | ||
| 355 | |||
| 356 | Assume POSIX 1003.1-1988 or later for errno.h (Bug#12968). | ||
| 357 | * dired.c (directory_files_internal, file_name_completion): | ||
| 358 | Assume EAGAIN and EINTR are defined. | ||
| 359 | |||
| 360 | * fileio.c (Fcopy_file): Assume EISDIR is defined. | ||
| 361 | * gmalloc.c (ENOMEM, EINVAL): Assume they're defined. | ||
| 362 | * gnutls.c (emacs_gnutls_write): Assume EAGAIN is defined. | ||
| 363 | * lread.c (readbyte_from_file): Assume EINTR is defined. | ||
| 364 | * process.c (wait_reading_process_output, send_process) [subprocesses]: | ||
| 365 | Assume EIO and EAGAIN are defined. | ||
| 366 | * unexcoff.c (write_segment): Assume EFAULT is defined. | ||
| 367 | |||
| 368 | 2012-11-27 Eli Zaretskii <eliz@gnu.org> | ||
| 369 | |||
| 370 | * fontset.c (Finternal_char_font): Return nil on non-GUI frames. | ||
| 371 | (Bug#11964) | ||
| 372 | |||
| 373 | * xdisp.c (draw_glyphs): Don't draw in mouse face if mouse | ||
| 374 | highlighting on the frame was cleared. Prevents assertion | ||
| 375 | violations when repeatedly clicking on the "Top" link of the | ||
| 376 | "bread-crumbs" in Info buffers. | ||
| 377 | |||
| 1 | 2012-11-25 Paul Eggert <eggert@cs.ucla.edu> | 378 | 2012-11-25 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 379 | ||
| 3 | * sysdep.c (sys_subshell): Don't assume pid_t fits in int. | 380 | * sysdep.c (sys_subshell): Don't assume pid_t fits in int. |
diff --git a/src/alloc.c b/src/alloc.c index 28c9b51dab4..5a3ba465d81 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -761,13 +761,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) | |||
| 761 | infinity. | 761 | infinity. |
| 762 | 762 | ||
| 763 | If PA is null, then allocate a new array instead of reallocating | 763 | If PA is null, then allocate a new array instead of reallocating |
| 764 | the old one. Thus, to grow an array A without saving its old | 764 | the old one. |
| 765 | contents, invoke xfree (A) immediately followed by xgrowalloc (0, | ||
| 766 | &NITEMS, ...). | ||
| 767 | 765 | ||
| 768 | Block interrupt input as needed. If memory exhaustion occurs, set | 766 | Block interrupt input as needed. If memory exhaustion occurs, set |
| 769 | *NITEMS to zero if PA is null, and signal an error (i.e., do not | 767 | *NITEMS to zero if PA is null, and signal an error (i.e., do not |
| 770 | return). */ | 768 | return). |
| 769 | |||
| 770 | Thus, to grow an array A without saving its old contents, do | ||
| 771 | { xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }. | ||
| 772 | The A = NULL avoids a dangling pointer if xpalloc exhausts memory | ||
| 773 | and signals an error, and later this code is reexecuted and | ||
| 774 | attempts to free A. */ | ||
| 771 | 775 | ||
| 772 | void * | 776 | void * |
| 773 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | 777 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, |
| @@ -816,18 +820,22 @@ xstrdup (const char *s) | |||
| 816 | return p; | 820 | return p; |
| 817 | } | 821 | } |
| 818 | 822 | ||
| 823 | /* Like putenv, but (1) use the equivalent of xmalloc and (2) the | ||
| 824 | argument is a const pointer. */ | ||
| 825 | |||
| 826 | void | ||
| 827 | xputenv (char const *string) | ||
| 828 | { | ||
| 829 | if (putenv ((char *) string) != 0) | ||
| 830 | memory_full (0); | ||
| 831 | } | ||
| 819 | 832 | ||
| 820 | /* Unwind for SAFE_ALLOCA */ | 833 | /* Unwind for SAFE_ALLOCA */ |
| 821 | 834 | ||
| 822 | Lisp_Object | 835 | Lisp_Object |
| 823 | safe_alloca_unwind (Lisp_Object arg) | 836 | safe_alloca_unwind (Lisp_Object arg) |
| 824 | { | 837 | { |
| 825 | register struct Lisp_Save_Value *p = XSAVE_VALUE (arg); | 838 | free_save_value (arg); |
| 826 | |||
| 827 | p->dogc = 0; | ||
| 828 | xfree (p->pointer); | ||
| 829 | p->pointer = 0; | ||
| 830 | free_misc (arg); | ||
| 831 | return Qnil; | 839 | return Qnil; |
| 832 | } | 840 | } |
| 833 | 841 | ||
| @@ -3361,6 +3369,19 @@ make_save_value (void *pointer, ptrdiff_t integer) | |||
| 3361 | return val; | 3369 | return val; |
| 3362 | } | 3370 | } |
| 3363 | 3371 | ||
| 3372 | /* Free a Lisp_Misc_Save_Value object. */ | ||
| 3373 | |||
| 3374 | void | ||
| 3375 | free_save_value (Lisp_Object save) | ||
| 3376 | { | ||
| 3377 | register struct Lisp_Save_Value *p = XSAVE_VALUE (save); | ||
| 3378 | |||
| 3379 | p->dogc = 0; | ||
| 3380 | xfree (p->pointer); | ||
| 3381 | p->pointer = NULL; | ||
| 3382 | free_misc (save); | ||
| 3383 | } | ||
| 3384 | |||
| 3364 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ | 3385 | /* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ |
| 3365 | 3386 | ||
| 3366 | Lisp_Object | 3387 | Lisp_Object |
diff --git a/src/buffer.c b/src/buffer.c index 619a729a859..6e2191dc22f 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1529,6 +1529,16 @@ This does not change the name of the visited file (if any). */) | |||
| 1529 | return BVAR (current_buffer, name); | 1529 | return BVAR (current_buffer, name); |
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | /* True if B can be used as 'other-than-BUFFER' buffer. */ | ||
| 1533 | |||
| 1534 | static bool | ||
| 1535 | candidate_buffer (Lisp_Object b, Lisp_Object buffer) | ||
| 1536 | { | ||
| 1537 | return (BUFFERP (b) && !EQ (b, buffer) | ||
| 1538 | && BUFFER_LIVE_P (XBUFFER (b)) | ||
| 1539 | && !BUFFER_HIDDEN_P (XBUFFER (b))); | ||
| 1540 | } | ||
| 1541 | |||
| 1532 | DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0, | 1542 | DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0, |
| 1533 | doc: /* Return most recently selected buffer other than BUFFER. | 1543 | doc: /* Return most recently selected buffer other than BUFFER. |
| 1534 | Buffers not visible in windows are preferred to visible buffers, unless | 1544 | Buffers not visible in windows are preferred to visible buffers, unless |
| @@ -1550,9 +1560,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) | |||
| 1550 | for (; CONSP (tail); tail = XCDR (tail)) | 1560 | for (; CONSP (tail); tail = XCDR (tail)) |
| 1551 | { | 1561 | { |
| 1552 | buf = XCAR (tail); | 1562 | buf = XCAR (tail); |
| 1553 | if (BUFFERP (buf) && !EQ (buf, buffer) | 1563 | if (candidate_buffer (buf, buffer) |
| 1554 | && BUFFER_LIVE_P (XBUFFER (buf)) | ||
| 1555 | && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ') | ||
| 1556 | /* If the frame has a buffer_predicate, disregard buffers that | 1564 | /* If the frame has a buffer_predicate, disregard buffers that |
| 1557 | don't fit the predicate. */ | 1565 | don't fit the predicate. */ |
| 1558 | && (NILP (pred) || !NILP (call1 (pred, buf)))) | 1566 | && (NILP (pred) || !NILP (call1 (pred, buf)))) |
| @@ -1570,9 +1578,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) | |||
| 1570 | for (; CONSP (tail); tail = XCDR (tail)) | 1578 | for (; CONSP (tail); tail = XCDR (tail)) |
| 1571 | { | 1579 | { |
| 1572 | buf = Fcdr (XCAR (tail)); | 1580 | buf = Fcdr (XCAR (tail)); |
| 1573 | if (BUFFERP (buf) && !EQ (buf, buffer) | 1581 | if (candidate_buffer (buf, buffer) |
| 1574 | && BUFFER_LIVE_P (XBUFFER (buf)) | ||
| 1575 | && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ') | ||
| 1576 | /* If the frame has a buffer_predicate, disregard buffers that | 1582 | /* If the frame has a buffer_predicate, disregard buffers that |
| 1577 | don't fit the predicate. */ | 1583 | don't fit the predicate. */ |
| 1578 | && (NILP (pred) || !NILP (call1 (pred, buf)))) | 1584 | && (NILP (pred) || !NILP (call1 (pred, buf)))) |
| @@ -1608,13 +1614,10 @@ other_buffer_safely (Lisp_Object buffer) | |||
| 1608 | { | 1614 | { |
| 1609 | Lisp_Object tail, buf; | 1615 | Lisp_Object tail, buf; |
| 1610 | 1616 | ||
| 1611 | tail = Vbuffer_alist; | 1617 | for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) |
| 1612 | for (; CONSP (tail); tail = XCDR (tail)) | ||
| 1613 | { | 1618 | { |
| 1614 | buf = Fcdr (XCAR (tail)); | 1619 | buf = Fcdr (XCAR (tail)); |
| 1615 | if (BUFFERP (buf) && !EQ (buf, buffer) | 1620 | if (candidate_buffer (buf, buffer)) |
| 1616 | && BUFFER_LIVE_P (XBUFFER (buf)) | ||
| 1617 | && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')) | ||
| 1618 | return buf; | 1621 | return buf; |
| 1619 | } | 1622 | } |
| 1620 | 1623 | ||
diff --git a/src/buffer.h b/src/buffer.h index fbbbf1b8434..1129840bd47 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -982,6 +982,11 @@ bset_width_table (struct buffer *b, Lisp_Object val) | |||
| 982 | 982 | ||
| 983 | #define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name))) | 983 | #define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name))) |
| 984 | 984 | ||
| 985 | /* Convenient check whether buffer B is hidden (i.e. its name | ||
| 986 | starts with a space). Caller must ensure that B is live. */ | ||
| 987 | |||
| 988 | #define BUFFER_HIDDEN_P(b) (SREF (BVAR (b, name), 0) == ' ') | ||
| 989 | |||
| 985 | /* Verify indirection counters. */ | 990 | /* Verify indirection counters. */ |
| 986 | 991 | ||
| 987 | #define BUFFER_CHECK_INDIRECTION(b) \ | 992 | #define BUFFER_CHECK_INDIRECTION(b) \ |
diff --git a/src/bytecode.c b/src/bytecode.c index 3267c7c8c76..4c5ac151de1 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -87,8 +87,6 @@ Lisp_Object Qbyte_code_meter; | |||
| 87 | #endif /* BYTE_CODE_METER */ | 87 | #endif /* BYTE_CODE_METER */ |
| 88 | 88 | ||
| 89 | 89 | ||
| 90 | Lisp_Object Qbytecode; | ||
| 91 | |||
| 92 | /* Byte codes: */ | 90 | /* Byte codes: */ |
| 93 | 91 | ||
| 94 | #define BYTE_CODES \ | 92 | #define BYTE_CODES \ |
| @@ -1963,8 +1961,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 1963 | void | 1961 | void |
| 1964 | syms_of_bytecode (void) | 1962 | syms_of_bytecode (void) |
| 1965 | { | 1963 | { |
| 1966 | DEFSYM (Qbytecode, "byte-code"); | ||
| 1967 | |||
| 1968 | defsubr (&Sbyte_code); | 1964 | defsubr (&Sbyte_code); |
| 1969 | 1965 | ||
| 1970 | #ifdef BYTE_CODE_METER | 1966 | #ifdef BYTE_CODE_METER |
diff --git a/src/callproc.c b/src/callproc.c index c9a504746b3..70e349d0d3a 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -67,88 +67,122 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 67 | /* Pattern used by call-process-region to make temp files. */ | 67 | /* Pattern used by call-process-region to make temp files. */ |
| 68 | static Lisp_Object Vtemp_file_name_pattern; | 68 | static Lisp_Object Vtemp_file_name_pattern; |
| 69 | 69 | ||
| 70 | /* True if we are about to fork off a synchronous process or if we | 70 | /* The next two variables are valid only while record-unwind-protect |
| 71 | are waiting for it. */ | 71 | is in place during call-process for a synchronous subprocess. At |
| 72 | bool synch_process_alive; | 72 | other times, their contents are irrelevant. Doing this via static |
| 73 | C variables is more convenient than putting them into the arguments | ||
| 74 | of record-unwind-protect, as they need to be updated at randomish | ||
| 75 | times in the code, and Lisp cannot always store these values as | ||
| 76 | Emacs integers. It's safe to use static variables here, as the | ||
| 77 | code is never invoked reentrantly. */ | ||
| 78 | |||
| 79 | /* If nonzero, a process-ID that has not been reaped. */ | ||
| 80 | static pid_t synch_process_pid; | ||
| 81 | |||
| 82 | /* If nonnegative, a file descriptor that has not been closed. */ | ||
| 83 | static int synch_process_fd; | ||
| 84 | |||
| 85 | /* Block SIGCHLD. */ | ||
| 73 | 86 | ||
| 74 | /* Nonzero => this is a string explaining death of synchronous subprocess. */ | 87 | static void |
| 75 | const char *synch_process_death; | 88 | block_child_signal (void) |
| 89 | { | ||
| 90 | sigset_t blocked; | ||
| 91 | sigemptyset (&blocked); | ||
| 92 | sigaddset (&blocked, SIGCHLD); | ||
| 93 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 94 | } | ||
| 76 | 95 | ||
| 77 | /* Nonzero => this is the signal number that terminated the subprocess. */ | 96 | /* Unblock SIGCHLD. */ |
| 78 | int synch_process_termsig; | ||
| 79 | 97 | ||
| 80 | /* If synch_process_death is zero, | 98 | static void |
| 81 | this is exit code of synchronous subprocess. */ | 99 | unblock_child_signal (void) |
| 82 | int synch_process_retcode; | 100 | { |
| 101 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | ||
| 102 | } | ||
| 83 | 103 | ||
| 84 | 104 | /* If P is reapable, record it as a deleted process and kill it. | |
| 85 | /* Clean up when exiting Fcall_process. | 105 | Do this in a critical section. Unless PID is wedged it will be |
| 86 | On MSDOS, delete the temporary file on any kind of termination. | 106 | reaped on receipt of the first SIGCHLD after the critical section. */ |
| 87 | On Unix, kill the process and any children on termination by signal. */ | ||
| 88 | 107 | ||
| 89 | /* True if this is termination due to exit. */ | 108 | void |
| 90 | static bool call_process_exited; | 109 | record_kill_process (struct Lisp_Process *p) |
| 110 | { | ||
| 111 | block_child_signal (); | ||
| 112 | |||
| 113 | if (p->alive) | ||
| 114 | { | ||
| 115 | p->alive = 0; | ||
| 116 | record_deleted_pid (p->pid); | ||
| 117 | kill (- p->pid, SIGKILL); | ||
| 118 | } | ||
| 119 | |||
| 120 | unblock_child_signal (); | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Clean up when exiting call_process_cleanup. */ | ||
| 91 | 124 | ||
| 92 | static Lisp_Object | 125 | static Lisp_Object |
| 93 | call_process_kill (Lisp_Object fdpid) | 126 | call_process_kill (Lisp_Object ignored) |
| 94 | { | 127 | { |
| 95 | int fd; | 128 | if (0 <= synch_process_fd) |
| 96 | pid_t pid; | 129 | emacs_close (synch_process_fd); |
| 97 | CONS_TO_INTEGER (Fcar (fdpid), int, fd); | 130 | |
| 98 | CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); | 131 | if (synch_process_pid) |
| 99 | emacs_close (fd); | 132 | { |
| 100 | EMACS_KILLPG (pid, SIGKILL); | 133 | struct Lisp_Process proc; |
| 101 | synch_process_alive = 0; | 134 | proc.alive = 1; |
| 135 | proc.pid = synch_process_pid; | ||
| 136 | record_kill_process (&proc); | ||
| 137 | } | ||
| 138 | |||
| 102 | return Qnil; | 139 | return Qnil; |
| 103 | } | 140 | } |
| 104 | 141 | ||
| 142 | /* Clean up when exiting Fcall_process. | ||
| 143 | On MSDOS, delete the temporary file on any kind of termination. | ||
| 144 | On Unix, kill the process and any children on termination by signal. */ | ||
| 145 | |||
| 105 | static Lisp_Object | 146 | static Lisp_Object |
| 106 | call_process_cleanup (Lisp_Object arg) | 147 | call_process_cleanup (Lisp_Object arg) |
| 107 | { | 148 | { |
| 108 | Lisp_Object fdpid = Fcdr (arg); | 149 | #ifdef MSDOS |
| 109 | int fd; | 150 | Lisp_Object buffer = Fcar (arg); |
| 110 | #if defined (MSDOS) | 151 | Lisp_Object file = Fcdr (arg); |
| 111 | Lisp_Object file; | ||
| 112 | #else | 152 | #else |
| 113 | pid_t pid; | 153 | Lisp_Object buffer = arg; |
| 114 | #endif | 154 | #endif |
| 115 | 155 | ||
| 116 | Fset_buffer (Fcar (arg)); | 156 | Fset_buffer (buffer); |
| 117 | CONS_TO_INTEGER (Fcar (fdpid), int, fd); | ||
| 118 | |||
| 119 | #if defined (MSDOS) | ||
| 120 | /* for MSDOS fdpid is really (fd . tempfile) */ | ||
| 121 | file = Fcdr (fdpid); | ||
| 122 | /* FD is -1 and FILE is "" when we didn't actually create a | ||
| 123 | temporary file in call-process. */ | ||
| 124 | if (fd >= 0) | ||
| 125 | emacs_close (fd); | ||
| 126 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | ||
| 127 | unlink (SDATA (file)); | ||
| 128 | #else /* not MSDOS */ | ||
| 129 | CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); | ||
| 130 | |||
| 131 | if (call_process_exited) | ||
| 132 | { | ||
| 133 | emacs_close (fd); | ||
| 134 | return Qnil; | ||
| 135 | } | ||
| 136 | 157 | ||
| 137 | if (EMACS_KILLPG (pid, SIGINT) == 0) | 158 | #ifndef MSDOS |
| 159 | /* If the process still exists, kill its process group. */ | ||
| 160 | if (synch_process_pid) | ||
| 138 | { | 161 | { |
| 139 | ptrdiff_t count = SPECPDL_INDEX (); | 162 | ptrdiff_t count = SPECPDL_INDEX (); |
| 140 | record_unwind_protect (call_process_kill, fdpid); | 163 | kill (-synch_process_pid, SIGINT); |
| 164 | record_unwind_protect (call_process_kill, make_number (0)); | ||
| 141 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); | 165 | message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); |
| 142 | immediate_quit = 1; | 166 | immediate_quit = 1; |
| 143 | QUIT; | 167 | QUIT; |
| 144 | wait_for_termination (pid); | 168 | wait_for_termination (synch_process_pid, 0, 1); |
| 169 | synch_process_pid = 0; | ||
| 145 | immediate_quit = 0; | 170 | immediate_quit = 0; |
| 146 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ | 171 | specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ |
| 147 | message1 ("Waiting for process to die...done"); | 172 | message1 ("Waiting for process to die...done"); |
| 148 | } | 173 | } |
| 149 | synch_process_alive = 0; | 174 | #endif |
| 150 | emacs_close (fd); | 175 | |
| 151 | #endif /* not MSDOS */ | 176 | if (0 <= synch_process_fd) |
| 177 | emacs_close (synch_process_fd); | ||
| 178 | |||
| 179 | #ifdef MSDOS | ||
| 180 | /* FILE is "" when we didn't actually create a temporary file in | ||
| 181 | call-process. */ | ||
| 182 | if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0')) | ||
| 183 | unlink (SDATA (file)); | ||
| 184 | #endif | ||
| 185 | |||
| 152 | return Qnil; | 186 | return Qnil; |
| 153 | } | 187 | } |
| 154 | 188 | ||
| @@ -181,18 +215,14 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again. | |||
| 181 | usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | 215 | usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) |
| 182 | (ptrdiff_t nargs, Lisp_Object *args) | 216 | (ptrdiff_t nargs, Lisp_Object *args) |
| 183 | { | 217 | { |
| 184 | Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail; | 218 | Lisp_Object infile, buffer, current_dir, path; |
| 185 | bool display_p; | 219 | bool display_p; |
| 186 | int fd[2]; | 220 | int fd0, fd1, filefd; |
| 187 | int filefd; | 221 | int status; |
| 188 | #define CALLPROC_BUFFER_SIZE_MIN (16 * 1024) | ||
| 189 | #define CALLPROC_BUFFER_SIZE_MAX (4 * CALLPROC_BUFFER_SIZE_MIN) | ||
| 190 | char buf[CALLPROC_BUFFER_SIZE_MAX]; | ||
| 191 | int bufsize = CALLPROC_BUFFER_SIZE_MIN; | ||
| 192 | ptrdiff_t count = SPECPDL_INDEX (); | 222 | ptrdiff_t count = SPECPDL_INDEX (); |
| 193 | USE_SAFE_ALLOCA; | 223 | USE_SAFE_ALLOCA; |
| 194 | 224 | ||
| 195 | register const unsigned char **new_argv; | 225 | char **new_argv; |
| 196 | /* File to use for stderr in the child. | 226 | /* File to use for stderr in the child. |
| 197 | t means use same as standard output. */ | 227 | t means use same as standard output. */ |
| 198 | Lisp_Object error_file; | 228 | Lisp_Object error_file; |
| @@ -204,6 +234,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 204 | #else | 234 | #else |
| 205 | pid_t pid; | 235 | pid_t pid; |
| 206 | #endif | 236 | #endif |
| 237 | int child_errno; | ||
| 207 | int fd_output = -1; | 238 | int fd_output = -1; |
| 208 | struct coding_system process_coding; /* coding-system of process output */ | 239 | struct coding_system process_coding; /* coding-system of process output */ |
| 209 | struct coding_system argument_coding; /* coding-system of arguments */ | 240 | struct coding_system argument_coding; /* coding-system of arguments */ |
| @@ -432,12 +463,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 432 | } | 463 | } |
| 433 | UNGCPRO; | 464 | UNGCPRO; |
| 434 | for (i = 4; i < nargs; i++) | 465 | for (i = 4; i < nargs; i++) |
| 435 | new_argv[i - 3] = SDATA (args[i]); | 466 | new_argv[i - 3] = SSDATA (args[i]); |
| 436 | new_argv[i - 3] = 0; | 467 | new_argv[i - 3] = 0; |
| 437 | } | 468 | } |
| 438 | else | 469 | else |
| 439 | new_argv[1] = 0; | 470 | new_argv[1] = 0; |
| 440 | new_argv[0] = SDATA (path); | 471 | new_argv[0] = SSDATA (path); |
| 441 | 472 | ||
| 442 | #ifdef MSDOS /* MW, July 1993 */ | 473 | #ifdef MSDOS /* MW, July 1993 */ |
| 443 | 474 | ||
| @@ -466,44 +497,37 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 466 | } | 497 | } |
| 467 | else | 498 | else |
| 468 | outfilefd = fd_output; | 499 | outfilefd = fd_output; |
| 469 | fd[0] = filefd; | 500 | fd0 = filefd; |
| 470 | fd[1] = outfilefd; | 501 | fd1 = outfilefd; |
| 471 | #endif /* MSDOS */ | 502 | #endif /* MSDOS */ |
| 472 | 503 | ||
| 473 | if (INTEGERP (buffer)) | 504 | if (INTEGERP (buffer)) |
| 474 | fd[1] = emacs_open (NULL_DEVICE, O_WRONLY, 0), fd[0] = -1; | 505 | { |
| 506 | fd0 = -1; | ||
| 507 | fd1 = emacs_open (NULL_DEVICE, O_WRONLY, 0); | ||
| 508 | } | ||
| 475 | else | 509 | else |
| 476 | { | 510 | { |
| 477 | #ifndef MSDOS | 511 | #ifndef MSDOS |
| 478 | errno = 0; | 512 | int fd[2]; |
| 479 | if (pipe (fd) == -1) | 513 | if (pipe (fd) == -1) |
| 480 | { | 514 | { |
| 515 | int pipe_errno = errno; | ||
| 481 | emacs_close (filefd); | 516 | emacs_close (filefd); |
| 517 | errno = pipe_errno; | ||
| 482 | report_file_error ("Creating process pipe", Qnil); | 518 | report_file_error ("Creating process pipe", Qnil); |
| 483 | } | 519 | } |
| 520 | fd0 = fd[0]; | ||
| 521 | fd1 = fd[1]; | ||
| 484 | #endif | 522 | #endif |
| 485 | } | 523 | } |
| 486 | 524 | ||
| 487 | { | 525 | { |
| 488 | /* child_setup must clobber environ in systems with true vfork. | ||
| 489 | Protect it from permanent change. */ | ||
| 490 | register char **save_environ = environ; | ||
| 491 | register int fd1 = fd[1]; | ||
| 492 | int fd_error = fd1; | 526 | int fd_error = fd1; |
| 493 | 527 | ||
| 494 | if (fd_output >= 0) | 528 | if (fd_output >= 0) |
| 495 | fd1 = fd_output; | 529 | fd1 = fd_output; |
| 496 | 530 | ||
| 497 | /* Record that we're about to create a synchronous process. */ | ||
| 498 | synch_process_alive = 1; | ||
| 499 | |||
| 500 | /* These vars record information from process termination. | ||
| 501 | Clear them now before process can possibly terminate, | ||
| 502 | to avoid timing error if process terminates soon. */ | ||
| 503 | synch_process_death = 0; | ||
| 504 | synch_process_retcode = 0; | ||
| 505 | synch_process_termsig = 0; | ||
| 506 | |||
| 507 | if (NILP (error_file)) | 531 | if (NILP (error_file)) |
| 508 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); | 532 | fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); |
| 509 | else if (STRINGP (error_file)) | 533 | else if (STRINGP (error_file)) |
| @@ -520,8 +544,8 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 520 | if (fd_error < 0) | 544 | if (fd_error < 0) |
| 521 | { | 545 | { |
| 522 | emacs_close (filefd); | 546 | emacs_close (filefd); |
| 523 | if (fd[0] != filefd) | 547 | if (fd0 != filefd) |
| 524 | emacs_close (fd[0]); | 548 | emacs_close (fd0); |
| 525 | if (fd1 >= 0) | 549 | if (fd1 >= 0) |
| 526 | emacs_close (fd1); | 550 | emacs_close (fd1); |
| 527 | #ifdef MSDOS | 551 | #ifdef MSDOS |
| @@ -536,31 +560,28 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 536 | 560 | ||
| 537 | #ifdef MSDOS /* MW, July 1993 */ | 561 | #ifdef MSDOS /* MW, July 1993 */ |
| 538 | /* Note that on MSDOS `child_setup' actually returns the child process | 562 | /* Note that on MSDOS `child_setup' actually returns the child process |
| 539 | exit status, not its PID, so we assign it to `synch_process_retcode' | 563 | exit status, not its PID, so assign it to status below. */ |
| 540 | below. */ | 564 | pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); |
| 541 | pid = child_setup (filefd, outfilefd, fd_error, (char **) new_argv, | 565 | child_errno = errno; |
| 542 | 0, current_dir); | ||
| 543 | |||
| 544 | /* Record that the synchronous process exited and note its | ||
| 545 | termination status. */ | ||
| 546 | synch_process_alive = 0; | ||
| 547 | synch_process_retcode = pid; | ||
| 548 | if (synch_process_retcode < 0) /* means it couldn't be exec'ed */ | ||
| 549 | { | ||
| 550 | synchronize_system_messages_locale (); | ||
| 551 | synch_process_death = strerror (errno); | ||
| 552 | } | ||
| 553 | 566 | ||
| 554 | emacs_close (outfilefd); | 567 | emacs_close (outfilefd); |
| 555 | if (fd_error != outfilefd) | 568 | if (fd_error != outfilefd) |
| 556 | emacs_close (fd_error); | 569 | emacs_close (fd_error); |
| 570 | if (pid < 0) | ||
| 571 | { | ||
| 572 | synchronize_system_messages_locale (); | ||
| 573 | return | ||
| 574 | code_convert_string_norecord (build_string (strerror (child_errno)), | ||
| 575 | Vlocale_coding_system, 0); | ||
| 576 | } | ||
| 577 | status = pid; | ||
| 557 | fd1 = -1; /* No harm in closing that one! */ | 578 | fd1 = -1; /* No harm in closing that one! */ |
| 558 | if (tempfile) | 579 | if (tempfile) |
| 559 | { | 580 | { |
| 560 | /* Since CRLF is converted to LF within `decode_coding', we | 581 | /* Since CRLF is converted to LF within `decode_coding', we |
| 561 | can always open a file with binary mode. */ | 582 | can always open a file with binary mode. */ |
| 562 | fd[0] = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); | 583 | fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); |
| 563 | if (fd[0] < 0) | 584 | if (fd0 < 0) |
| 564 | { | 585 | { |
| 565 | unlink (tempfile); | 586 | unlink (tempfile); |
| 566 | emacs_close (filefd); | 587 | emacs_close (filefd); |
| @@ -569,14 +590,29 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 569 | } | 590 | } |
| 570 | } | 591 | } |
| 571 | else | 592 | else |
| 572 | fd[0] = -1; /* We are not going to read from tempfile. */ | 593 | fd0 = -1; /* We are not going to read from tempfile. */ |
| 573 | #else /* not MSDOS */ | 594 | #endif /* MSDOS */ |
| 574 | #ifdef WINDOWSNT | 595 | |
| 575 | pid = child_setup (filefd, fd1, fd_error, (char **) new_argv, | 596 | /* Do the unwind-protect now, even though the pid is not known, so |
| 576 | 0, current_dir); | 597 | that no storage allocation is done in the critical section. |
| 577 | #else /* not WINDOWSNT */ | 598 | The actual PID will be filled in during the critical section. */ |
| 599 | synch_process_pid = 0; | ||
| 600 | synch_process_fd = fd0; | ||
| 601 | |||
| 602 | #ifdef MSDOS | ||
| 603 | /* MSDOS needs different cleanup information. */ | ||
| 604 | record_unwind_protect (call_process_cleanup, | ||
| 605 | Fcons (Fcurrent_buffer (), | ||
| 606 | build_string (tempfile ? tempfile : ""))); | ||
| 607 | #else | ||
| 608 | record_unwind_protect (call_process_cleanup, Fcurrent_buffer ()); | ||
| 578 | 609 | ||
| 579 | block_input (); | 610 | block_input (); |
| 611 | block_child_signal (); | ||
| 612 | |||
| 613 | #ifdef WINDOWSNT | ||
| 614 | pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); | ||
| 615 | #else /* not WINDOWSNT */ | ||
| 580 | 616 | ||
| 581 | /* vfork, and prevent local vars from being clobbered by the vfork. */ | 617 | /* vfork, and prevent local vars from being clobbered by the vfork. */ |
| 582 | { | 618 | { |
| @@ -589,50 +625,67 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 589 | int volatile fd1_volatile = fd1; | 625 | int volatile fd1_volatile = fd1; |
| 590 | int volatile fd_error_volatile = fd_error; | 626 | int volatile fd_error_volatile = fd_error; |
| 591 | int volatile fd_output_volatile = fd_output; | 627 | int volatile fd_output_volatile = fd_output; |
| 628 | int volatile filefd_volatile = filefd; | ||
| 629 | ptrdiff_t volatile count_volatile = count; | ||
| 592 | ptrdiff_t volatile sa_count_volatile = sa_count; | 630 | ptrdiff_t volatile sa_count_volatile = sa_count; |
| 593 | unsigned char const **volatile new_argv_volatile = new_argv; | 631 | char **volatile new_argv_volatile = new_argv; |
| 594 | 632 | ||
| 595 | pid = vfork (); | 633 | pid = vfork (); |
| 634 | child_errno = errno; | ||
| 596 | 635 | ||
| 597 | buffer = buffer_volatile; | 636 | buffer = buffer_volatile; |
| 598 | coding_systems = coding_systems_volatile; | 637 | coding_systems = coding_systems_volatile; |
| 599 | current_dir = current_dir_volatile; | 638 | current_dir = current_dir_volatile; |
| 600 | display_p = display_p_volatile; | 639 | display_p = display_p_volatile; |
| 640 | output_to_buffer = output_to_buffer_volatile; | ||
| 641 | sa_must_free = sa_must_free_volatile; | ||
| 601 | fd1 = fd1_volatile; | 642 | fd1 = fd1_volatile; |
| 602 | fd_error = fd_error_volatile; | 643 | fd_error = fd_error_volatile; |
| 603 | fd_output = fd_output_volatile; | 644 | fd_output = fd_output_volatile; |
| 604 | output_to_buffer = output_to_buffer_volatile; | 645 | filefd = filefd_volatile; |
| 605 | sa_must_free = sa_must_free_volatile; | 646 | count = count_volatile; |
| 606 | sa_count = sa_count_volatile; | 647 | sa_count = sa_count_volatile; |
| 607 | new_argv = new_argv_volatile; | 648 | new_argv = new_argv_volatile; |
| 649 | |||
| 650 | fd0 = synch_process_fd; | ||
| 608 | } | 651 | } |
| 609 | 652 | ||
| 610 | if (pid == 0) | 653 | if (pid == 0) |
| 611 | { | 654 | { |
| 612 | if (fd[0] >= 0) | 655 | unblock_child_signal (); |
| 613 | emacs_close (fd[0]); | 656 | |
| 657 | if (fd0 >= 0) | ||
| 658 | emacs_close (fd0); | ||
| 614 | 659 | ||
| 615 | setsid (); | 660 | setsid (); |
| 616 | 661 | ||
| 617 | /* Emacs ignores SIGPIPE, but the child should not. */ | 662 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 618 | signal (SIGPIPE, SIG_DFL); | 663 | signal (SIGPIPE, SIG_DFL); |
| 619 | 664 | ||
| 620 | child_setup (filefd, fd1, fd_error, (char **) new_argv, | 665 | child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); |
| 621 | 0, current_dir); | ||
| 622 | } | 666 | } |
| 623 | 667 | ||
| 624 | unblock_input (); | ||
| 625 | |||
| 626 | #endif /* not WINDOWSNT */ | 668 | #endif /* not WINDOWSNT */ |
| 627 | 669 | ||
| 670 | child_errno = errno; | ||
| 671 | |||
| 672 | if (0 < pid) | ||
| 673 | { | ||
| 674 | if (INTEGERP (buffer)) | ||
| 675 | record_deleted_pid (pid); | ||
| 676 | else | ||
| 677 | synch_process_pid = pid; | ||
| 678 | } | ||
| 679 | |||
| 680 | unblock_child_signal (); | ||
| 681 | unblock_input (); | ||
| 682 | |||
| 628 | /* The MSDOS case did this already. */ | 683 | /* The MSDOS case did this already. */ |
| 629 | if (fd_error >= 0) | 684 | if (fd_error >= 0) |
| 630 | emacs_close (fd_error); | 685 | emacs_close (fd_error); |
| 631 | #endif /* not MSDOS */ | 686 | #endif /* not MSDOS */ |
| 632 | 687 | ||
| 633 | environ = save_environ; | 688 | /* Close most of our file descriptors, but not fd0 |
| 634 | |||
| 635 | /* Close most of our fd's, but not fd[0] | ||
| 636 | since we will use that to read input from. */ | 689 | since we will use that to read input from. */ |
| 637 | emacs_close (filefd); | 690 | emacs_close (filefd); |
| 638 | if (fd_output >= 0) | 691 | if (fd_output >= 0) |
| @@ -643,31 +696,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 643 | 696 | ||
| 644 | if (pid < 0) | 697 | if (pid < 0) |
| 645 | { | 698 | { |
| 646 | if (fd[0] >= 0) | 699 | errno = child_errno; |
| 647 | emacs_close (fd[0]); | ||
| 648 | report_file_error ("Doing vfork", Qnil); | 700 | report_file_error ("Doing vfork", Qnil); |
| 649 | } | 701 | } |
| 650 | 702 | ||
| 651 | if (INTEGERP (buffer)) | 703 | if (INTEGERP (buffer)) |
| 652 | { | 704 | return unbind_to (count, Qnil); |
| 653 | if (fd[0] >= 0) | ||
| 654 | emacs_close (fd[0]); | ||
| 655 | return Qnil; | ||
| 656 | } | ||
| 657 | |||
| 658 | /* Enable sending signal if user quits below. */ | ||
| 659 | call_process_exited = 0; | ||
| 660 | |||
| 661 | #if defined (MSDOS) | ||
| 662 | /* MSDOS needs different cleanup information. */ | ||
| 663 | cleanup_info_tail = build_string (tempfile ? tempfile : ""); | ||
| 664 | #else | ||
| 665 | cleanup_info_tail = INTEGER_TO_CONS (pid); | ||
| 666 | #endif /* not MSDOS */ | ||
| 667 | record_unwind_protect (call_process_cleanup, | ||
| 668 | Fcons (Fcurrent_buffer (), | ||
| 669 | Fcons (INTEGER_TO_CONS (fd[0]), | ||
| 670 | cleanup_info_tail))); | ||
| 671 | 705 | ||
| 672 | if (BUFFERP (buffer)) | 706 | if (BUFFERP (buffer)) |
| 673 | Fset_buffer (buffer); | 707 | Fset_buffer (buffer); |
| @@ -723,6 +757,10 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 723 | 757 | ||
| 724 | if (output_to_buffer) | 758 | if (output_to_buffer) |
| 725 | { | 759 | { |
| 760 | enum { CALLPROC_BUFFER_SIZE_MIN = 16 * 1024 }; | ||
| 761 | enum { CALLPROC_BUFFER_SIZE_MAX = 4 * CALLPROC_BUFFER_SIZE_MIN }; | ||
| 762 | char buf[CALLPROC_BUFFER_SIZE_MAX]; | ||
| 763 | int bufsize = CALLPROC_BUFFER_SIZE_MIN; | ||
| 726 | int nread; | 764 | int nread; |
| 727 | bool first = 1; | 765 | bool first = 1; |
| 728 | EMACS_INT total_read = 0; | 766 | EMACS_INT total_read = 0; |
| @@ -739,7 +777,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 739 | nread = carryover; | 777 | nread = carryover; |
| 740 | while (nread < bufsize - 1024) | 778 | while (nread < bufsize - 1024) |
| 741 | { | 779 | { |
| 742 | int this_read = emacs_read (fd[0], buf + nread, | 780 | int this_read = emacs_read (fd0, buf + nread, |
| 743 | bufsize - nread); | 781 | bufsize - nread); |
| 744 | 782 | ||
| 745 | if (this_read < 0) | 783 | if (this_read < 0) |
| @@ -850,38 +888,34 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | |||
| 850 | 888 | ||
| 851 | #ifndef MSDOS | 889 | #ifndef MSDOS |
| 852 | /* Wait for it to terminate, unless it already has. */ | 890 | /* Wait for it to terminate, unless it already has. */ |
| 853 | if (output_to_buffer) | 891 | wait_for_termination (pid, &status, !output_to_buffer); |
| 854 | wait_for_termination (pid); | ||
| 855 | else | ||
| 856 | interruptible_wait_for_termination (pid); | ||
| 857 | #endif | 892 | #endif |
| 858 | 893 | ||
| 859 | immediate_quit = 0; | 894 | immediate_quit = 0; |
| 860 | 895 | ||
| 861 | /* Don't kill any children that the subprocess may have left behind | 896 | /* Don't kill any children that the subprocess may have left behind |
| 862 | when exiting. */ | 897 | when exiting. */ |
| 863 | call_process_exited = 1; | 898 | synch_process_pid = 0; |
| 864 | 899 | ||
| 865 | SAFE_FREE (); | 900 | SAFE_FREE (); |
| 866 | unbind_to (count, Qnil); | 901 | unbind_to (count, Qnil); |
| 867 | 902 | ||
| 868 | if (synch_process_termsig) | 903 | if (WIFSIGNALED (status)) |
| 869 | { | 904 | { |
| 870 | const char *signame; | 905 | const char *signame; |
| 871 | 906 | ||
| 872 | synchronize_system_messages_locale (); | 907 | synchronize_system_messages_locale (); |
| 873 | signame = strsignal (synch_process_termsig); | 908 | signame = strsignal (WTERMSIG (status)); |
| 874 | 909 | ||
| 875 | if (signame == 0) | 910 | if (signame == 0) |
| 876 | signame = "unknown"; | 911 | signame = "unknown"; |
| 877 | 912 | ||
| 878 | synch_process_death = signame; | 913 | return code_convert_string_norecord (build_string (signame), |
| 914 | Vlocale_coding_system, 0); | ||
| 879 | } | 915 | } |
| 880 | 916 | ||
| 881 | if (synch_process_death) | 917 | eassert (WIFEXITED (status)); |
| 882 | return code_convert_string_norecord (build_string (synch_process_death), | 918 | return make_number (WEXITSTATUS (status)); |
| 883 | Vlocale_coding_system, 0); | ||
| 884 | return make_number (synch_process_retcode); | ||
| 885 | } | 919 | } |
| 886 | 920 | ||
| 887 | static Lisp_Object | 921 | static Lisp_Object |
| @@ -955,8 +989,9 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 955 | { | 989 | { |
| 956 | USE_SAFE_ALLOCA; | 990 | USE_SAFE_ALLOCA; |
| 957 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); | 991 | Lisp_Object pattern = Fexpand_file_name (Vtemp_file_name_pattern, tmpdir); |
| 958 | char *tempfile = SAFE_ALLOCA (SBYTES (pattern) + 1); | 992 | Lisp_Object encoded_tem = ENCODE_FILE (pattern); |
| 959 | memcpy (tempfile, SDATA (pattern), SBYTES (pattern) + 1); | 993 | char *tempfile = SAFE_ALLOCA (SBYTES (encoded_tem) + 1); |
| 994 | memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); | ||
| 960 | coding_systems = Qt; | 995 | coding_systems = Qt; |
| 961 | 996 | ||
| 962 | #ifdef HAVE_MKSTEMP | 997 | #ifdef HAVE_MKSTEMP |
| @@ -973,7 +1008,15 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r | |||
| 973 | close (fd); | 1008 | close (fd); |
| 974 | } | 1009 | } |
| 975 | #else | 1010 | #else |
| 1011 | errno = 0; | ||
| 976 | mktemp (tempfile); | 1012 | mktemp (tempfile); |
| 1013 | if (!*tempfile) | ||
| 1014 | { | ||
| 1015 | if (!errno) | ||
| 1016 | errno = EEXIST; | ||
| 1017 | report_file_error ("Failed to open temporary file using pattern", | ||
| 1018 | Fcons (pattern, Qnil)); | ||
| 1019 | } | ||
| 977 | #endif | 1020 | #endif |
| 978 | 1021 | ||
| 979 | filename_string = build_string (tempfile); | 1022 | filename_string = build_string (tempfile); |
| @@ -1079,10 +1122,6 @@ add_env (char **env, char **new_env, char *string) | |||
| 1079 | Initialize inferior's priority, pgrp, connected dir and environment. | 1122 | Initialize inferior's priority, pgrp, connected dir and environment. |
| 1080 | then exec another program based on new_argv. | 1123 | then exec another program based on new_argv. |
| 1081 | 1124 | ||
| 1082 | This function may change environ for the superior process. | ||
| 1083 | Therefore, the superior process must save and restore the value | ||
| 1084 | of environ around the vfork and the call to this function. | ||
| 1085 | |||
| 1086 | If SET_PGRP, put the subprocess into a separate process group. | 1125 | If SET_PGRP, put the subprocess into a separate process group. |
| 1087 | 1126 | ||
| 1088 | CURRENT_DIR is an elisp string giving the path of the current | 1127 | CURRENT_DIR is an elisp string giving the path of the current |
| @@ -1285,11 +1324,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1285 | setpgid (0, 0); | 1324 | setpgid (0, 0); |
| 1286 | tcsetpgrp (0, pid); | 1325 | tcsetpgrp (0, pid); |
| 1287 | 1326 | ||
| 1288 | /* execvp does not accept an environment arg so the only way | 1327 | execve (new_argv[0], new_argv, env); |
| 1289 | to pass this environment is to set environ. Our caller | ||
| 1290 | is responsible for restoring the ambient value of environ. */ | ||
| 1291 | environ = env; | ||
| 1292 | execvp (new_argv[0], new_argv); | ||
| 1293 | 1328 | ||
| 1294 | emacs_write (1, "Can't exec program: ", 20); | 1329 | emacs_write (1, "Can't exec program: ", 20); |
| 1295 | emacs_write (1, new_argv[0], strlen (new_argv[0])); | 1330 | emacs_write (1, new_argv[0], strlen (new_argv[0])); |
diff --git a/src/casefiddle.c b/src/casefiddle.c index e3654627576..d9c6a078973 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -213,7 +213,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) | |||
| 213 | validate_region (&b, &e); | 213 | validate_region (&b, &e); |
| 214 | start = XFASTINT (b); | 214 | start = XFASTINT (b); |
| 215 | end = XFASTINT (e); | 215 | end = XFASTINT (e); |
| 216 | modify_region (current_buffer, start, end, 0); | 216 | modify_region_1 (start, end, false); |
| 217 | record_change (start, end - start); | 217 | record_change (start, end - start); |
| 218 | start_byte = CHAR_TO_BYTE (start); | 218 | start_byte = CHAR_TO_BYTE (start); |
| 219 | 219 | ||
diff --git a/src/charset.c b/src/charset.c index c9133c780e8..43be0e9c780 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -1142,12 +1142,14 @@ usage: (define-charset-internal ...) */) | |||
| 1142 | example, the IDs are stuffed into struct | 1142 | example, the IDs are stuffed into struct |
| 1143 | coding_system.charbuf[i] entries, which are 'int'. */ | 1143 | coding_system.charbuf[i] entries, which are 'int'. */ |
| 1144 | int old_size = charset_table_size; | 1144 | int old_size = charset_table_size; |
| 1145 | ptrdiff_t new_size = old_size; | ||
| 1145 | struct charset *new_table = | 1146 | struct charset *new_table = |
| 1146 | xpalloc (0, &charset_table_size, 1, | 1147 | xpalloc (0, &new_size, 1, |
| 1147 | min (INT_MAX, MOST_POSITIVE_FIXNUM), | 1148 | min (INT_MAX, MOST_POSITIVE_FIXNUM), |
| 1148 | sizeof *charset_table); | 1149 | sizeof *charset_table); |
| 1149 | memcpy (new_table, charset_table, old_size * sizeof *new_table); | 1150 | memcpy (new_table, charset_table, old_size * sizeof *new_table); |
| 1150 | charset_table = new_table; | 1151 | charset_table = new_table; |
| 1152 | charset_table_size = new_size; | ||
| 1151 | /* FIXME: This leaks memory, as the old charset_table becomes | 1153 | /* FIXME: This leaks memory, as the old charset_table becomes |
| 1152 | unreachable. If the old charset table is charset_table_init | 1154 | unreachable. If the old charset table is charset_table_init |
| 1153 | then this leak is intentional; otherwise, it's unclear. | 1155 | then this leak is intentional; otherwise, it's unclear. |
diff --git a/src/data.c b/src/data.c index 5fc6afaaa03..a72fa3e2b5f 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -506,7 +506,9 @@ DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0, | |||
| 506 | /* Extract and set components of symbols. */ | 506 | /* Extract and set components of symbols. */ |
| 507 | 507 | ||
| 508 | DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, | 508 | DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, |
| 509 | doc: /* Return t if SYMBOL's value is not void. */) | 509 | doc: /* Return t if SYMBOL's value is not void. |
| 510 | Note that if `lexical-binding' is in effect, this refers to the | ||
| 511 | global value outside of any lexical scope. */) | ||
| 510 | (register Lisp_Object symbol) | 512 | (register Lisp_Object symbol) |
| 511 | { | 513 | { |
| 512 | Lisp_Object valcontents; | 514 | Lisp_Object valcontents; |
| @@ -1047,7 +1049,9 @@ find_symbol_value (Lisp_Object symbol) | |||
| 1047 | } | 1049 | } |
| 1048 | 1050 | ||
| 1049 | DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, | 1051 | DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, |
| 1050 | doc: /* Return SYMBOL's value. Error if that is void. */) | 1052 | doc: /* Return SYMBOL's value. Error if that is void. |
| 1053 | Note that if `lexical-binding' is in effect, this returns the | ||
| 1054 | global value outside of any lexical scope. */) | ||
| 1051 | (Lisp_Object symbol) | 1055 | (Lisp_Object symbol) |
| 1052 | { | 1056 | { |
| 1053 | Lisp_Object val; | 1057 | Lisp_Object val; |
diff --git a/src/dbusbind.c b/src/dbusbind.c index 80086946fc4..da8bbb1e5d7 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c | |||
| @@ -1203,7 +1203,7 @@ this connection to those buses. */) | |||
| 1203 | xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); | 1203 | xd_registered_buses = Fcons (Fcons (bus, val), xd_registered_buses); |
| 1204 | 1204 | ||
| 1205 | /* We do not want to abort. */ | 1205 | /* We do not want to abort. */ |
| 1206 | putenv ((char *) "DBUS_FATAL_WARNINGS=0"); | 1206 | xputenv ("DBUS_FATAL_WARNINGS=0"); |
| 1207 | 1207 | ||
| 1208 | /* Cleanup. */ | 1208 | /* Cleanup. */ |
| 1209 | dbus_error_free (&derror); | 1209 | dbus_error_free (&derror); |
diff --git a/src/dired.c b/src/dired.c index 3530b74ecb4..bdb71c46364 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -193,19 +193,15 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 193 | 193 | ||
| 194 | errno = 0; | 194 | errno = 0; |
| 195 | dp = readdir (d); | 195 | dp = readdir (d); |
| 196 | 196 | if (!dp) | |
| 197 | if (dp == NULL && (0 | 197 | { |
| 198 | #ifdef EAGAIN | 198 | if (errno == EAGAIN || errno == EINTR) |
| 199 | || errno == EAGAIN | 199 | { |
| 200 | #endif | 200 | QUIT; |
| 201 | #ifdef EINTR | 201 | continue; |
| 202 | || errno == EINTR | 202 | } |
| 203 | #endif | 203 | break; |
| 204 | )) | 204 | } |
| 205 | { QUIT; continue; } | ||
| 206 | |||
| 207 | if (dp == NULL) | ||
| 208 | break; | ||
| 209 | 205 | ||
| 210 | len = dirent_namelen (dp); | 206 | len = dirent_namelen (dp); |
| 211 | name = finalname = make_unibyte_string (dp->d_name, len); | 207 | name = finalname = make_unibyte_string (dp->d_name, len); |
| @@ -480,17 +476,15 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, | |||
| 480 | 476 | ||
| 481 | errno = 0; | 477 | errno = 0; |
| 482 | dp = readdir (d); | 478 | dp = readdir (d); |
| 483 | if (dp == NULL && (0 | 479 | if (!dp) |
| 484 | # ifdef EAGAIN | 480 | { |
| 485 | || errno == EAGAIN | 481 | if (errno == EAGAIN || errno == EINTR) |
| 486 | # endif | 482 | { |
| 487 | # ifdef EINTR | 483 | QUIT; |
| 488 | || errno == EINTR | 484 | continue; |
| 489 | # endif | 485 | } |
| 490 | )) | 486 | break; |
| 491 | { QUIT; continue; } | 487 | } |
| 492 | |||
| 493 | if (!dp) break; | ||
| 494 | 488 | ||
| 495 | len = dirent_namelen (dp); | 489 | len = dirent_namelen (dp); |
| 496 | 490 | ||
| @@ -826,7 +820,7 @@ stat_uname (struct stat *st) | |||
| 826 | #ifdef WINDOWSNT | 820 | #ifdef WINDOWSNT |
| 827 | return st->st_uname; | 821 | return st->st_uname; |
| 828 | #else | 822 | #else |
| 829 | struct passwd *pw = (struct passwd *) getpwuid (st->st_uid); | 823 | struct passwd *pw = getpwuid (st->st_uid); |
| 830 | 824 | ||
| 831 | if (pw) | 825 | if (pw) |
| 832 | return pw->pw_name; | 826 | return pw->pw_name; |
| @@ -841,7 +835,7 @@ stat_gname (struct stat *st) | |||
| 841 | #ifdef WINDOWSNT | 835 | #ifdef WINDOWSNT |
| 842 | return st->st_gname; | 836 | return st->st_gname; |
| 843 | #else | 837 | #else |
| 844 | struct group *gr = (struct group *) getgrgid (st->st_gid); | 838 | struct group *gr = getgrgid (st->st_gid); |
| 845 | 839 | ||
| 846 | if (gr) | 840 | if (gr) |
| 847 | return gr->gr_name; | 841 | return gr->gr_name; |
diff --git a/src/dispextern.h b/src/dispextern.h index c5ebb808b05..aa40f019fbe 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1572,12 +1572,12 @@ struct face | |||
| 1572 | /* Pixmap width and height. */ | 1572 | /* Pixmap width and height. */ |
| 1573 | unsigned int pixmap_w, pixmap_h; | 1573 | unsigned int pixmap_w, pixmap_h; |
| 1574 | 1574 | ||
| 1575 | /* Non-zero means characters in this face have a box that thickness | 1575 | /* Non-zero means characters in this face have a box of that |
| 1576 | around them. If it is negative, the absolute value indicates the | 1576 | thickness around them. If this value is negative, its absolute |
| 1577 | thickness, and the horizontal lines of box (top and bottom) are | 1577 | value indicates the thickness, and the horizontal (top and |
| 1578 | drawn inside of characters glyph area. The vertical lines of box | 1578 | bottom) borders of box are drawn inside of the character glyphs' |
| 1579 | (left and right) are drawn as the same way as the case that this | 1579 | area. The vertical (left and right) borders of the box are drawn |
| 1580 | value is positive. */ | 1580 | in the same way as when this value is positive. */ |
| 1581 | int box_line_width; | 1581 | int box_line_width; |
| 1582 | 1582 | ||
| 1583 | /* Type of box drawn. A value of FACE_NO_BOX means no box is drawn | 1583 | /* Type of box drawn. A value of FACE_NO_BOX means no box is drawn |
| @@ -338,6 +338,14 @@ string is passed through `substitute-command-keys'. */) | |||
| 338 | 338 | ||
| 339 | doc = Qnil; | 339 | doc = Qnil; |
| 340 | 340 | ||
| 341 | if (SYMBOLP (function)) | ||
| 342 | { | ||
| 343 | Lisp_Object tem = Fget (function, Qfunction_documentation); | ||
| 344 | if (!NILP (tem)) | ||
| 345 | return Fdocumentation_property (function, Qfunction_documentation, | ||
| 346 | raw); | ||
| 347 | } | ||
| 348 | |||
| 341 | fun = Findirect_function (function, Qnil); | 349 | fun = Findirect_function (function, Qnil); |
| 342 | if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) | 350 | if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) |
| 343 | fun = XCDR (fun); | 351 | fun = XCDR (fun); |
diff --git a/src/doprnt.c b/src/doprnt.c index caa56d6ae88..8cab219aafa 100644 --- a/src/doprnt.c +++ b/src/doprnt.c | |||
| @@ -521,7 +521,10 @@ evxprintf (char **buf, ptrdiff_t *bufsize, | |||
| 521 | if (nbytes < *bufsize - 1) | 521 | if (nbytes < *bufsize - 1) |
| 522 | return nbytes; | 522 | return nbytes; |
| 523 | if (*buf != nonheapbuf) | 523 | if (*buf != nonheapbuf) |
| 524 | xfree (*buf); | 524 | { |
| 525 | xfree (*buf); | ||
| 526 | *buf = NULL; | ||
| 527 | } | ||
| 525 | *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); | 528 | *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); |
| 526 | } | 529 | } |
| 527 | } | 530 | } |
diff --git a/src/editfns.c b/src/editfns.c index 8122ffdd0d4..7d179c8566a 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -78,6 +78,15 @@ Lisp_Object Qfield; | |||
| 78 | 78 | ||
| 79 | static Lisp_Object Qboundary; | 79 | static Lisp_Object Qboundary; |
| 80 | 80 | ||
| 81 | /* The startup value of the TZ environment variable so it can be | ||
| 82 | restored if the user calls set-time-zone-rule with a nil | ||
| 83 | argument. If null, the TZ environment variable was unset. */ | ||
| 84 | static char const *initial_tz; | ||
| 85 | |||
| 86 | /* True if the static variable tzvalbuf (defined in | ||
| 87 | set_time_zone_rule) is part of 'environ'. */ | ||
| 88 | static bool tzvalbuf_in_environ; | ||
| 89 | |||
| 81 | 90 | ||
| 82 | void | 91 | void |
| 83 | init_editfns (void) | 92 | init_editfns (void) |
| @@ -96,6 +105,9 @@ init_editfns (void) | |||
| 96 | return; | 105 | return; |
| 97 | #endif /* not CANNOT_DUMP */ | 106 | #endif /* not CANNOT_DUMP */ |
| 98 | 107 | ||
| 108 | initial_tz = getenv ("TZ"); | ||
| 109 | tzvalbuf_in_environ = 0; | ||
| 110 | |||
| 99 | pw = getpwuid (getuid ()); | 111 | pw = getpwuid (getuid ()); |
| 100 | #ifdef MSDOS | 112 | #ifdef MSDOS |
| 101 | /* We let the real user name default to "root" because that's quite | 113 | /* We let the real user name default to "root" because that's quite |
| @@ -813,38 +825,43 @@ This function does not move point. */) | |||
| 813 | Qnil, Qt, Qnil); | 825 | Qnil, Qt, Qnil); |
| 814 | } | 826 | } |
| 815 | 827 | ||
| 816 | 828 | /* Save current buffer state for `save-excursion' special form. | |
| 829 | We (ab)use Lisp_Misc_Save_Value to allow explicit free and so | ||
| 830 | offload some work from GC. */ | ||
| 831 | |||
| 817 | Lisp_Object | 832 | Lisp_Object |
| 818 | save_excursion_save (void) | 833 | save_excursion_save (void) |
| 819 | { | 834 | { |
| 820 | bool visible = (XBUFFER (XWINDOW (selected_window)->buffer) | 835 | Lisp_Object save, *data = xmalloc (word_size * 4); |
| 821 | == current_buffer); | 836 | |
| 837 | data[0] = Fpoint_marker (); | ||
| 822 | /* Do not copy the mark if it points to nowhere. */ | 838 | /* Do not copy the mark if it points to nowhere. */ |
| 823 | Lisp_Object mark = (XMARKER (BVAR (current_buffer, mark))->buffer | 839 | data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer |
| 824 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) | 840 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) |
| 825 | : Qnil); | 841 | : Qnil); |
| 826 | 842 | /* Selected window if current buffer is shown in it, nil otherwise. */ | |
| 827 | return Fcons (Fpoint_marker (), | 843 | data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) |
| 828 | Fcons (mark, | 844 | ? selected_window : Qnil); |
| 829 | Fcons (visible ? Qt : Qnil, | 845 | data[3] = BVAR (current_buffer, mark_active); |
| 830 | Fcons (BVAR (current_buffer, mark_active), | 846 | |
| 831 | selected_window)))); | 847 | save = make_save_value (data, 4); |
| 848 | XSAVE_VALUE (save)->dogc = 1; | ||
| 849 | return save; | ||
| 832 | } | 850 | } |
| 833 | 851 | ||
| 852 | /* Restore saved buffer before leaving `save-excursion' special form. */ | ||
| 853 | |||
| 834 | Lisp_Object | 854 | Lisp_Object |
| 835 | save_excursion_restore (Lisp_Object info) | 855 | save_excursion_restore (Lisp_Object info) |
| 836 | { | 856 | { |
| 837 | Lisp_Object tem, tem1, omark, nmark; | 857 | Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer; |
| 838 | struct gcpro gcpro1, gcpro2, gcpro3; | 858 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 839 | bool visible_p; | ||
| 840 | 859 | ||
| 841 | tem = Fmarker_buffer (XCAR (info)); | 860 | tem = Fmarker_buffer (data[0]); |
| 842 | /* If buffer being returned to is now deleted, avoid error */ | 861 | /* If we're unwinding to top level, saved buffer may be deleted. This |
| 843 | /* Otherwise could get error here while unwinding to top level | 862 | means that all of its markers are unchained and so tem is nil. */ |
| 844 | and crash */ | ||
| 845 | /* In that case, Fmarker_buffer returns nil now. */ | ||
| 846 | if (NILP (tem)) | 863 | if (NILP (tem)) |
| 847 | return Qnil; | 864 | goto out; |
| 848 | 865 | ||
| 849 | omark = nmark = Qnil; | 866 | omark = nmark = Qnil; |
| 850 | GCPRO3 (info, omark, nmark); | 867 | GCPRO3 (info, omark, nmark); |
| @@ -852,13 +869,12 @@ save_excursion_restore (Lisp_Object info) | |||
| 852 | Fset_buffer (tem); | 869 | Fset_buffer (tem); |
| 853 | 870 | ||
| 854 | /* Point marker. */ | 871 | /* Point marker. */ |
| 855 | tem = XCAR (info); | 872 | tem = data[0]; |
| 856 | Fgoto_char (tem); | 873 | Fgoto_char (tem); |
| 857 | unchain_marker (XMARKER (tem)); | 874 | unchain_marker (XMARKER (tem)); |
| 858 | 875 | ||
| 859 | /* Mark marker. */ | 876 | /* Mark marker. */ |
| 860 | info = XCDR (info); | 877 | tem = data[1]; |
| 861 | tem = XCAR (info); | ||
| 862 | omark = Fmarker_position (BVAR (current_buffer, mark)); | 878 | omark = Fmarker_position (BVAR (current_buffer, mark)); |
| 863 | if (NILP (tem)) | 879 | if (NILP (tem)) |
| 864 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); | 880 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); |
| @@ -869,23 +885,8 @@ save_excursion_restore (Lisp_Object info) | |||
| 869 | unchain_marker (XMARKER (tem)); | 885 | unchain_marker (XMARKER (tem)); |
| 870 | } | 886 | } |
| 871 | 887 | ||
| 872 | /* visible */ | 888 | /* Mark active. */ |
| 873 | info = XCDR (info); | 889 | tem = data[3]; |
| 874 | visible_p = !NILP (XCAR (info)); | ||
| 875 | |||
| 876 | #if 0 /* We used to make the current buffer visible in the selected window | ||
| 877 | if that was true previously. That avoids some anomalies. | ||
| 878 | But it creates others, and it wasn't documented, and it is simpler | ||
| 879 | and cleaner never to alter the window/buffer connections. */ | ||
| 880 | tem1 = Fcar (tem); | ||
| 881 | if (!NILP (tem1) | ||
| 882 | && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) | ||
| 883 | Fswitch_to_buffer (Fcurrent_buffer (), Qnil); | ||
| 884 | #endif /* 0 */ | ||
| 885 | |||
| 886 | /* Mark active */ | ||
| 887 | info = XCDR (info); | ||
| 888 | tem = XCAR (info); | ||
| 889 | tem1 = BVAR (current_buffer, mark_active); | 890 | tem1 = BVAR (current_buffer, mark_active); |
| 890 | bset_mark_active (current_buffer, tem); | 891 | bset_mark_active (current_buffer, tem); |
| 891 | 892 | ||
| @@ -909,8 +910,8 @@ save_excursion_restore (Lisp_Object info) | |||
| 909 | /* If buffer was visible in a window, and a different window was | 910 | /* If buffer was visible in a window, and a different window was |
| 910 | selected, and the old selected window is still showing this | 911 | selected, and the old selected window is still showing this |
| 911 | buffer, restore point in that window. */ | 912 | buffer, restore point in that window. */ |
| 912 | tem = XCDR (info); | 913 | tem = data[2]; |
| 913 | if (visible_p | 914 | if (WINDOWP (tem) |
| 914 | && !EQ (tem, selected_window) | 915 | && !EQ (tem, selected_window) |
| 915 | && (tem1 = XWINDOW (tem)->buffer, | 916 | && (tem1 = XWINDOW (tem)->buffer, |
| 916 | (/* Window is live... */ | 917 | (/* Window is live... */ |
| @@ -920,6 +921,10 @@ save_excursion_restore (Lisp_Object info) | |||
| 920 | Fset_window_point (tem, make_number (PT)); | 921 | Fset_window_point (tem, make_number (PT)); |
| 921 | 922 | ||
| 922 | UNGCPRO; | 923 | UNGCPRO; |
| 924 | |||
| 925 | out: | ||
| 926 | |||
| 927 | free_save_value (info); | ||
| 923 | return Qnil; | 928 | return Qnil; |
| 924 | } | 929 | } |
| 925 | 930 | ||
| @@ -1907,9 +1912,11 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) | |||
| 1907 | } | 1912 | } |
| 1908 | else | 1913 | else |
| 1909 | { | 1914 | { |
| 1910 | char tzbuf[100]; | 1915 | static char const tzbuf_format[] = "XXX%s%"pI"d:%02d:%02d"; |
| 1916 | char tzbuf[sizeof tzbuf_format + INT_STRLEN_BOUND (EMACS_INT)]; | ||
| 1917 | char *old_tzstring; | ||
| 1911 | const char *tzstring; | 1918 | const char *tzstring; |
| 1912 | char **oldenv = environ, **newenv; | 1919 | USE_SAFE_ALLOCA; |
| 1913 | 1920 | ||
| 1914 | if (EQ (zone, Qt)) | 1921 | if (EQ (zone, Qt)) |
| 1915 | tzstring = "UTC0"; | 1922 | tzstring = "UTC0"; |
| @@ -1921,13 +1928,20 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) | |||
| 1921 | EMACS_INT zone_hr = abszone / (60*60); | 1928 | EMACS_INT zone_hr = abszone / (60*60); |
| 1922 | int zone_min = (abszone/60) % 60; | 1929 | int zone_min = (abszone/60) % 60; |
| 1923 | int zone_sec = abszone % 60; | 1930 | int zone_sec = abszone % 60; |
| 1924 | sprintf (tzbuf, "XXX%s%"pI"d:%02d:%02d", "-" + (XINT (zone) < 0), | 1931 | sprintf (tzbuf, tzbuf_format, "-" + (XINT (zone) < 0), |
| 1925 | zone_hr, zone_min, zone_sec); | 1932 | zone_hr, zone_min, zone_sec); |
| 1926 | tzstring = tzbuf; | 1933 | tzstring = tzbuf; |
| 1927 | } | 1934 | } |
| 1928 | else | 1935 | else |
| 1929 | error ("Invalid time zone specification"); | 1936 | error ("Invalid time zone specification"); |
| 1930 | 1937 | ||
| 1938 | old_tzstring = getenv ("TZ"); | ||
| 1939 | if (old_tzstring) | ||
| 1940 | { | ||
| 1941 | char *buf = SAFE_ALLOCA (strlen (old_tzstring) + 1); | ||
| 1942 | old_tzstring = strcpy (buf, old_tzstring); | ||
| 1943 | } | ||
| 1944 | |||
| 1931 | block_input (); | 1945 | block_input (); |
| 1932 | 1946 | ||
| 1933 | /* Set TZ before calling mktime; merely adjusting mktime's returned | 1947 | /* Set TZ before calling mktime; merely adjusting mktime's returned |
| @@ -1936,15 +1950,12 @@ usage: (encode-time SECOND MINUTE HOUR DAY MONTH YEAR &optional ZONE) */) | |||
| 1936 | 1950 | ||
| 1937 | value = mktime (&tm); | 1951 | value = mktime (&tm); |
| 1938 | 1952 | ||
| 1939 | /* Restore TZ to previous value. */ | 1953 | set_time_zone_rule (old_tzstring); |
| 1940 | newenv = environ; | ||
| 1941 | environ = oldenv; | ||
| 1942 | #ifdef LOCALTIME_CACHE | 1954 | #ifdef LOCALTIME_CACHE |
| 1943 | tzset (); | 1955 | tzset (); |
| 1944 | #endif | 1956 | #endif |
| 1945 | unblock_input (); | 1957 | unblock_input (); |
| 1946 | 1958 | SAFE_FREE (); | |
| 1947 | xfree (newenv); | ||
| 1948 | } | 1959 | } |
| 1949 | 1960 | ||
| 1950 | if (value == (time_t) -1) | 1961 | if (value == (time_t) -1) |
| @@ -2074,16 +2085,6 @@ the data it can't find. */) | |||
| 2074 | return list2 (zone_offset, zone_name); | 2085 | return list2 (zone_offset, zone_name); |
| 2075 | } | 2086 | } |
| 2076 | 2087 | ||
| 2077 | /* This holds the value of `environ' produced by the previous | ||
| 2078 | call to Fset_time_zone_rule, or 0 if Fset_time_zone_rule | ||
| 2079 | has never been called. */ | ||
| 2080 | static char **environbuf; | ||
| 2081 | |||
| 2082 | /* This holds the startup value of the TZ environment variable so it | ||
| 2083 | can be restored if the user calls set-time-zone-rule with a nil | ||
| 2084 | argument. */ | ||
| 2085 | static char *initial_tz; | ||
| 2086 | |||
| 2087 | DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, | 2088 | DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, |
| 2088 | doc: /* Set the local time zone using TZ, a string specifying a time zone rule. | 2089 | doc: /* Set the local time zone using TZ, a string specifying a time zone rule. |
| 2089 | If TZ is nil, use implementation-defined default time zone information. | 2090 | If TZ is nil, use implementation-defined default time zone information. |
| @@ -2096,18 +2097,10 @@ only the former. */) | |||
| 2096 | (Lisp_Object tz) | 2097 | (Lisp_Object tz) |
| 2097 | { | 2098 | { |
| 2098 | const char *tzstring; | 2099 | const char *tzstring; |
| 2099 | char **old_environbuf; | ||
| 2100 | 2100 | ||
| 2101 | if (! (NILP (tz) || EQ (tz, Qt))) | 2101 | if (! (NILP (tz) || EQ (tz, Qt))) |
| 2102 | CHECK_STRING (tz); | 2102 | CHECK_STRING (tz); |
| 2103 | 2103 | ||
| 2104 | block_input (); | ||
| 2105 | |||
| 2106 | /* When called for the first time, save the original TZ. */ | ||
| 2107 | old_environbuf = environbuf; | ||
| 2108 | if (!old_environbuf) | ||
| 2109 | initial_tz = (char *) getenv ("TZ"); | ||
| 2110 | |||
| 2111 | if (NILP (tz)) | 2104 | if (NILP (tz)) |
| 2112 | tzstring = initial_tz; | 2105 | tzstring = initial_tz; |
| 2113 | else if (EQ (tz, Qt)) | 2106 | else if (EQ (tz, Qt)) |
| @@ -2115,106 +2108,97 @@ only the former. */) | |||
| 2115 | else | 2108 | else |
| 2116 | tzstring = SSDATA (tz); | 2109 | tzstring = SSDATA (tz); |
| 2117 | 2110 | ||
| 2111 | block_input (); | ||
| 2118 | set_time_zone_rule (tzstring); | 2112 | set_time_zone_rule (tzstring); |
| 2119 | environbuf = environ; | ||
| 2120 | |||
| 2121 | unblock_input (); | 2113 | unblock_input (); |
| 2122 | 2114 | ||
| 2123 | xfree (old_environbuf); | ||
| 2124 | return Qnil; | 2115 | return Qnil; |
| 2125 | } | 2116 | } |
| 2126 | 2117 | ||
| 2127 | #ifdef LOCALTIME_CACHE | ||
| 2128 | |||
| 2129 | /* These two values are known to load tz files in buggy implementations, | ||
| 2130 | i.e. Solaris 1 executables running under either Solaris 1 or Solaris 2. | ||
| 2131 | Their values shouldn't matter in non-buggy implementations. | ||
| 2132 | We don't use string literals for these strings, | ||
| 2133 | since if a string in the environment is in readonly | ||
| 2134 | storage, it runs afoul of bugs in SVR4 and Solaris 2.3. | ||
| 2135 | See Sun bugs 1113095 and 1114114, ``Timezone routines | ||
| 2136 | improperly modify environment''. */ | ||
| 2137 | |||
| 2138 | static char set_time_zone_rule_tz1[] = "TZ=GMT+0"; | ||
| 2139 | static char set_time_zone_rule_tz2[] = "TZ=GMT+1"; | ||
| 2140 | |||
| 2141 | #endif | ||
| 2142 | |||
| 2143 | /* Set the local time zone rule to TZSTRING. | 2118 | /* Set the local time zone rule to TZSTRING. |
| 2144 | This allocates memory into `environ', which it is the caller's | 2119 | |
| 2145 | responsibility to free. */ | 2120 | This function is not thread-safe, partly because putenv, unsetenv |
| 2121 | and tzset are not, and partly because of the static storage it | ||
| 2122 | updates. Other threads that invoke localtime etc. may be adversely | ||
| 2123 | affected while this function is executing. */ | ||
| 2146 | 2124 | ||
| 2147 | void | 2125 | void |
| 2148 | set_time_zone_rule (const char *tzstring) | 2126 | set_time_zone_rule (const char *tzstring) |
| 2149 | { | 2127 | { |
| 2150 | ptrdiff_t envptrs; | 2128 | /* A buffer holding a string of the form "TZ=value", intended |
| 2151 | char **from, **to, **newenv; | 2129 | to be part of the environment. */ |
| 2130 | static char *tzvalbuf; | ||
| 2131 | static ptrdiff_t tzvalbufsize; | ||
| 2152 | 2132 | ||
| 2153 | /* Make the ENVIRON vector longer with room for TZSTRING. */ | 2133 | int tzeqlen = sizeof "TZ=" - 1; |
| 2154 | for (from = environ; *from; from++) | 2134 | |
| 2155 | continue; | 2135 | #ifdef LOCALTIME_CACHE |
| 2156 | envptrs = from - environ + 2; | 2136 | /* These two values are known to load tz files in buggy implementations, |
| 2157 | newenv = to = xmalloc (envptrs * sizeof *newenv | 2137 | i.e., Solaris 1 executables running under either Solaris 1 or Solaris 2. |
| 2158 | + (tzstring ? strlen (tzstring) + 4 : 0)); | 2138 | Their values shouldn't matter in non-buggy implementations. |
| 2139 | We don't use string literals for these strings, | ||
| 2140 | since if a string in the environment is in readonly | ||
| 2141 | storage, it runs afoul of bugs in SVR4 and Solaris 2.3. | ||
| 2142 | See Sun bugs 1113095 and 1114114, ``Timezone routines | ||
| 2143 | improperly modify environment''. */ | ||
| 2144 | |||
| 2145 | static char set_time_zone_rule_tz[][sizeof "TZ=GMT+0"] | ||
| 2146 | = { "TZ=GMT+0", "TZ=GMT+1" }; | ||
| 2147 | |||
| 2148 | /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like | ||
| 2149 | "US/Pacific" that loads a tz file, then changes to a value like | ||
| 2150 | "XXX0" that does not load a tz file, and then changes back to | ||
| 2151 | its original value, the last change is (incorrectly) ignored. | ||
| 2152 | Also, if TZ changes twice in succession to values that do | ||
| 2153 | not load a tz file, tzset can dump core (see Sun bug#1225179). | ||
| 2154 | The following code works around these bugs. */ | ||
| 2159 | 2155 | ||
| 2160 | /* Add TZSTRING to the end of environ, as a value for TZ. */ | ||
| 2161 | if (tzstring) | 2156 | if (tzstring) |
| 2162 | { | 2157 | { |
| 2163 | char *t = (char *) (to + envptrs); | 2158 | /* Temporarily set TZ to a value that loads a tz file |
| 2164 | strcpy (t, "TZ="); | 2159 | and that differs from tzstring. */ |
| 2165 | strcat (t, tzstring); | 2160 | bool eq0 = strcmp (tzstring, set_time_zone_rule_tz[0] + tzeqlen) == 0; |
| 2166 | *to++ = t; | 2161 | xputenv (set_time_zone_rule_tz[eq0]); |
| 2167 | } | 2162 | } |
| 2163 | else | ||
| 2164 | { | ||
| 2165 | /* The implied tzstring is unknown, so temporarily set TZ to | ||
| 2166 | two different values that each load a tz file. */ | ||
| 2167 | xputenv (set_time_zone_rule_tz[0]); | ||
| 2168 | tzset (); | ||
| 2169 | xputenv (set_time_zone_rule_tz[1]); | ||
| 2170 | } | ||
| 2171 | tzset (); | ||
| 2172 | #endif | ||
| 2168 | 2173 | ||
| 2169 | /* Copy the old environ vector elements into NEWENV, | 2174 | if (!tzstring) |
| 2170 | but don't copy the TZ variable. | 2175 | { |
| 2171 | So we have only one definition of TZ, which came from TZSTRING. */ | 2176 | unsetenv ("TZ"); |
| 2172 | for (from = environ; *from; from++) | 2177 | tzvalbuf_in_environ = 0; |
| 2173 | if (strncmp (*from, "TZ=", 3) != 0) | 2178 | } |
| 2174 | *to++ = *from; | 2179 | else |
| 2175 | *to = 0; | 2180 | { |
| 2176 | 2181 | ptrdiff_t tzstringlen = strlen (tzstring); | |
| 2177 | environ = newenv; | ||
| 2178 | 2182 | ||
| 2179 | /* If we do have a TZSTRING, NEWENV points to the vector slot where | 2183 | if (tzvalbufsize <= tzeqlen + tzstringlen) |
| 2180 | the TZ variable is stored. If we do not have a TZSTRING, | 2184 | { |
| 2181 | TO points to the vector slot which has the terminating null. */ | 2185 | unsetenv ("TZ"); |
| 2186 | tzvalbuf_in_environ = 0; | ||
| 2187 | tzvalbuf = xpalloc (tzvalbuf, &tzvalbufsize, | ||
| 2188 | tzeqlen + tzstringlen - tzvalbufsize + 1, -1, 1); | ||
| 2189 | memcpy (tzvalbuf, "TZ=", tzeqlen); | ||
| 2190 | } | ||
| 2182 | 2191 | ||
| 2183 | #ifdef LOCALTIME_CACHE | 2192 | strcpy (tzvalbuf + tzeqlen, tzstring); |
| 2184 | { | ||
| 2185 | /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like | ||
| 2186 | "US/Pacific" that loads a tz file, then changes to a value like | ||
| 2187 | "XXX0" that does not load a tz file, and then changes back to | ||
| 2188 | its original value, the last change is (incorrectly) ignored. | ||
| 2189 | Also, if TZ changes twice in succession to values that do | ||
| 2190 | not load a tz file, tzset can dump core (see Sun bug#1225179). | ||
| 2191 | The following code works around these bugs. */ | ||
| 2192 | |||
| 2193 | if (tzstring) | ||
| 2194 | { | ||
| 2195 | /* Temporarily set TZ to a value that loads a tz file | ||
| 2196 | and that differs from tzstring. */ | ||
| 2197 | char *tz = *newenv; | ||
| 2198 | *newenv = (strcmp (tzstring, set_time_zone_rule_tz1 + 3) == 0 | ||
| 2199 | ? set_time_zone_rule_tz2 : set_time_zone_rule_tz1); | ||
| 2200 | tzset (); | ||
| 2201 | *newenv = tz; | ||
| 2202 | } | ||
| 2203 | else | ||
| 2204 | { | ||
| 2205 | /* The implied tzstring is unknown, so temporarily set TZ to | ||
| 2206 | two different values that each load a tz file. */ | ||
| 2207 | *to = set_time_zone_rule_tz1; | ||
| 2208 | to[1] = 0; | ||
| 2209 | tzset (); | ||
| 2210 | *to = set_time_zone_rule_tz2; | ||
| 2211 | tzset (); | ||
| 2212 | *to = 0; | ||
| 2213 | } | ||
| 2214 | 2193 | ||
| 2215 | /* Now TZ has the desired value, and tzset can be invoked safely. */ | 2194 | if (!tzvalbuf_in_environ) |
| 2216 | } | 2195 | { |
| 2196 | xputenv (tzvalbuf); | ||
| 2197 | tzvalbuf_in_environ = 1; | ||
| 2198 | } | ||
| 2199 | } | ||
| 2217 | 2200 | ||
| 2201 | #ifdef LOCALTIME_CACHE | ||
| 2218 | tzset (); | 2202 | tzset (); |
| 2219 | #endif | 2203 | #endif |
| 2220 | } | 2204 | } |
| @@ -2358,9 +2342,10 @@ usage: (insert-before-markers-and-inherit &rest ARGS) */) | |||
| 2358 | } | 2342 | } |
| 2359 | 2343 | ||
| 2360 | DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3, | 2344 | DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3, |
| 2361 | "(list (read-char-by-name \"Insert character (Unicode name or hex): \")\ | 2345 | "(list (or (read-char-by-name \"Insert character (Unicode name or hex): \")\ |
| 2362 | (prefix-numeric-value current-prefix-arg)\ | 2346 | (error \"You did not specify a valid character\"))\ |
| 2363 | t))", | 2347 | (prefix-numeric-value current-prefix-arg)\ |
| 2348 | t))", | ||
| 2364 | doc: /* Insert COUNT copies of CHARACTER. | 2349 | doc: /* Insert COUNT copies of CHARACTER. |
| 2365 | Interactively, prompt for CHARACTER. You can specify CHARACTER in one | 2350 | Interactively, prompt for CHARACTER. You can specify CHARACTER in one |
| 2366 | of these ways: | 2351 | of these ways: |
| @@ -2929,7 +2914,7 @@ Both characters must have the same length of multi-byte form. */) | |||
| 2929 | else if (!changed) | 2914 | else if (!changed) |
| 2930 | { | 2915 | { |
| 2931 | changed = -1; | 2916 | changed = -1; |
| 2932 | modify_region (current_buffer, pos, XINT (end), 0); | 2917 | modify_region_1 (pos, XINT (end), false); |
| 2933 | 2918 | ||
| 2934 | if (! NILP (noundo)) | 2919 | if (! NILP (noundo)) |
| 2935 | { | 2920 | { |
| @@ -3105,7 +3090,7 @@ It returns the number of characters changed. */) | |||
| 3105 | pos = XINT (start); | 3090 | pos = XINT (start); |
| 3106 | pos_byte = CHAR_TO_BYTE (pos); | 3091 | pos_byte = CHAR_TO_BYTE (pos); |
| 3107 | end_pos = XINT (end); | 3092 | end_pos = XINT (end); |
| 3108 | modify_region (current_buffer, pos, end_pos, 0); | 3093 | modify_region_1 (pos, end_pos, false); |
| 3109 | 3094 | ||
| 3110 | cnt = 0; | 3095 | cnt = 0; |
| 3111 | for (; pos < end_pos; ) | 3096 | for (; pos < end_pos; ) |
| @@ -4629,7 +4614,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4629 | 4614 | ||
| 4630 | if (end1 == start2) /* adjacent regions */ | 4615 | if (end1 == start2) /* adjacent regions */ |
| 4631 | { | 4616 | { |
| 4632 | modify_region (current_buffer, start1, end2, 0); | 4617 | modify_region_1 (start1, end2, false); |
| 4633 | record_change (start1, len1 + len2); | 4618 | record_change (start1, len1 + len2); |
| 4634 | 4619 | ||
| 4635 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4620 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| @@ -4688,8 +4673,8 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4688 | { | 4673 | { |
| 4689 | USE_SAFE_ALLOCA; | 4674 | USE_SAFE_ALLOCA; |
| 4690 | 4675 | ||
| 4691 | modify_region (current_buffer, start1, end1, 0); | 4676 | modify_region_1 (start1, end1, false); |
| 4692 | modify_region (current_buffer, start2, end2, 0); | 4677 | modify_region_1 (start2, end2, false); |
| 4693 | record_change (start1, len1); | 4678 | record_change (start1, len1); |
| 4694 | record_change (start2, len2); | 4679 | record_change (start2, len2); |
| 4695 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4680 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| @@ -4722,7 +4707,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4722 | { | 4707 | { |
| 4723 | USE_SAFE_ALLOCA; | 4708 | USE_SAFE_ALLOCA; |
| 4724 | 4709 | ||
| 4725 | modify_region (current_buffer, start1, end2, 0); | 4710 | modify_region_1 (start1, end2, false); |
| 4726 | record_change (start1, (end2 - start1)); | 4711 | record_change (start1, (end2 - start1)); |
| 4727 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4712 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| 4728 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); | 4713 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); |
| @@ -4755,7 +4740,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4755 | USE_SAFE_ALLOCA; | 4740 | USE_SAFE_ALLOCA; |
| 4756 | 4741 | ||
| 4757 | record_change (start1, (end2 - start1)); | 4742 | record_change (start1, (end2 - start1)); |
| 4758 | modify_region (current_buffer, start1, end2, 0); | 4743 | modify_region_1 (start1, end2, false); |
| 4759 | 4744 | ||
| 4760 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4745 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| 4761 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); | 4746 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); |
| @@ -4806,9 +4791,6 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4806 | void | 4791 | void |
| 4807 | syms_of_editfns (void) | 4792 | syms_of_editfns (void) |
| 4808 | { | 4793 | { |
| 4809 | environbuf = 0; | ||
| 4810 | initial_tz = 0; | ||
| 4811 | |||
| 4812 | DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); | 4794 | DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); |
| 4813 | 4795 | ||
| 4814 | DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, | 4796 | DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, |
diff --git a/src/emacs.c b/src/emacs.c index b2b193e3a4f..fbaf0355000 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -535,7 +535,7 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory, | |||
| 535 | #ifdef HAVE_TZSET | 535 | #ifdef HAVE_TZSET |
| 536 | /* A valid but unlikely value for the TZ environment value. | 536 | /* A valid but unlikely value for the TZ environment value. |
| 537 | It is OK (though a bit slower) if the user actually chooses this value. */ | 537 | It is OK (though a bit slower) if the user actually chooses this value. */ |
| 538 | static char dump_tz[] = "UtC0"; | 538 | static char const dump_tz[] = "UtC0"; |
| 539 | #endif | 539 | #endif |
| 540 | 540 | ||
| 541 | #ifndef ORDINARY_LINK | 541 | #ifndef ORDINARY_LINK |
| @@ -717,7 +717,7 @@ main (int argc, char **argv) | |||
| 717 | 717 | ||
| 718 | #ifdef G_SLICE_ALWAYS_MALLOC | 718 | #ifdef G_SLICE_ALWAYS_MALLOC |
| 719 | /* This is used by the Cygwin build. */ | 719 | /* This is used by the Cygwin build. */ |
| 720 | setenv ("G_SLICE", "always-malloc", 1); | 720 | xputenv ("G_SLICE=always-malloc"); |
| 721 | #endif | 721 | #endif |
| 722 | 722 | ||
| 723 | #ifdef GNU_LINUX | 723 | #ifdef GNU_LINUX |
| @@ -803,9 +803,8 @@ main (int argc, char **argv) | |||
| 803 | #ifdef HAVE_PERSONALITY_LINUX32 | 803 | #ifdef HAVE_PERSONALITY_LINUX32 |
| 804 | if (dumping && ! getenv ("EMACS_HEAP_EXEC")) | 804 | if (dumping && ! getenv ("EMACS_HEAP_EXEC")) |
| 805 | { | 805 | { |
| 806 | static char heapexec[] = "EMACS_HEAP_EXEC=true"; | ||
| 807 | /* Set this so we only do this once. */ | 806 | /* Set this so we only do this once. */ |
| 808 | putenv (heapexec); | 807 | xputenv ("EMACS_HEAP_EXEC=true"); |
| 809 | 808 | ||
| 810 | /* A flag to turn off address randomization which is introduced | 809 | /* A flag to turn off address randomization which is introduced |
| 811 | in linux kernel shipped with fedora core 4 */ | 810 | in linux kernel shipped with fedora core 4 */ |
| @@ -1309,7 +1308,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1309 | don't pollute Vglobal_environment. */ | 1308 | don't pollute Vglobal_environment. */ |
| 1310 | /* Setting LANG here will defeat the startup locale processing... */ | 1309 | /* Setting LANG here will defeat the startup locale processing... */ |
| 1311 | #ifdef AIX | 1310 | #ifdef AIX |
| 1312 | putenv ("LANG=C"); | 1311 | xputenv ("LANG=C"); |
| 1313 | #endif | 1312 | #endif |
| 1314 | 1313 | ||
| 1315 | init_buffer (); /* Init default directory of main buffer. */ | 1314 | init_buffer (); /* Init default directory of main buffer. */ |
diff --git a/src/fileio.c b/src/fileio.c index 442c66550d3..de3b84ba95d 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -455,7 +455,7 @@ get a current directory to run processes in. */) | |||
| 455 | 455 | ||
| 456 | /* Convert from file name SRC of length SRCLEN to directory name | 456 | /* Convert from file name SRC of length SRCLEN to directory name |
| 457 | in DST. On UNIX, just make sure there is a terminating /. | 457 | in DST. On UNIX, just make sure there is a terminating /. |
| 458 | Return the length of DST. */ | 458 | Return the length of DST in bytes. */ |
| 459 | 459 | ||
| 460 | static ptrdiff_t | 460 | static ptrdiff_t |
| 461 | file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) | 461 | file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) |
| @@ -477,7 +477,14 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) | |||
| 477 | srclen++; | 477 | srclen++; |
| 478 | } | 478 | } |
| 479 | #ifdef DOS_NT | 479 | #ifdef DOS_NT |
| 480 | dostounix_filename (dst); | 480 | { |
| 481 | Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1); | ||
| 482 | |||
| 483 | tem_fn = ENCODE_FILE (tem_fn); | ||
| 484 | dostounix_filename (SSDATA (tem_fn)); | ||
| 485 | tem_fn = DECODE_FILE (tem_fn); | ||
| 486 | memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1); | ||
| 487 | } | ||
| 481 | #endif | 488 | #endif |
| 482 | return srclen; | 489 | return srclen; |
| 483 | } | 490 | } |
| @@ -519,7 +526,7 @@ For a Unix-syntax file name, just appends a slash. */) | |||
| 519 | 526 | ||
| 520 | /* Convert from directory name SRC of length SRCLEN to | 527 | /* Convert from directory name SRC of length SRCLEN to |
| 521 | file name in DST. On UNIX, just make sure there isn't | 528 | file name in DST. On UNIX, just make sure there isn't |
| 522 | a terminating /. Return the length of DST. */ | 529 | a terminating /. Return the length of DST in bytes. */ |
| 523 | 530 | ||
| 524 | static ptrdiff_t | 531 | static ptrdiff_t |
| 525 | directory_file_name (char *dst, char *src, ptrdiff_t srclen) | 532 | directory_file_name (char *dst, char *src, ptrdiff_t srclen) |
| @@ -538,7 +545,14 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen) | |||
| 538 | srclen--; | 545 | srclen--; |
| 539 | } | 546 | } |
| 540 | #ifdef DOS_NT | 547 | #ifdef DOS_NT |
| 541 | dostounix_filename (dst); | 548 | { |
| 549 | Lisp_Object tem_fn = make_specified_string (dst, -1, srclen, 1); | ||
| 550 | |||
| 551 | tem_fn = ENCODE_FILE (tem_fn); | ||
| 552 | dostounix_filename (SSDATA (tem_fn)); | ||
| 553 | tem_fn = DECODE_FILE (tem_fn); | ||
| 554 | memcpy (dst, SSDATA (tem_fn), (srclen = SBYTES (tem_fn)) + 1); | ||
| 555 | } | ||
| 542 | #endif | 556 | #endif |
| 543 | return srclen; | 557 | return srclen; |
| 544 | } | 558 | } |
| @@ -1042,7 +1056,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1042 | o [p - nm] = 0; | 1056 | o [p - nm] = 0; |
| 1043 | 1057 | ||
| 1044 | block_input (); | 1058 | block_input (); |
| 1045 | pw = (struct passwd *) getpwnam (o + 1); | 1059 | pw = getpwnam (o + 1); |
| 1046 | unblock_input (); | 1060 | unblock_input (); |
| 1047 | if (pw) | 1061 | if (pw) |
| 1048 | { | 1062 | { |
| @@ -1995,10 +2009,8 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) | |||
| 1995 | { | 2009 | { |
| 1996 | if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode))) | 2010 | if (!(S_ISREG (st.st_mode)) && !(S_ISLNK (st.st_mode))) |
| 1997 | { | 2011 | { |
| 1998 | #if defined (EISDIR) | ||
| 1999 | /* Get a better looking error message. */ | 2012 | /* Get a better looking error message. */ |
| 2000 | errno = EISDIR; | 2013 | errno = EISDIR; |
| 2001 | #endif /* EISDIR */ | ||
| 2002 | report_file_error ("Non-regular file", Fcons (file, Qnil)); | 2014 | report_file_error ("Non-regular file", Fcons (file, Qnil)); |
| 2003 | } | 2015 | } |
| 2004 | } | 2016 | } |
| @@ -5773,7 +5785,7 @@ This applies only to the operation `inhibit-file-name-operation'. */); | |||
| 5773 | DEFVAR_LISP ("auto-save-list-file-name", Vauto_save_list_file_name, | 5785 | DEFVAR_LISP ("auto-save-list-file-name", Vauto_save_list_file_name, |
| 5774 | doc: /* File name in which we write a list of all auto save file names. | 5786 | doc: /* File name in which we write a list of all auto save file names. |
| 5775 | This variable is initialized automatically from `auto-save-list-file-prefix' | 5787 | This variable is initialized automatically from `auto-save-list-file-prefix' |
| 5776 | shortly after Emacs reads your `.emacs' file, if you have not yet given it | 5788 | shortly after Emacs reads your init file, if you have not yet given it |
| 5777 | a non-nil value. */); | 5789 | a non-nil value. */); |
| 5778 | Vauto_save_list_file_name = Qnil; | 5790 | Vauto_save_list_file_name = Qnil; |
| 5779 | 5791 | ||
diff --git a/src/font.c b/src/font.c index 41dbfd7a757..f6b6fa026c0 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -1234,8 +1234,21 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes) | |||
| 1234 | f[j] = "*"; | 1234 | f[j] = "*"; |
| 1235 | else | 1235 | else |
| 1236 | { | 1236 | { |
| 1237 | int c, k, l; | ||
| 1238 | ptrdiff_t alloc; | ||
| 1239 | |||
| 1237 | val = SYMBOL_NAME (val); | 1240 | val = SYMBOL_NAME (val); |
| 1238 | f[j] = SSDATA (val); | 1241 | alloc = SBYTES (val) + 1; |
| 1242 | if (nbytes <= alloc) | ||
| 1243 | return -1; | ||
| 1244 | f[j] = p = alloca (alloc); | ||
| 1245 | /* Copy the name while excluding '-', '?', ',', and '"'. */ | ||
| 1246 | for (k = l = 0; k < alloc; k++) | ||
| 1247 | { | ||
| 1248 | c = SREF (val, k); | ||
| 1249 | if (c != '-' && c != '?' && c != ',' && c != '"') | ||
| 1250 | p[l++] = c; | ||
| 1251 | } | ||
| 1239 | } | 1252 | } |
| 1240 | } | 1253 | } |
| 1241 | 1254 | ||
diff --git a/src/fontset.c b/src/fontset.c index b76a216bac2..660ca432fad 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -1876,6 +1876,8 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, | |||
| 1876 | } | 1876 | } |
| 1877 | if (! CHAR_VALID_P (c)) | 1877 | if (! CHAR_VALID_P (c)) |
| 1878 | return Qnil; | 1878 | return Qnil; |
| 1879 | if (!FRAME_WINDOW_P (f)) | ||
| 1880 | return Qnil; | ||
| 1879 | face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil); | 1881 | face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c, pos, Qnil); |
| 1880 | face = FACE_FROM_ID (f, face_id); | 1882 | face = FACE_FROM_ID (f, face_id); |
| 1881 | if (face->font) | 1883 | if (face->font) |
diff --git a/src/frame.c b/src/frame.c index 3501fc36675..5cefad6ca46 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -346,13 +346,10 @@ make_frame (int mini_p) | |||
| 346 | 346 | ||
| 347 | /* Choose a buffer for the frame's root window. */ | 347 | /* Choose a buffer for the frame's root window. */ |
| 348 | { | 348 | { |
| 349 | Lisp_Object buf; | 349 | Lisp_Object buf = Fcurrent_buffer (); |
| 350 | 350 | ||
| 351 | wset_buffer (XWINDOW (root_window), Qt); | 351 | /* If current buffer is hidden, try to find another one. */ |
| 352 | buf = Fcurrent_buffer (); | 352 | if (BUFFER_HIDDEN_P (XBUFFER (buf))) |
| 353 | /* If buf is a 'hidden' buffer (i.e. one whose name starts with | ||
| 354 | a space), try to find another one. */ | ||
| 355 | if (SREF (Fbuffer_name (buf), 0) == ' ') | ||
| 356 | buf = other_buffer_safely (buf); | 353 | buf = other_buffer_safely (buf); |
| 357 | 354 | ||
| 358 | /* Use set_window_buffer, not Fset_window_buffer, and don't let | 355 | /* Use set_window_buffer, not Fset_window_buffer, and don't let |
| @@ -366,14 +363,11 @@ make_frame (int mini_p) | |||
| 366 | } | 363 | } |
| 367 | 364 | ||
| 368 | if (mini_p) | 365 | if (mini_p) |
| 369 | { | 366 | set_window_buffer (mini_window, |
| 370 | wset_buffer (XWINDOW (mini_window), Qt); | 367 | (NILP (Vminibuffer_list) |
| 371 | set_window_buffer (mini_window, | 368 | ? get_minibuffer (0) |
| 372 | (NILP (Vminibuffer_list) | 369 | : Fcar (Vminibuffer_list)), |
| 373 | ? get_minibuffer (0) | 370 | 0, 0); |
| 374 | : Fcar (Vminibuffer_list)), | ||
| 375 | 0, 0); | ||
| 376 | } | ||
| 377 | 371 | ||
| 378 | fset_root_window (f, root_window); | 372 | fset_root_window (f, root_window); |
| 379 | fset_selected_window (f, root_window); | 373 | fset_selected_window (f, root_window); |
| @@ -895,13 +889,58 @@ DEFUN ("frame-list", Fframe_list, Sframe_list, | |||
| 895 | return frames; | 889 | return frames; |
| 896 | } | 890 | } |
| 897 | 891 | ||
| 898 | /* Return the next frame in the frame list after FRAME. | 892 | /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the |
| 899 | If MINIBUF is nil, exclude minibuffer-only frames. | 893 | same tty (for tty frames) or among frames which uses FRAME's keyboard. |
| 900 | If MINIBUF is a window, include only its own frame | 894 | If MINIBUF is nil, do not consider minibuffer-only candidate. |
| 901 | and any frame now using that window as the minibuffer. | 895 | If MINIBUF is `visible', do not consider an invisible candidate. |
| 902 | If MINIBUF is `visible', include all visible frames. | 896 | If MINIBUF is a window, consider only its own frame and candidate now |
| 903 | If MINIBUF is 0, include all visible and iconified frames. | 897 | using that window as the minibuffer. |
| 904 | Otherwise, include all frames. */ | 898 | If MINIBUF is 0, consider candidate if it is visible or iconified. |
| 899 | Otherwise consider any candidate and return nil if CANDIDATE is not | ||
| 900 | acceptable. */ | ||
| 901 | |||
| 902 | static Lisp_Object | ||
| 903 | candidate_frame (Lisp_Object candidate, Lisp_Object frame, Lisp_Object minibuf) | ||
| 904 | { | ||
| 905 | struct frame *c = XFRAME (candidate), *f = XFRAME (frame); | ||
| 906 | |||
| 907 | if ((!FRAME_TERMCAP_P (c) && !FRAME_TERMCAP_P (f) | ||
| 908 | && FRAME_KBOARD (c) == FRAME_KBOARD (f)) | ||
| 909 | || (FRAME_TERMCAP_P (c) && FRAME_TERMCAP_P (f) | ||
| 910 | && FRAME_TTY (c) == FRAME_TTY (f))) | ||
| 911 | { | ||
| 912 | if (NILP (minibuf)) | ||
| 913 | { | ||
| 914 | if (!FRAME_MINIBUF_ONLY_P (c)) | ||
| 915 | return candidate; | ||
| 916 | } | ||
| 917 | else if (EQ (minibuf, Qvisible)) | ||
| 918 | { | ||
| 919 | FRAME_SAMPLE_VISIBILITY (c); | ||
| 920 | if (FRAME_VISIBLE_P (c)) | ||
| 921 | return candidate; | ||
| 922 | } | ||
| 923 | else if (WINDOWP (minibuf)) | ||
| 924 | { | ||
| 925 | if (EQ (FRAME_MINIBUF_WINDOW (c), minibuf) | ||
| 926 | || EQ (WINDOW_FRAME (XWINDOW (minibuf)), candidate) | ||
| 927 | || EQ (WINDOW_FRAME (XWINDOW (minibuf)), | ||
| 928 | FRAME_FOCUS_FRAME (c))) | ||
| 929 | return candidate; | ||
| 930 | } | ||
| 931 | else if (XFASTINT (minibuf) == 0) | ||
| 932 | { | ||
| 933 | FRAME_SAMPLE_VISIBILITY (c); | ||
| 934 | if (FRAME_VISIBLE_P (c) || FRAME_ICONIFIED_P (c)) | ||
| 935 | return candidate; | ||
| 936 | } | ||
| 937 | else | ||
| 938 | return candidate; | ||
| 939 | } | ||
| 940 | return Qnil; | ||
| 941 | } | ||
| 942 | |||
| 943 | /* Return the next frame in the frame list after FRAME. */ | ||
| 905 | 944 | ||
| 906 | static Lisp_Object | 945 | static Lisp_Object |
| 907 | next_frame (Lisp_Object frame, Lisp_Object minibuf) | 946 | next_frame (Lisp_Object frame, Lisp_Object minibuf) |
| @@ -910,72 +949,24 @@ next_frame (Lisp_Object frame, Lisp_Object minibuf) | |||
| 910 | int passed = 0; | 949 | int passed = 0; |
| 911 | 950 | ||
| 912 | /* There must always be at least one frame in Vframe_list. */ | 951 | /* There must always be at least one frame in Vframe_list. */ |
| 913 | if (! CONSP (Vframe_list)) | 952 | eassert (CONSP (Vframe_list)); |
| 914 | emacs_abort (); | ||
| 915 | |||
| 916 | /* If this frame is dead, it won't be in Vframe_list, and we'll loop | ||
| 917 | forever. Forestall that. */ | ||
| 918 | CHECK_LIVE_FRAME (frame); | ||
| 919 | 953 | ||
| 920 | while (1) | 954 | while (passed < 2) |
| 921 | FOR_EACH_FRAME (tail, f) | 955 | FOR_EACH_FRAME (tail, f) |
| 922 | { | 956 | { |
| 923 | if (passed | 957 | if (passed) |
| 924 | && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) | ||
| 925 | && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) | ||
| 926 | || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame)) | ||
| 927 | && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))) | ||
| 928 | { | 958 | { |
| 929 | /* Decide whether this frame is eligible to be returned. */ | 959 | f = candidate_frame (f, frame, minibuf); |
| 930 | 960 | if (!NILP (f)) | |
| 931 | /* If we've looped all the way around without finding any | ||
| 932 | eligible frames, return the original frame. */ | ||
| 933 | if (EQ (f, frame)) | ||
| 934 | return f; | ||
| 935 | |||
| 936 | /* Let minibuf decide if this frame is acceptable. */ | ||
| 937 | if (NILP (minibuf)) | ||
| 938 | { | ||
| 939 | if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) | ||
| 940 | return f; | ||
| 941 | } | ||
| 942 | else if (EQ (minibuf, Qvisible)) | ||
| 943 | { | ||
| 944 | FRAME_SAMPLE_VISIBILITY (XFRAME (f)); | ||
| 945 | if (FRAME_VISIBLE_P (XFRAME (f))) | ||
| 946 | return f; | ||
| 947 | } | ||
| 948 | else if (INTEGERP (minibuf) && XINT (minibuf) == 0) | ||
| 949 | { | ||
| 950 | FRAME_SAMPLE_VISIBILITY (XFRAME (f)); | ||
| 951 | if (FRAME_VISIBLE_P (XFRAME (f)) | ||
| 952 | || FRAME_ICONIFIED_P (XFRAME (f))) | ||
| 953 | return f; | ||
| 954 | } | ||
| 955 | else if (WINDOWP (minibuf)) | ||
| 956 | { | ||
| 957 | if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf) | ||
| 958 | || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f) | ||
| 959 | || EQ (WINDOW_FRAME (XWINDOW (minibuf)), | ||
| 960 | FRAME_FOCUS_FRAME (XFRAME (f)))) | ||
| 961 | return f; | ||
| 962 | } | ||
| 963 | else | ||
| 964 | return f; | 961 | return f; |
| 965 | } | 962 | } |
| 966 | |||
| 967 | if (EQ (frame, f)) | 963 | if (EQ (frame, f)) |
| 968 | passed++; | 964 | passed++; |
| 969 | } | 965 | } |
| 966 | return frame; | ||
| 970 | } | 967 | } |
| 971 | 968 | ||
| 972 | /* Return the previous frame in the frame list before FRAME. | 969 | /* Return the previous frame in the frame list before FRAME. */ |
| 973 | If MINIBUF is nil, exclude minibuffer-only frames. | ||
| 974 | If MINIBUF is a window, include only its own frame | ||
| 975 | and any frame now using that window as the minibuffer. | ||
| 976 | If MINIBUF is `visible', include all visible frames. | ||
| 977 | If MINIBUF is 0, include all visible and iconified frames. | ||
| 978 | Otherwise, include all frames. */ | ||
| 979 | 970 | ||
| 980 | static Lisp_Object | 971 | static Lisp_Object |
| 981 | prev_frame (Lisp_Object frame, Lisp_Object minibuf) | 972 | prev_frame (Lisp_Object frame, Lisp_Object minibuf) |
| @@ -989,43 +980,9 @@ prev_frame (Lisp_Object frame, Lisp_Object minibuf) | |||
| 989 | { | 980 | { |
| 990 | if (EQ (frame, f) && !NILP (prev)) | 981 | if (EQ (frame, f) && !NILP (prev)) |
| 991 | return prev; | 982 | return prev; |
| 992 | 983 | f = candidate_frame (f, frame, minibuf); | |
| 993 | if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame)) | 984 | if (!NILP (f)) |
| 994 | && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame))) | 985 | prev = f; |
| 995 | || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame)) | ||
| 996 | && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))) | ||
| 997 | { | ||
| 998 | /* Decide whether this frame is eligible to be returned, | ||
| 999 | according to minibuf. */ | ||
| 1000 | if (NILP (minibuf)) | ||
| 1001 | { | ||
| 1002 | if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) | ||
| 1003 | prev = f; | ||
| 1004 | } | ||
| 1005 | else if (WINDOWP (minibuf)) | ||
| 1006 | { | ||
| 1007 | if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf) | ||
| 1008 | || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f) | ||
| 1009 | || EQ (WINDOW_FRAME (XWINDOW (minibuf)), | ||
| 1010 | FRAME_FOCUS_FRAME (XFRAME (f)))) | ||
| 1011 | prev = f; | ||
| 1012 | } | ||
| 1013 | else if (EQ (minibuf, Qvisible)) | ||
| 1014 | { | ||
| 1015 | FRAME_SAMPLE_VISIBILITY (XFRAME (f)); | ||
| 1016 | if (FRAME_VISIBLE_P (XFRAME (f))) | ||
| 1017 | prev = f; | ||
| 1018 | } | ||
| 1019 | else if (XFASTINT (minibuf) == 0) | ||
| 1020 | { | ||
| 1021 | FRAME_SAMPLE_VISIBILITY (XFRAME (f)); | ||
| 1022 | if (FRAME_VISIBLE_P (XFRAME (f)) | ||
| 1023 | || FRAME_ICONIFIED_P (XFRAME (f))) | ||
| 1024 | prev = f; | ||
| 1025 | } | ||
| 1026 | else | ||
| 1027 | prev = f; | ||
| 1028 | } | ||
| 1029 | } | 986 | } |
| 1030 | 987 | ||
| 1031 | /* We've scanned the entire list. */ | 988 | /* We've scanned the entire list. */ |
| @@ -1056,7 +1013,6 @@ Otherwise, include all frames. */) | |||
| 1056 | { | 1013 | { |
| 1057 | if (NILP (frame)) | 1014 | if (NILP (frame)) |
| 1058 | frame = selected_frame; | 1015 | frame = selected_frame; |
| 1059 | |||
| 1060 | CHECK_LIVE_FRAME (frame); | 1016 | CHECK_LIVE_FRAME (frame); |
| 1061 | return next_frame (frame, miniframe); | 1017 | return next_frame (frame, miniframe); |
| 1062 | } | 1018 | } |
| @@ -2314,7 +2270,7 @@ For a terminal frame, the value is always 1. */) | |||
| 2314 | struct frame *f = decode_any_frame (frame); | 2270 | struct frame *f = decode_any_frame (frame); |
| 2315 | 2271 | ||
| 2316 | if (FRAME_WINDOW_P (f)) | 2272 | if (FRAME_WINDOW_P (f)) |
| 2317 | return make_number (x_char_height (f)); | 2273 | return make_number (FRAME_LINE_HEIGHT (f)); |
| 2318 | else | 2274 | else |
| 2319 | #endif | 2275 | #endif |
| 2320 | return make_number (1); | 2276 | return make_number (1); |
| @@ -2333,7 +2289,7 @@ For a terminal screen, the value is always 1. */) | |||
| 2333 | struct frame *f = decode_any_frame (frame); | 2289 | struct frame *f = decode_any_frame (frame); |
| 2334 | 2290 | ||
| 2335 | if (FRAME_WINDOW_P (f)) | 2291 | if (FRAME_WINDOW_P (f)) |
| 2336 | return make_number (x_char_width (f)); | 2292 | return make_number (FRAME_COLUMN_WIDTH (f)); |
| 2337 | else | 2293 | else |
| 2338 | #endif | 2294 | #endif |
| 2339 | return make_number (1); | 2295 | return make_number (1); |
diff --git a/src/frame.h b/src/frame.h index 5ebfc2f7ec3..589b45fc0ff 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -301,9 +301,6 @@ struct frame | |||
| 301 | /* Canonical X unit. Width of default font, in pixels. */ | 301 | /* Canonical X unit. Width of default font, in pixels. */ |
| 302 | int column_width; | 302 | int column_width; |
| 303 | 303 | ||
| 304 | /* Width of space glyph of default font, in pixels. */ | ||
| 305 | int space_width; | ||
| 306 | |||
| 307 | /* Canonical Y unit. Height of a line, in pixels. */ | 304 | /* Canonical Y unit. Height of a line, in pixels. */ |
| 308 | int line_height; | 305 | int line_height; |
| 309 | 306 | ||
| @@ -1000,11 +997,6 @@ extern Lisp_Object selected_frame; | |||
| 1000 | 997 | ||
| 1001 | #define FRAME_COLUMN_WIDTH(F) ((F)->column_width) | 998 | #define FRAME_COLUMN_WIDTH(F) ((F)->column_width) |
| 1002 | 999 | ||
| 1003 | /* Space glyph width of the default font of frame F. */ | ||
| 1004 | |||
| 1005 | #define FRAME_SPACE_WIDTH(F) ((F)->space_width) | ||
| 1006 | |||
| 1007 | |||
| 1008 | /* Pixel width of areas used to display truncation marks, continuation | 1000 | /* Pixel width of areas used to display truncation marks, continuation |
| 1009 | marks, overlay arrows. This is 0 for terminal frames. */ | 1001 | marks, overlay arrows. This is 0 for terminal frames. */ |
| 1010 | 1002 | ||
| @@ -1263,8 +1255,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); | |||
| 1263 | extern void x_make_frame_visible (struct frame *f); | 1255 | extern void x_make_frame_visible (struct frame *f); |
| 1264 | extern void x_make_frame_invisible (struct frame *f); | 1256 | extern void x_make_frame_invisible (struct frame *f); |
| 1265 | extern void x_iconify_frame (struct frame *f); | 1257 | extern void x_iconify_frame (struct frame *f); |
| 1266 | extern int x_char_width (struct frame *f); | ||
| 1267 | extern int x_char_height (struct frame *f); | ||
| 1268 | extern int x_pixel_width (struct frame *f); | 1258 | extern int x_pixel_width (struct frame *f); |
| 1269 | extern int x_pixel_height (struct frame *f); | 1259 | extern int x_pixel_height (struct frame *f); |
| 1270 | extern void x_set_frame_alpha (struct frame *f); | 1260 | extern void x_set_frame_alpha (struct frame *f); |
diff --git a/src/gmalloc.c b/src/gmalloc.c index dc584955661..c325ca79910 100644 --- a/src/gmalloc.c +++ b/src/gmalloc.c | |||
| @@ -1645,14 +1645,6 @@ memalign (size_t alignment, size_t size) | |||
| 1645 | return result; | 1645 | return result; |
| 1646 | } | 1646 | } |
| 1647 | 1647 | ||
| 1648 | #ifndef ENOMEM | ||
| 1649 | #define ENOMEM 12 | ||
| 1650 | #endif | ||
| 1651 | |||
| 1652 | #ifndef EINVAL | ||
| 1653 | #define EINVAL 22 | ||
| 1654 | #endif | ||
| 1655 | |||
| 1656 | int | 1648 | int |
| 1657 | posix_memalign (void **memptr, size_t alignment, size_t size) | 1649 | posix_memalign (void **memptr, size_t alignment, size_t size) |
| 1658 | { | 1650 | { |
diff --git a/src/gnutls.c b/src/gnutls.c index e3d84a0b61b..03f753fa8cc 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -359,12 +359,7 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) | |||
| 359 | 359 | ||
| 360 | if (proc->gnutls_initstage != GNUTLS_STAGE_READY) | 360 | if (proc->gnutls_initstage != GNUTLS_STAGE_READY) |
| 361 | { | 361 | { |
| 362 | #ifdef EWOULDBLOCK | ||
| 363 | errno = EWOULDBLOCK; | ||
| 364 | #endif | ||
| 365 | #ifdef EAGAIN | ||
| 366 | errno = EAGAIN; | 362 | errno = EAGAIN; |
| 367 | #endif | ||
| 368 | return 0; | 363 | return 0; |
| 369 | } | 364 | } |
| 370 | 365 | ||
| @@ -384,14 +379,7 @@ emacs_gnutls_write (struct Lisp_Process *proc, const char *buf, ptrdiff_t nbyte) | |||
| 384 | appropriately so that send_process retries the | 379 | appropriately so that send_process retries the |
| 385 | correct way instead of erroring out. */ | 380 | correct way instead of erroring out. */ |
| 386 | if (rtnval == GNUTLS_E_AGAIN) | 381 | if (rtnval == GNUTLS_E_AGAIN) |
| 387 | { | 382 | errno = EAGAIN; |
| 388 | #ifdef EWOULDBLOCK | ||
| 389 | errno = EWOULDBLOCK; | ||
| 390 | #endif | ||
| 391 | #ifdef EAGAIN | ||
| 392 | errno = EAGAIN; | ||
| 393 | #endif | ||
| 394 | } | ||
| 395 | break; | 383 | break; |
| 396 | } | 384 | } |
| 397 | } | 385 | } |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 4367b534cb9..52a6c37b0d5 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -813,6 +813,14 @@ xg_hide_tooltip (FRAME_PTR f) | |||
| 813 | General functions for creating widgets, resizing, events, e.t.c. | 813 | General functions for creating widgets, resizing, events, e.t.c. |
| 814 | ***********************************************************************/ | 814 | ***********************************************************************/ |
| 815 | 815 | ||
| 816 | static void | ||
| 817 | my_log_handler (const gchar *log_domain, GLogLevelFlags log_level, | ||
| 818 | const gchar *msg, gpointer user_data) | ||
| 819 | { | ||
| 820 | if (!strstr (msg, "visible children")) | ||
| 821 | fprintf (stderr, "XX %s-WARNING **: %s\n", log_domain, msg); | ||
| 822 | } | ||
| 823 | |||
| 816 | /* Make a geometry string and pass that to GTK. It seems this is the | 824 | /* Make a geometry string and pass that to GTK. It seems this is the |
| 817 | only way to get geometry position right if the user explicitly | 825 | only way to get geometry position right if the user explicitly |
| 818 | asked for a position when starting Emacs. | 826 | asked for a position when starting Emacs. |
| @@ -828,6 +836,7 @@ xg_set_geometry (FRAME_PTR f) | |||
| 828 | int top = f->top_pos; | 836 | int top = f->top_pos; |
| 829 | int yneg = f->size_hint_flags & YNegative; | 837 | int yneg = f->size_hint_flags & YNegative; |
| 830 | char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)]; | 838 | char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)]; |
| 839 | guint id; | ||
| 831 | 840 | ||
| 832 | if (xneg) | 841 | if (xneg) |
| 833 | left = -left; | 842 | left = -left; |
| @@ -840,9 +849,15 @@ xg_set_geometry (FRAME_PTR f) | |||
| 840 | (xneg ? '-' : '+'), left, | 849 | (xneg ? '-' : '+'), left, |
| 841 | (yneg ? '-' : '+'), top); | 850 | (yneg ? '-' : '+'), top); |
| 842 | 851 | ||
| 852 | /* Silence warning about visible children. */ | ||
| 853 | id = g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | ||
| 854 | | G_LOG_FLAG_RECURSION, my_log_handler, NULL); | ||
| 855 | |||
| 843 | if (!gtk_window_parse_geometry (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), | 856 | if (!gtk_window_parse_geometry (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), |
| 844 | geom_str)) | 857 | geom_str)) |
| 845 | fprintf (stderr, "Failed to parse: '%s'\n", geom_str); | 858 | fprintf (stderr, "Failed to parse: '%s'\n", geom_str); |
| 859 | |||
| 860 | g_log_remove_handler ("Gtk", id); | ||
| 846 | } | 861 | } |
| 847 | } | 862 | } |
| 848 | 863 | ||
diff --git a/src/insdel.c b/src/insdel.c index 87010cd8251..892ca3d5216 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -1755,9 +1755,9 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, | |||
| 1755 | 1755 | ||
| 1756 | return deletion; | 1756 | return deletion; |
| 1757 | } | 1757 | } |
| 1758 | 1758 | ||
| 1759 | /* Call this if you're about to change the region of BUFFER from | 1759 | /* Call this if you're about to change the region of current buffer |
| 1760 | character positions START to END. This checks the read-only | 1760 | from character positions START to END. This checks the read-only |
| 1761 | properties of the region, calls the necessary modification hooks, | 1761 | properties of the region, calls the necessary modification hooks, |
| 1762 | and warns the next redisplay that it should pay attention to that | 1762 | and warns the next redisplay that it should pay attention to that |
| 1763 | area. | 1763 | area. |
| @@ -1766,16 +1766,11 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, | |||
| 1766 | Otherwise set CHARS_MODIFF to the new value of MODIFF. */ | 1766 | Otherwise set CHARS_MODIFF to the new value of MODIFF. */ |
| 1767 | 1767 | ||
| 1768 | void | 1768 | void |
| 1769 | modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, | 1769 | modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) |
| 1770 | bool preserve_chars_modiff) | ||
| 1771 | { | 1770 | { |
| 1772 | struct buffer *old_buffer = current_buffer; | ||
| 1773 | |||
| 1774 | set_buffer_internal (buffer); | ||
| 1775 | |||
| 1776 | prepare_to_modify_buffer (start, end, NULL); | 1771 | prepare_to_modify_buffer (start, end, NULL); |
| 1777 | 1772 | ||
| 1778 | BUF_COMPUTE_UNCHANGED (buffer, start - 1, end); | 1773 | BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); |
| 1779 | 1774 | ||
| 1780 | if (MODIFF <= SAVE_MODIFF) | 1775 | if (MODIFF <= SAVE_MODIFF) |
| 1781 | record_first_change (); | 1776 | record_first_change (); |
| @@ -1783,11 +1778,9 @@ modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, | |||
| 1783 | if (! preserve_chars_modiff) | 1778 | if (! preserve_chars_modiff) |
| 1784 | CHARS_MODIFF = MODIFF; | 1779 | CHARS_MODIFF = MODIFF; |
| 1785 | 1780 | ||
| 1786 | bset_point_before_scroll (buffer, Qnil); | 1781 | bset_point_before_scroll (current_buffer, Qnil); |
| 1787 | |||
| 1788 | set_buffer_internal (old_buffer); | ||
| 1789 | } | 1782 | } |
| 1790 | 1783 | ||
| 1791 | /* Check that it is okay to modify the buffer between START and END, | 1784 | /* Check that it is okay to modify the buffer between START and END, |
| 1792 | which are char positions. | 1785 | which are char positions. |
| 1793 | 1786 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 0ad6d18c044..fc155c5a5f7 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1116,8 +1116,7 @@ cmd_error_internal (Lisp_Object data, const char *context) | |||
| 1116 | 1116 | ||
| 1117 | Vsignaling_function = Qnil; | 1117 | Vsignaling_function = Qnil; |
| 1118 | } | 1118 | } |
| 1119 | 1119 | ||
| 1120 | Lisp_Object command_loop_1 (void); | ||
| 1121 | static Lisp_Object command_loop_2 (Lisp_Object); | 1120 | static Lisp_Object command_loop_2 (Lisp_Object); |
| 1122 | static Lisp_Object top_level_1 (Lisp_Object); | 1121 | static Lisp_Object top_level_1 (Lisp_Object); |
| 1123 | 1122 | ||
| @@ -1154,7 +1153,7 @@ command_loop (void) | |||
| 1154 | value to us. A value of nil means that command_loop_1 itself | 1153 | value to us. A value of nil means that command_loop_1 itself |
| 1155 | returned due to end of file (or end of kbd macro). */ | 1154 | returned due to end of file (or end of kbd macro). */ |
| 1156 | 1155 | ||
| 1157 | Lisp_Object | 1156 | static Lisp_Object |
| 1158 | command_loop_2 (Lisp_Object ignore) | 1157 | command_loop_2 (Lisp_Object ignore) |
| 1159 | { | 1158 | { |
| 1160 | register Lisp_Object val; | 1159 | register Lisp_Object val; |
| @@ -1172,7 +1171,7 @@ top_level_2 (void) | |||
| 1172 | return Feval (Vtop_level, Qnil); | 1171 | return Feval (Vtop_level, Qnil); |
| 1173 | } | 1172 | } |
| 1174 | 1173 | ||
| 1175 | Lisp_Object | 1174 | static Lisp_Object |
| 1176 | top_level_1 (Lisp_Object ignore) | 1175 | top_level_1 (Lisp_Object ignore) |
| 1177 | { | 1176 | { |
| 1178 | /* On entry to the outer level, run the startup file */ | 1177 | /* On entry to the outer level, run the startup file */ |
| @@ -6960,10 +6959,7 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 6960 | an EAGAIN error. Does anybody know of a situation | 6959 | an EAGAIN error. Does anybody know of a situation |
| 6961 | where a retry is actually needed? */ | 6960 | where a retry is actually needed? */ |
| 6962 | #if 0 | 6961 | #if 0 |
| 6963 | nread < 0 && (errno == EAGAIN | 6962 | nread < 0 && (errno == EAGAIN || errno == EFAULT |
| 6964 | #ifdef EFAULT | ||
| 6965 | || errno == EFAULT | ||
| 6966 | #endif | ||
| 6967 | #ifdef EBADSLT | 6963 | #ifdef EBADSLT |
| 6968 | || errno == EBADSLT | 6964 | || errno == EBADSLT |
| 6969 | #endif | 6965 | #endif |
| @@ -10692,7 +10688,7 @@ handle_interrupt (bool in_signal_handler) | |||
| 10692 | fflush (stdout); | 10688 | fflush (stdout); |
| 10693 | reset_all_sys_modes (); | 10689 | reset_all_sys_modes (); |
| 10694 | 10690 | ||
| 10695 | #ifdef SIGTSTP /* Support possible in later USG versions */ | 10691 | #ifdef SIGTSTP |
| 10696 | /* | 10692 | /* |
| 10697 | * On systems which can suspend the current process and return to the original | 10693 | * On systems which can suspend the current process and return to the original |
| 10698 | * shell, this command causes the user to end up back at the shell. | 10694 | * shell, this command causes the user to end up back at the shell. |
diff --git a/src/lisp.h b/src/lisp.h index 419176d06c8..91fc3dfa1c6 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1644,7 +1644,6 @@ typedef struct { | |||
| 1644 | int mouse_face_beg_x, mouse_face_beg_y; | 1644 | int mouse_face_beg_x, mouse_face_beg_y; |
| 1645 | int mouse_face_end_row, mouse_face_end_col; | 1645 | int mouse_face_end_row, mouse_face_end_col; |
| 1646 | int mouse_face_end_x, mouse_face_end_y; | 1646 | int mouse_face_end_x, mouse_face_end_y; |
| 1647 | int mouse_face_past_end; | ||
| 1648 | Lisp_Object mouse_face_window; | 1647 | Lisp_Object mouse_face_window; |
| 1649 | int mouse_face_face_id; | 1648 | int mouse_face_face_id; |
| 1650 | Lisp_Object mouse_face_overlay; | 1649 | Lisp_Object mouse_face_overlay; |
| @@ -1654,13 +1653,15 @@ typedef struct { | |||
| 1654 | struct frame *mouse_face_mouse_frame; | 1653 | struct frame *mouse_face_mouse_frame; |
| 1655 | int mouse_face_mouse_x, mouse_face_mouse_y; | 1654 | int mouse_face_mouse_x, mouse_face_mouse_y; |
| 1656 | 1655 | ||
| 1656 | /* Nonzero if part of the text currently shown in | ||
| 1657 | its mouse-face is beyond the window end. */ | ||
| 1658 | unsigned mouse_face_past_end : 1; | ||
| 1659 | |||
| 1657 | /* Nonzero means defer mouse-motion highlighting. */ | 1660 | /* Nonzero means defer mouse-motion highlighting. */ |
| 1658 | int mouse_face_defer; | 1661 | unsigned mouse_face_defer : 1; |
| 1659 | 1662 | ||
| 1660 | /* Nonzero means that the mouse highlight should not be shown. */ | 1663 | /* Nonzero means that the mouse highlight should not be shown. */ |
| 1661 | int mouse_face_hidden; | 1664 | unsigned mouse_face_hidden : 1; |
| 1662 | |||
| 1663 | int mouse_face_image_state; | ||
| 1664 | } Mouse_HLInfo; | 1665 | } Mouse_HLInfo; |
| 1665 | 1666 | ||
| 1666 | /* Data type checking. */ | 1667 | /* Data type checking. */ |
| @@ -2796,7 +2797,7 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool); | |||
| 2796 | extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); | 2797 | extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); |
| 2797 | extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, | 2798 | extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, |
| 2798 | ptrdiff_t, ptrdiff_t, bool); | 2799 | ptrdiff_t, ptrdiff_t, bool); |
| 2799 | extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, bool); | 2800 | extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); |
| 2800 | extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); | 2801 | extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); |
| 2801 | extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); | 2802 | extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 2802 | extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, | 2803 | extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| @@ -2963,6 +2964,7 @@ extern Lisp_Object make_float (double); | |||
| 2963 | extern void display_malloc_warning (void); | 2964 | extern void display_malloc_warning (void); |
| 2964 | extern ptrdiff_t inhibit_garbage_collection (void); | 2965 | extern ptrdiff_t inhibit_garbage_collection (void); |
| 2965 | extern Lisp_Object make_save_value (void *, ptrdiff_t); | 2966 | extern Lisp_Object make_save_value (void *, ptrdiff_t); |
| 2967 | extern void free_save_value (Lisp_Object); | ||
| 2966 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); | 2968 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); |
| 2967 | extern void free_marker (Lisp_Object); | 2969 | extern void free_marker (Lisp_Object); |
| 2968 | extern void free_cons (struct Lisp_Cons *); | 2970 | extern void free_cons (struct Lisp_Cons *); |
| @@ -3393,7 +3395,6 @@ extern void syms_of_doc (void); | |||
| 3393 | extern int read_bytecode_char (bool); | 3395 | extern int read_bytecode_char (bool); |
| 3394 | 3396 | ||
| 3395 | /* Defined in bytecode.c. */ | 3397 | /* Defined in bytecode.c. */ |
| 3396 | extern Lisp_Object Qbytecode; | ||
| 3397 | extern void syms_of_bytecode (void); | 3398 | extern void syms_of_bytecode (void); |
| 3398 | extern struct byte_stack *byte_stack_list; | 3399 | extern struct byte_stack *byte_stack_list; |
| 3399 | #if BYTE_MARK_STACK | 3400 | #if BYTE_MARK_STACK |
| @@ -3593,6 +3594,7 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t); | |||
| 3593 | extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); | 3594 | extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 3594 | 3595 | ||
| 3595 | extern char *xstrdup (const char *); | 3596 | extern char *xstrdup (const char *); |
| 3597 | extern void xputenv (const char *); | ||
| 3596 | 3598 | ||
| 3597 | extern char *egetenv (const char *); | 3599 | extern char *egetenv (const char *); |
| 3598 | 3600 | ||
diff --git a/src/lread.c b/src/lread.c index 6d0ff9f780e..6647382a254 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -440,7 +440,6 @@ readbyte_from_file (int c, Lisp_Object readcharfun) | |||
| 440 | block_input (); | 440 | block_input (); |
| 441 | c = getc (instream); | 441 | c = getc (instream); |
| 442 | 442 | ||
| 443 | #ifdef EINTR | ||
| 444 | /* Interrupted reads have been observed while reading over the network. */ | 443 | /* Interrupted reads have been observed while reading over the network. */ |
| 445 | while (c == EOF && ferror (instream) && errno == EINTR) | 444 | while (c == EOF && ferror (instream) && errno == EINTR) |
| 446 | { | 445 | { |
| @@ -450,7 +449,6 @@ readbyte_from_file (int c, Lisp_Object readcharfun) | |||
| 450 | clearerr (instream); | 449 | clearerr (instream); |
| 451 | c = getc (instream); | 450 | c = getc (instream); |
| 452 | } | 451 | } |
| 453 | #endif | ||
| 454 | 452 | ||
| 455 | unblock_input (); | 453 | unblock_input (); |
| 456 | 454 | ||
diff --git a/src/nsfns.m b/src/nsfns.m index e8bf696e7f5..428cfcb9a10 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -2243,20 +2243,6 @@ x_pixel_height (struct frame *f) | |||
| 2243 | 2243 | ||
| 2244 | 2244 | ||
| 2245 | int | 2245 | int |
| 2246 | x_char_width (struct frame *f) | ||
| 2247 | { | ||
| 2248 | return FRAME_COLUMN_WIDTH (f); | ||
| 2249 | } | ||
| 2250 | |||
| 2251 | |||
| 2252 | int | ||
| 2253 | x_char_height (struct frame *f) | ||
| 2254 | { | ||
| 2255 | return FRAME_LINE_HEIGHT (f); | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | |||
| 2259 | int | ||
| 2260 | x_screen_planes (struct frame *f) | 2246 | x_screen_planes (struct frame *f) |
| 2261 | { | 2247 | { |
| 2262 | return FRAME_NS_DISPLAY_INFO (f)->n_planes; | 2248 | return FRAME_NS_DISPLAY_INFO (f)->n_planes; |
diff --git a/src/nsterm.m b/src/nsterm.m index 25eb7ebc495..55a106b7e03 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -6954,7 +6954,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) | |||
| 6954 | 6954 | ||
| 6955 | FRAME_BASELINE_OFFSET (f) = font->baseline_offset; | 6955 | FRAME_BASELINE_OFFSET (f) = font->baseline_offset; |
| 6956 | FRAME_COLUMN_WIDTH (f) = font->average_width; | 6956 | FRAME_COLUMN_WIDTH (f) = font->average_width; |
| 6957 | FRAME_SPACE_WIDTH (f) = font->space_width; | ||
| 6958 | FRAME_LINE_HEIGHT (f) = font->height; | 6957 | FRAME_LINE_HEIGHT (f) = font->height; |
| 6959 | 6958 | ||
| 6960 | compute_fringe_widths (f, 1); | 6959 | compute_fringe_widths (f, 1); |
diff --git a/src/process.c b/src/process.c index 0036ce595f5..7b21d060cf8 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -91,6 +91,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 91 | #include <pty.h> | 91 | #include <pty.h> |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | #include <c-ctype.h> | ||
| 95 | #include <sig2str.h> | ||
| 96 | |||
| 94 | #endif /* subprocesses */ | 97 | #endif /* subprocesses */ |
| 95 | 98 | ||
| 96 | #include "systime.h" | 99 | #include "systime.h" |
| @@ -773,13 +776,22 @@ get_process (register Lisp_Object name) | |||
| 773 | } | 776 | } |
| 774 | 777 | ||
| 775 | 778 | ||
| 776 | #ifdef SIGCHLD | ||
| 777 | /* Fdelete_process promises to immediately forget about the process, but in | 779 | /* Fdelete_process promises to immediately forget about the process, but in |
| 778 | reality, Emacs needs to remember those processes until they have been | 780 | reality, Emacs needs to remember those processes until they have been |
| 779 | treated by the SIGCHLD handler and waitpid has been invoked on them; | 781 | treated by the SIGCHLD handler and waitpid has been invoked on them; |
| 780 | otherwise they might fill up the kernel's process table. */ | 782 | otherwise they might fill up the kernel's process table. |
| 783 | |||
| 784 | Some processes created by call-process are also put onto this list. */ | ||
| 781 | static Lisp_Object deleted_pid_list; | 785 | static Lisp_Object deleted_pid_list; |
| 782 | #endif | 786 | |
| 787 | void | ||
| 788 | record_deleted_pid (pid_t pid) | ||
| 789 | { | ||
| 790 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), | ||
| 791 | /* GC treated elements set to nil. */ | ||
| 792 | Fdelq (Qnil, deleted_pid_list)); | ||
| 793 | |||
| 794 | } | ||
| 783 | 795 | ||
| 784 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, | 796 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, |
| 785 | doc: /* Delete PROCESS: kill it and forget about it immediately. | 797 | doc: /* Delete PROCESS: kill it and forget about it immediately. |
| @@ -800,32 +812,22 @@ nil, indicating the current buffer's process. */) | |||
| 800 | status_notify (p); | 812 | status_notify (p); |
| 801 | redisplay_preserve_echo_area (13); | 813 | redisplay_preserve_echo_area (13); |
| 802 | } | 814 | } |
| 803 | else if (p->infd >= 0) | 815 | else |
| 804 | { | 816 | { |
| 805 | #ifdef SIGCHLD | 817 | if (p->alive) |
| 806 | Lisp_Object symbol; | 818 | record_kill_process (p); |
| 807 | pid_t pid = p->pid; | 819 | |
| 808 | 820 | if (p->infd >= 0) | |
| 809 | /* No problem storing the pid here, as it is still in Vprocess_alist. */ | ||
| 810 | deleted_pid_list = Fcons (make_fixnum_or_float (pid), | ||
| 811 | /* GC treated elements set to nil. */ | ||
| 812 | Fdelq (Qnil, deleted_pid_list)); | ||
| 813 | /* If the process has already signaled, remove it from the list. */ | ||
| 814 | if (p->raw_status_new) | ||
| 815 | update_status (p); | ||
| 816 | symbol = p->status; | ||
| 817 | if (CONSP (p->status)) | ||
| 818 | symbol = XCAR (p->status); | ||
| 819 | if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)) | ||
| 820 | deleted_pid_list | ||
| 821 | = Fdelete (make_fixnum_or_float (pid), deleted_pid_list); | ||
| 822 | else | ||
| 823 | #endif | ||
| 824 | { | 821 | { |
| 825 | Fkill_process (process, Qnil); | 822 | /* Update P's status, since record_kill_process will make the |
| 826 | /* Do this now, since remove_process will make the | 823 | SIGCHLD handler update deleted_pid_list, not *P. */ |
| 827 | SIGCHLD handler do nothing. */ | 824 | Lisp_Object symbol; |
| 828 | pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil))); | 825 | if (p->raw_status_new) |
| 826 | update_status (p); | ||
| 827 | symbol = CONSP (p->status) ? XCAR (p->status) : p->status; | ||
| 828 | if (! (EQ (symbol, Qsignal) || EQ (symbol, Qexit))) | ||
| 829 | pset_status (p, list2 (Qsignal, make_number (SIGKILL))); | ||
| 830 | |||
| 829 | p->tick = ++process_tick; | 831 | p->tick = ++process_tick; |
| 830 | status_notify (p); | 832 | status_notify (p); |
| 831 | redisplay_preserve_echo_area (13); | 833 | redisplay_preserve_echo_area (13); |
| @@ -1578,17 +1580,12 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1578 | #ifndef WINDOWSNT | 1580 | #ifndef WINDOWSNT |
| 1579 | int wait_child_setup[2]; | 1581 | int wait_child_setup[2]; |
| 1580 | #endif | 1582 | #endif |
| 1581 | #ifdef SIGCHLD | ||
| 1582 | sigset_t blocked; | 1583 | sigset_t blocked; |
| 1583 | #endif | ||
| 1584 | /* Use volatile to protect variables from being clobbered by vfork. */ | 1584 | /* Use volatile to protect variables from being clobbered by vfork. */ |
| 1585 | volatile int forkin, forkout; | 1585 | volatile int forkin, forkout; |
| 1586 | volatile int pty_flag = 0; | 1586 | volatile int pty_flag = 0; |
| 1587 | volatile Lisp_Object lisp_pty_name = Qnil; | 1587 | volatile Lisp_Object lisp_pty_name = Qnil; |
| 1588 | volatile Lisp_Object encoded_current_dir; | 1588 | volatile Lisp_Object encoded_current_dir; |
| 1589 | #if HAVE_WORKING_VFORK | ||
| 1590 | char **volatile save_environ; | ||
| 1591 | #endif | ||
| 1592 | 1589 | ||
| 1593 | inchannel = outchannel = -1; | 1590 | inchannel = outchannel = -1; |
| 1594 | 1591 | ||
| @@ -1680,19 +1677,11 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1680 | 1677 | ||
| 1681 | block_input (); | 1678 | block_input (); |
| 1682 | 1679 | ||
| 1683 | #ifdef SIGCHLD | ||
| 1684 | /* Block SIGCHLD until we have a chance to store the new fork's | 1680 | /* Block SIGCHLD until we have a chance to store the new fork's |
| 1685 | pid in its process structure. */ | 1681 | pid in its process structure. */ |
| 1686 | sigemptyset (&blocked); | 1682 | sigemptyset (&blocked); |
| 1687 | sigaddset (&blocked, SIGCHLD); | 1683 | sigaddset (&blocked, SIGCHLD); |
| 1688 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | 1684 | pthread_sigmask (SIG_BLOCK, &blocked, 0); |
| 1689 | #endif | ||
| 1690 | |||
| 1691 | #if HAVE_WORKING_VFORK | ||
| 1692 | /* child_setup must clobber environ on systems with true vfork. | ||
| 1693 | Protect it from permanent change. */ | ||
| 1694 | save_environ = environ; | ||
| 1695 | #endif | ||
| 1696 | 1685 | ||
| 1697 | #ifndef WINDOWSNT | 1686 | #ifndef WINDOWSNT |
| 1698 | pid = vfork (); | 1687 | pid = vfork (); |
| @@ -1800,10 +1789,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1800 | /* Emacs ignores SIGPIPE, but the child should not. */ | 1789 | /* Emacs ignores SIGPIPE, but the child should not. */ |
| 1801 | signal (SIGPIPE, SIG_DFL); | 1790 | signal (SIGPIPE, SIG_DFL); |
| 1802 | 1791 | ||
| 1803 | #ifdef SIGCHLD | ||
| 1804 | /* Stop blocking signals in the child. */ | 1792 | /* Stop blocking signals in the child. */ |
| 1805 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1793 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 1806 | #endif | ||
| 1807 | 1794 | ||
| 1808 | if (pty_flag) | 1795 | if (pty_flag) |
| 1809 | child_setup_tty (xforkout); | 1796 | child_setup_tty (xforkout); |
| @@ -1819,18 +1806,12 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1819 | 1806 | ||
| 1820 | /* Back in the parent process. */ | 1807 | /* Back in the parent process. */ |
| 1821 | 1808 | ||
| 1822 | #if HAVE_WORKING_VFORK | ||
| 1823 | environ = save_environ; | ||
| 1824 | #endif | ||
| 1825 | |||
| 1826 | XPROCESS (process)->pid = pid; | 1809 | XPROCESS (process)->pid = pid; |
| 1827 | if (0 <= pid) | 1810 | if (0 <= pid) |
| 1828 | XPROCESS (process)->alive = 1; | 1811 | XPROCESS (process)->alive = 1; |
| 1829 | 1812 | ||
| 1830 | /* Stop blocking signals in the parent. */ | 1813 | /* Stop blocking signals in the parent. */ |
| 1831 | #ifdef SIGCHLD | ||
| 1832 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); | 1814 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 1833 | #endif | ||
| 1834 | unblock_input (); | 1815 | unblock_input (); |
| 1835 | 1816 | ||
| 1836 | if (pid < 0) | 1817 | if (pid < 0) |
| @@ -1874,7 +1855,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1874 | /* Wait for child_setup to complete in case that vfork is | 1855 | /* Wait for child_setup to complete in case that vfork is |
| 1875 | actually defined as fork. The descriptor wait_child_setup[1] | 1856 | actually defined as fork. The descriptor wait_child_setup[1] |
| 1876 | of a pipe is closed at the child side either by close-on-exec | 1857 | of a pipe is closed at the child side either by close-on-exec |
| 1877 | on successful execvp or the _exit call in child_setup. */ | 1858 | on successful execve or the _exit call in child_setup. */ |
| 1878 | { | 1859 | { |
| 1879 | char dummy; | 1860 | char dummy; |
| 1880 | 1861 | ||
| @@ -4432,14 +4413,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4432 | total_nread += nread; | 4413 | total_nread += nread; |
| 4433 | got_some_input = 1; | 4414 | got_some_input = 1; |
| 4434 | } | 4415 | } |
| 4435 | #ifdef EIO | 4416 | else if (nread == -1 && (errno == EIO || errno == EAGAIN)) |
| 4436 | else if (nread == -1 && EIO == errno) | ||
| 4437 | break; | ||
| 4438 | #endif | ||
| 4439 | #ifdef EAGAIN | ||
| 4440 | else if (nread == -1 && EAGAIN == errno) | ||
| 4441 | break; | 4417 | break; |
| 4442 | #endif | ||
| 4443 | #ifdef EWOULDBLOCK | 4418 | #ifdef EWOULDBLOCK |
| 4444 | else if (nread == -1 && EWOULDBLOCK == errno) | 4419 | else if (nread == -1 && EWOULDBLOCK == errno) |
| 4445 | break; | 4420 | break; |
| @@ -4628,7 +4603,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4628 | yielding EBADF here or at select() call above. | 4603 | yielding EBADF here or at select() call above. |
| 4629 | So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF | 4604 | So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF |
| 4630 | in m/ibmrt-aix.h), and here we just ignore the select error. | 4605 | in m/ibmrt-aix.h), and here we just ignore the select error. |
| 4631 | Cleanup occurs c/o status_notify after SIGCLD. */ | 4606 | Cleanup occurs c/o status_notify after SIGCHLD. */ |
| 4632 | no_avail = 1; /* Cannot depend on values returned */ | 4607 | no_avail = 1; /* Cannot depend on values returned */ |
| 4633 | #else | 4608 | #else |
| 4634 | emacs_abort (); | 4609 | emacs_abort (); |
| @@ -4826,10 +4801,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4826 | #endif /* HAVE_PTYS */ | 4801 | #endif /* HAVE_PTYS */ |
| 4827 | /* If we can detect process termination, don't consider the | 4802 | /* If we can detect process termination, don't consider the |
| 4828 | process gone just because its pipe is closed. */ | 4803 | process gone just because its pipe is closed. */ |
| 4829 | #ifdef SIGCHLD | ||
| 4830 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) | 4804 | else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) |
| 4831 | ; | 4805 | ; |
| 4832 | #endif | ||
| 4833 | else | 4806 | else |
| 4834 | { | 4807 | { |
| 4835 | /* Preserve status of processes already terminated. */ | 4808 | /* Preserve status of processes already terminated. */ |
| @@ -5517,13 +5490,10 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 5517 | 5490 | ||
| 5518 | if (rv < 0) | 5491 | if (rv < 0) |
| 5519 | { | 5492 | { |
| 5520 | if (0 | 5493 | if (errno == EAGAIN |
| 5521 | #ifdef EWOULDBLOCK | 5494 | #ifdef EWOULDBLOCK |
| 5522 | || errno == EWOULDBLOCK | 5495 | || errno == EWOULDBLOCK |
| 5523 | #endif | 5496 | #endif |
| 5524 | #ifdef EAGAIN | ||
| 5525 | || errno == EAGAIN | ||
| 5526 | #endif | ||
| 5527 | ) | 5497 | ) |
| 5528 | /* Buffer is full. Wait, accepting input; | 5498 | /* Buffer is full. Wait, accepting input; |
| 5529 | that may allow the program | 5499 | that may allow the program |
| @@ -5695,7 +5665,7 @@ return t unconditionally. */) | |||
| 5695 | 5665 | ||
| 5696 | If we can, we try to signal PROCESS by sending control characters | 5666 | If we can, we try to signal PROCESS by sending control characters |
| 5697 | down the pty. This allows us to signal inferiors who have changed | 5667 | down the pty. This allows us to signal inferiors who have changed |
| 5698 | their uid, for which killpg would return an EPERM error. */ | 5668 | their uid, for which kill would return an EPERM error. */ |
| 5699 | 5669 | ||
| 5700 | static void | 5670 | static void |
| 5701 | process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | 5671 | process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, |
| @@ -5833,7 +5803,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5833 | if (!NILP (current_group)) | 5803 | if (!NILP (current_group)) |
| 5834 | { | 5804 | { |
| 5835 | if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) | 5805 | if (ioctl (p->infd, TIOCSIGSEND, signo) == -1) |
| 5836 | EMACS_KILLPG (gid, signo); | 5806 | kill (-gid, signo); |
| 5837 | } | 5807 | } |
| 5838 | else | 5808 | else |
| 5839 | { | 5809 | { |
| @@ -5841,7 +5811,7 @@ process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, | |||
| 5841 | kill (gid, signo); | 5811 | kill (gid, signo); |
| 5842 | } | 5812 | } |
| 5843 | #else /* ! defined (TIOCSIGSEND) */ | 5813 | #else /* ! defined (TIOCSIGSEND) */ |
| 5844 | EMACS_KILLPG (gid, signo); | 5814 | kill (-gid, signo); |
| 5845 | #endif /* ! defined (TIOCSIGSEND) */ | 5815 | #endif /* ! defined (TIOCSIGSEND) */ |
| 5846 | } | 5816 | } |
| 5847 | 5817 | ||
| @@ -5946,6 +5916,27 @@ traffic. */) | |||
| 5946 | return process; | 5916 | return process; |
| 5947 | } | 5917 | } |
| 5948 | 5918 | ||
| 5919 | /* Return the integer value of the signal whose abbreviation is ABBR, | ||
| 5920 | or a negative number if there is no such signal. */ | ||
| 5921 | static int | ||
| 5922 | abbr_to_signal (char const *name) | ||
| 5923 | { | ||
| 5924 | int i, signo; | ||
| 5925 | char sigbuf[20]; /* Large enough for all valid signal abbreviations. */ | ||
| 5926 | |||
| 5927 | if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3)) | ||
| 5928 | name += 3; | ||
| 5929 | |||
| 5930 | for (i = 0; i < sizeof sigbuf; i++) | ||
| 5931 | { | ||
| 5932 | sigbuf[i] = c_toupper (name[i]); | ||
| 5933 | if (! sigbuf[i]) | ||
| 5934 | return str2sig (sigbuf, &signo) == 0 ? signo : -1; | ||
| 5935 | } | ||
| 5936 | |||
| 5937 | return -1; | ||
| 5938 | } | ||
| 5939 | |||
| 5949 | DEFUN ("signal-process", Fsignal_process, Ssignal_process, | 5940 | DEFUN ("signal-process", Fsignal_process, Ssignal_process, |
| 5950 | 2, 2, "sProcess (name or number): \nnSignal code: ", | 5941 | 2, 2, "sProcess (name or number): \nnSignal code: ", |
| 5951 | doc: /* Send PROCESS the signal with code SIGCODE. | 5942 | doc: /* Send PROCESS the signal with code SIGCODE. |
| @@ -5956,6 +5947,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 5956 | (Lisp_Object process, Lisp_Object sigcode) | 5947 | (Lisp_Object process, Lisp_Object sigcode) |
| 5957 | { | 5948 | { |
| 5958 | pid_t pid; | 5949 | pid_t pid; |
| 5950 | int signo; | ||
| 5959 | 5951 | ||
| 5960 | if (STRINGP (process)) | 5952 | if (STRINGP (process)) |
| 5961 | { | 5953 | { |
| @@ -5985,12 +5977,11 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 5985 | error ("Cannot signal process %s", SDATA (XPROCESS (process)->name)); | 5977 | error ("Cannot signal process %s", SDATA (XPROCESS (process)->name)); |
| 5986 | } | 5978 | } |
| 5987 | 5979 | ||
| 5988 | #define parse_signal(NAME, VALUE) \ | ||
| 5989 | else if (!xstrcasecmp (name, NAME)) \ | ||
| 5990 | XSETINT (sigcode, VALUE) | ||
| 5991 | |||
| 5992 | if (INTEGERP (sigcode)) | 5980 | if (INTEGERP (sigcode)) |
| 5993 | CHECK_TYPE_RANGED_INTEGER (int, sigcode); | 5981 | { |
| 5982 | CHECK_TYPE_RANGED_INTEGER (int, sigcode); | ||
| 5983 | signo = XINT (sigcode); | ||
| 5984 | } | ||
| 5994 | else | 5985 | else |
| 5995 | { | 5986 | { |
| 5996 | char *name; | 5987 | char *name; |
| @@ -5998,96 +5989,12 @@ SIGCODE may be an integer, or a symbol whose name is a signal name. */) | |||
| 5998 | CHECK_SYMBOL (sigcode); | 5989 | CHECK_SYMBOL (sigcode); |
| 5999 | name = SSDATA (SYMBOL_NAME (sigcode)); | 5990 | name = SSDATA (SYMBOL_NAME (sigcode)); |
| 6000 | 5991 | ||
| 6001 | if (!strncmp (name, "SIG", 3) || !strncmp (name, "sig", 3)) | 5992 | signo = abbr_to_signal (name); |
| 6002 | name += 3; | 5993 | if (signo < 0) |
| 6003 | |||
| 6004 | if (0) | ||
| 6005 | ; | ||
| 6006 | #ifdef SIGUSR1 | ||
| 6007 | parse_signal ("usr1", SIGUSR1); | ||
| 6008 | #endif | ||
| 6009 | #ifdef SIGUSR2 | ||
| 6010 | parse_signal ("usr2", SIGUSR2); | ||
| 6011 | #endif | ||
| 6012 | parse_signal ("term", SIGTERM); | ||
| 6013 | #ifdef SIGHUP | ||
| 6014 | parse_signal ("hup", SIGHUP); | ||
| 6015 | #endif | ||
| 6016 | parse_signal ("int", SIGINT); | ||
| 6017 | #ifdef SIGQUIT | ||
| 6018 | parse_signal ("quit", SIGQUIT); | ||
| 6019 | #endif | ||
| 6020 | parse_signal ("ill", SIGILL); | ||
| 6021 | parse_signal ("abrt", SIGABRT); | ||
| 6022 | #ifdef SIGEMT | ||
| 6023 | parse_signal ("emt", SIGEMT); | ||
| 6024 | #endif | ||
| 6025 | #ifdef SIGKILL | ||
| 6026 | parse_signal ("kill", SIGKILL); | ||
| 6027 | #endif | ||
| 6028 | parse_signal ("fpe", SIGFPE); | ||
| 6029 | #ifdef SIGBUS | ||
| 6030 | parse_signal ("bus", SIGBUS); | ||
| 6031 | #endif | ||
| 6032 | parse_signal ("segv", SIGSEGV); | ||
| 6033 | #ifdef SIGSYS | ||
| 6034 | parse_signal ("sys", SIGSYS); | ||
| 6035 | #endif | ||
| 6036 | #ifdef SIGPIPE | ||
| 6037 | parse_signal ("pipe", SIGPIPE); | ||
| 6038 | #endif | ||
| 6039 | #ifdef SIGALRM | ||
| 6040 | parse_signal ("alrm", SIGALRM); | ||
| 6041 | #endif | ||
| 6042 | #ifdef SIGURG | ||
| 6043 | parse_signal ("urg", SIGURG); | ||
| 6044 | #endif | ||
| 6045 | #ifdef SIGSTOP | ||
| 6046 | parse_signal ("stop", SIGSTOP); | ||
| 6047 | #endif | ||
| 6048 | #ifdef SIGTSTP | ||
| 6049 | parse_signal ("tstp", SIGTSTP); | ||
| 6050 | #endif | ||
| 6051 | #ifdef SIGCONT | ||
| 6052 | parse_signal ("cont", SIGCONT); | ||
| 6053 | #endif | ||
| 6054 | #ifdef SIGCHLD | ||
| 6055 | parse_signal ("chld", SIGCHLD); | ||
| 6056 | #endif | ||
| 6057 | #ifdef SIGTTIN | ||
| 6058 | parse_signal ("ttin", SIGTTIN); | ||
| 6059 | #endif | ||
| 6060 | #ifdef SIGTTOU | ||
| 6061 | parse_signal ("ttou", SIGTTOU); | ||
| 6062 | #endif | ||
| 6063 | #ifdef SIGIO | ||
| 6064 | parse_signal ("io", SIGIO); | ||
| 6065 | #endif | ||
| 6066 | #ifdef SIGXCPU | ||
| 6067 | parse_signal ("xcpu", SIGXCPU); | ||
| 6068 | #endif | ||
| 6069 | #ifdef SIGXFSZ | ||
| 6070 | parse_signal ("xfsz", SIGXFSZ); | ||
| 6071 | #endif | ||
| 6072 | #ifdef SIGVTALRM | ||
| 6073 | parse_signal ("vtalrm", SIGVTALRM); | ||
| 6074 | #endif | ||
| 6075 | #ifdef SIGPROF | ||
| 6076 | parse_signal ("prof", SIGPROF); | ||
| 6077 | #endif | ||
| 6078 | #ifdef SIGWINCH | ||
| 6079 | parse_signal ("winch", SIGWINCH); | ||
| 6080 | #endif | ||
| 6081 | #ifdef SIGINFO | ||
| 6082 | parse_signal ("info", SIGINFO); | ||
| 6083 | #endif | ||
| 6084 | else | ||
| 6085 | error ("Undefined signal name %s", name); | 5994 | error ("Undefined signal name %s", name); |
| 6086 | } | 5995 | } |
| 6087 | 5996 | ||
| 6088 | #undef parse_signal | 5997 | return make_number (kill (pid, signo)); |
| 6089 | |||
| 6090 | return make_number (kill (pid, XINT (sigcode))); | ||
| 6091 | } | 5998 | } |
| 6092 | 5999 | ||
| 6093 | DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, | 6000 | DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, |
| @@ -6169,35 +6076,35 @@ process has been transmitted to the serial port. */) | |||
| 6169 | return process; | 6076 | return process; |
| 6170 | } | 6077 | } |
| 6171 | 6078 | ||
| 6172 | /* If the status of the process DESIRED has changed, return true and | 6079 | /* The main Emacs thread records child processes in three places: |
| 6173 | set *STATUS to its exit status; otherwise, return false. | 6080 | |
| 6174 | If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...) | 6081 | - Vprocess_alist, for asynchronous subprocesses, which are child |
| 6175 | has already been invoked, and do not invoke waitpid again. */ | 6082 | processes visible to Lisp. |
| 6176 | 6083 | ||
| 6177 | static bool | 6084 | - deleted_pid_list, for child processes invisible to Lisp, |
| 6178 | process_status_retrieved (pid_t desired, pid_t have, int *status) | 6085 | typically because of delete-process. These are recorded so that |
| 6179 | { | 6086 | the processes can be reaped when they exit, so that the operating |
| 6180 | if (have < 0) | 6087 | system's process table is not cluttered by zombies. |
| 6181 | { | 6088 | |
| 6182 | /* Invoke waitpid only with a known process ID; do not invoke | 6089 | - the local variable PID in Fcall_process, call_process_cleanup and |
| 6183 | waitpid with a nonpositive argument. Otherwise, Emacs might | 6090 | call_process_kill, for synchronous subprocesses. |
| 6184 | reap an unwanted process by mistake. For example, invoking | 6091 | record_unwind_protect is used to make sure this process is not |
| 6185 | waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, | 6092 | forgotten: if the user interrupts call-process and the child |
| 6186 | so that another thread running glib won't find them. */ | 6093 | process refuses to exit immediately even with two C-g's, |
| 6187 | do | 6094 | call_process_kill adds PID's contents to deleted_pid_list before |
| 6188 | have = waitpid (desired, status, WNOHANG | WUNTRACED); | 6095 | returning. |
| 6189 | while (have < 0 && errno == EINTR); | 6096 | |
| 6190 | } | 6097 | The main Emacs thread invokes waitpid only on child processes that |
| 6191 | 6098 | it creates and that have not been reaped. This avoid races on | |
| 6192 | return have == desired; | 6099 | platforms such as GTK, where other threads create their own |
| 6193 | } | 6100 | subprocesses which the main thread should not reap. For example, |
| 6194 | 6101 | if the main thread attempted to reap an already-reaped child, it | |
| 6195 | /* If PID is nonnegative, the child process PID with wait status W has | 6102 | might inadvertently reap a GTK-created process that happened to |
| 6196 | changed its status; record this and return true. | 6103 | have the same process ID. */ |
| 6197 | 6104 | ||
| 6198 | If PID is negative, ignore W, and look for known child processes | 6105 | /* Handle a SIGCHLD signal by looking for known child processes of |
| 6199 | of Emacs whose status have changed. For each one found, record its new | 6106 | Emacs whose status have changed. For each one found, record its |
| 6200 | status. | 6107 | new status. |
| 6201 | 6108 | ||
| 6202 | All we do is change the status; we do not run sentinels or print | 6109 | All we do is change the status; we do not run sentinels or print |
| 6203 | notifications. That is saved for the next time keyboard input is | 6110 | notifications. That is saved for the next time keyboard input is |
| @@ -6220,20 +6127,15 @@ process_status_retrieved (pid_t desired, pid_t have, int *status) | |||
| 6220 | ** Malloc WARNING: This should never call malloc either directly or | 6127 | ** Malloc WARNING: This should never call malloc either directly or |
| 6221 | indirectly; if it does, that is a bug */ | 6128 | indirectly; if it does, that is a bug */ |
| 6222 | 6129 | ||
| 6223 | void | 6130 | static void |
| 6224 | record_child_status_change (pid_t pid, int w) | 6131 | handle_child_signal (int sig) |
| 6225 | { | 6132 | { |
| 6226 | #ifdef SIGCHLD | ||
| 6227 | |||
| 6228 | /* Record at most one child only if we already know one child that | ||
| 6229 | has exited. */ | ||
| 6230 | bool record_at_most_one_child = 0 <= pid; | ||
| 6231 | |||
| 6232 | Lisp_Object tail; | 6133 | Lisp_Object tail; |
| 6233 | 6134 | ||
| 6234 | /* Find the process that signaled us, and record its status. */ | 6135 | /* Find the process that signaled us, and record its status. */ |
| 6235 | 6136 | ||
| 6236 | /* The process can have been deleted by Fdelete_process. */ | 6137 | /* The process can have been deleted by Fdelete_process, or have |
| 6138 | been started asynchronously by Fcall_process. */ | ||
| 6237 | for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) | 6139 | for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) |
| 6238 | { | 6140 | { |
| 6239 | bool all_pids_are_fixnums | 6141 | bool all_pids_are_fixnums |
| @@ -6247,12 +6149,8 @@ record_child_status_change (pid_t pid, int w) | |||
| 6247 | deleted_pid = XINT (xpid); | 6149 | deleted_pid = XINT (xpid); |
| 6248 | else | 6150 | else |
| 6249 | deleted_pid = XFLOAT_DATA (xpid); | 6151 | deleted_pid = XFLOAT_DATA (xpid); |
| 6250 | if (process_status_retrieved (deleted_pid, pid, &w)) | 6152 | if (child_status_changed (deleted_pid, 0, 0)) |
| 6251 | { | 6153 | XSETCAR (tail, Qnil); |
| 6252 | XSETCAR (tail, Qnil); | ||
| 6253 | if (record_at_most_one_child) | ||
| 6254 | return; | ||
| 6255 | } | ||
| 6256 | } | 6154 | } |
| 6257 | } | 6155 | } |
| 6258 | 6156 | ||
| @@ -6261,15 +6159,17 @@ record_child_status_change (pid_t pid, int w) | |||
| 6261 | { | 6159 | { |
| 6262 | Lisp_Object proc = XCDR (XCAR (tail)); | 6160 | Lisp_Object proc = XCDR (XCAR (tail)); |
| 6263 | struct Lisp_Process *p = XPROCESS (proc); | 6161 | struct Lisp_Process *p = XPROCESS (proc); |
| 6264 | if (p->alive && process_status_retrieved (p->pid, pid, &w)) | 6162 | int status; |
| 6163 | |||
| 6164 | if (p->alive && child_status_changed (p->pid, &status, WUNTRACED)) | ||
| 6265 | { | 6165 | { |
| 6266 | /* Change the status of the process that was found. */ | 6166 | /* Change the status of the process that was found. */ |
| 6267 | p->tick = ++process_tick; | 6167 | p->tick = ++process_tick; |
| 6268 | p->raw_status = w; | 6168 | p->raw_status = status; |
| 6269 | p->raw_status_new = 1; | 6169 | p->raw_status_new = 1; |
| 6270 | 6170 | ||
| 6271 | /* If process has terminated, stop waiting for its output. */ | 6171 | /* If process has terminated, stop waiting for its output. */ |
| 6272 | if (WIFSIGNALED (w) || WIFEXITED (w)) | 6172 | if (WIFSIGNALED (status) || WIFEXITED (status)) |
| 6273 | { | 6173 | { |
| 6274 | int clear_desc_flag = 0; | 6174 | int clear_desc_flag = 0; |
| 6275 | p->alive = 0; | 6175 | p->alive = 0; |
| @@ -6283,44 +6183,8 @@ record_child_status_change (pid_t pid, int w) | |||
| 6283 | FD_CLR (p->infd, &non_keyboard_wait_mask); | 6183 | FD_CLR (p->infd, &non_keyboard_wait_mask); |
| 6284 | } | 6184 | } |
| 6285 | } | 6185 | } |
| 6286 | |||
| 6287 | /* Tell wait_reading_process_output that it needs to wake up and | ||
| 6288 | look around. */ | ||
| 6289 | if (input_available_clear_time) | ||
| 6290 | *input_available_clear_time = make_emacs_time (0, 0); | ||
| 6291 | |||
| 6292 | if (record_at_most_one_child) | ||
| 6293 | return; | ||
| 6294 | } | 6186 | } |
| 6295 | } | 6187 | } |
| 6296 | |||
| 6297 | if (0 <= pid) | ||
| 6298 | { | ||
| 6299 | /* The caller successfully waited for a pid but no asynchronous | ||
| 6300 | process was found for it, so this is a synchronous process. */ | ||
| 6301 | |||
| 6302 | synch_process_alive = 0; | ||
| 6303 | |||
| 6304 | /* Report the status of the synchronous process. */ | ||
| 6305 | if (WIFEXITED (w)) | ||
| 6306 | synch_process_retcode = WEXITSTATUS (w); | ||
| 6307 | else if (WIFSIGNALED (w)) | ||
| 6308 | synch_process_termsig = WTERMSIG (w); | ||
| 6309 | |||
| 6310 | /* Tell wait_reading_process_output that it needs to wake up and | ||
| 6311 | look around. */ | ||
| 6312 | if (input_available_clear_time) | ||
| 6313 | *input_available_clear_time = make_emacs_time (0, 0); | ||
| 6314 | } | ||
| 6315 | #endif | ||
| 6316 | } | ||
| 6317 | |||
| 6318 | #ifdef SIGCHLD | ||
| 6319 | |||
| 6320 | static void | ||
| 6321 | handle_child_signal (int sig) | ||
| 6322 | { | ||
| 6323 | record_child_status_change (-1, 0); | ||
| 6324 | } | 6188 | } |
| 6325 | 6189 | ||
| 6326 | static void | 6190 | static void |
| @@ -6328,8 +6192,6 @@ deliver_child_signal (int sig) | |||
| 6328 | { | 6192 | { |
| 6329 | deliver_process_signal (sig, handle_child_signal); | 6193 | deliver_process_signal (sig, handle_child_signal); |
| 6330 | } | 6194 | } |
| 6331 | |||
| 6332 | #endif /* SIGCHLD */ | ||
| 6333 | 6195 | ||
| 6334 | 6196 | ||
| 6335 | static Lisp_Object | 6197 | static Lisp_Object |
| @@ -7178,7 +7040,6 @@ init_process_emacs (void) | |||
| 7178 | 7040 | ||
| 7179 | inhibit_sentinels = 0; | 7041 | inhibit_sentinels = 0; |
| 7180 | 7042 | ||
| 7181 | #ifdef SIGCHLD | ||
| 7182 | #ifndef CANNOT_DUMP | 7043 | #ifndef CANNOT_DUMP |
| 7183 | if (! noninteractive || initialized) | 7044 | if (! noninteractive || initialized) |
| 7184 | #endif | 7045 | #endif |
| @@ -7187,7 +7048,6 @@ init_process_emacs (void) | |||
| 7187 | emacs_sigaction_init (&action, deliver_child_signal); | 7048 | emacs_sigaction_init (&action, deliver_child_signal); |
| 7188 | sigaction (SIGCHLD, &action, 0); | 7049 | sigaction (SIGCHLD, &action, 0); |
| 7189 | } | 7050 | } |
| 7190 | #endif | ||
| 7191 | 7051 | ||
| 7192 | FD_ZERO (&input_wait_mask); | 7052 | FD_ZERO (&input_wait_mask); |
| 7193 | FD_ZERO (&non_keyboard_wait_mask); | 7053 | FD_ZERO (&non_keyboard_wait_mask); |
| @@ -7214,9 +7074,7 @@ init_process_emacs (void) | |||
| 7214 | #endif | 7074 | #endif |
| 7215 | 7075 | ||
| 7216 | Vprocess_alist = Qnil; | 7076 | Vprocess_alist = Qnil; |
| 7217 | #ifdef SIGCHLD | ||
| 7218 | deleted_pid_list = Qnil; | 7077 | deleted_pid_list = Qnil; |
| 7219 | #endif | ||
| 7220 | for (i = 0; i < MAXDESC; i++) | 7078 | for (i = 0; i < MAXDESC; i++) |
| 7221 | { | 7079 | { |
| 7222 | chan_process[i] = Qnil; | 7080 | chan_process[i] = Qnil; |
| @@ -7343,9 +7201,7 @@ syms_of_process (void) | |||
| 7343 | DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); | 7201 | DEFSYM (Qlast_nonmenu_event, "last-nonmenu-event"); |
| 7344 | 7202 | ||
| 7345 | staticpro (&Vprocess_alist); | 7203 | staticpro (&Vprocess_alist); |
| 7346 | #ifdef SIGCHLD | ||
| 7347 | staticpro (&deleted_pid_list); | 7204 | staticpro (&deleted_pid_list); |
| 7348 | #endif | ||
| 7349 | 7205 | ||
| 7350 | #endif /* subprocesses */ | 7206 | #endif /* subprocesses */ |
| 7351 | 7207 | ||
diff --git a/src/process.h b/src/process.h index 74d1a124060..a0521689abf 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -185,23 +185,6 @@ pset_gnutls_cred_type (struct Lisp_Process *p, Lisp_Object val) | |||
| 185 | } | 185 | } |
| 186 | #endif | 186 | #endif |
| 187 | 187 | ||
| 188 | /* True if we are about to fork off a synchronous process or if we | ||
| 189 | are waiting for it. */ | ||
| 190 | extern bool synch_process_alive; | ||
| 191 | |||
| 192 | /* Communicate exit status of sync process to from sigchld_handler | ||
| 193 | to Fcall_process. */ | ||
| 194 | |||
| 195 | /* Nonzero => this is a string explaining death of synchronous subprocess. */ | ||
| 196 | extern const char *synch_process_death; | ||
| 197 | |||
| 198 | /* Nonzero => this is the signal number that terminated the subprocess. */ | ||
| 199 | extern int synch_process_termsig; | ||
| 200 | |||
| 201 | /* If synch_process_death is zero, | ||
| 202 | this is exit code of synchronous subprocess. */ | ||
| 203 | extern int synch_process_retcode; | ||
| 204 | |||
| 205 | /* Nonzero means don't run process sentinels. This is used | 188 | /* Nonzero means don't run process sentinels. This is used |
| 206 | when exiting. */ | 189 | when exiting. */ |
| 207 | extern int inhibit_sentinels; | 190 | extern int inhibit_sentinels; |
| @@ -215,6 +198,12 @@ extern Lisp_Object QCspeed; | |||
| 215 | extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; | 198 | extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; |
| 216 | extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; | 199 | extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; |
| 217 | 200 | ||
| 201 | /* Defined in callproc.c. */ | ||
| 202 | |||
| 203 | extern void record_kill_process (struct Lisp_Process *); | ||
| 204 | |||
| 205 | /* Defined in process.c. */ | ||
| 206 | |||
| 218 | extern Lisp_Object list_system_processes (void); | 207 | extern Lisp_Object list_system_processes (void); |
| 219 | extern Lisp_Object system_process_attributes (Lisp_Object); | 208 | extern Lisp_Object system_process_attributes (Lisp_Object); |
| 220 | 209 | ||
diff --git a/src/sysdep.c b/src/sysdep.c index 1a3834f0379..5291c5d59aa 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -266,45 +266,74 @@ init_baud_rate (int fd) | |||
| 266 | 266 | ||
| 267 | #ifndef MSDOS | 267 | #ifndef MSDOS |
| 268 | 268 | ||
| 269 | static void | 269 | /* Wait for the subprocess with process id CHILD to terminate or change status. |
| 270 | wait_for_termination_1 (pid_t pid, int interruptible) | 270 | CHILD must be a child process that has not been reaped. |
| 271 | If STATUS is non-null, store the waitpid-style exit status into *STATUS | ||
| 272 | and tell wait_reading_process_output that it needs to look around. | ||
| 273 | Use waitpid-style OPTIONS when waiting. | ||
| 274 | If INTERRUPTIBLE, this function is interruptible by a signal. | ||
| 275 | |||
| 276 | Return CHILD if successful, 0 if no status is available; | ||
| 277 | the latter is possible only when options & NOHANG. */ | ||
| 278 | static pid_t | ||
| 279 | get_child_status (pid_t child, int *status, int options, bool interruptible) | ||
| 271 | { | 280 | { |
| 272 | while (1) | 281 | pid_t pid; |
| 282 | |||
| 283 | /* Invoke waitpid only with a known process ID; do not invoke | ||
| 284 | waitpid with a nonpositive argument. Otherwise, Emacs might | ||
| 285 | reap an unwanted process by mistake. For example, invoking | ||
| 286 | waitpid (-1, ...) can mess up glib by reaping glib's subprocesses, | ||
| 287 | so that another thread running glib won't find them. */ | ||
| 288 | eassert (0 < child); | ||
| 289 | |||
| 290 | while ((pid = waitpid (child, status, options)) < 0) | ||
| 273 | { | 291 | { |
| 274 | int status; | 292 | /* Check that CHILD is a child process that has not been reaped, |
| 275 | int wait_result = waitpid (pid, &status, 0); | 293 | and that STATUS and OPTIONS are valid. Otherwise abort, |
| 276 | if (wait_result < 0) | 294 | as continuing after this internal error could cause Emacs to |
| 277 | { | 295 | become confused and kill innocent-victim processes. */ |
| 278 | if (errno != EINTR) | 296 | if (errno != EINTR) |
| 279 | break; | 297 | emacs_abort (); |
| 280 | } | ||
| 281 | else | ||
| 282 | { | ||
| 283 | record_child_status_change (wait_result, status); | ||
| 284 | break; | ||
| 285 | } | ||
| 286 | 298 | ||
| 287 | /* Note: the MS-Windows emulation of waitpid calls QUIT | 299 | /* Note: the MS-Windows emulation of waitpid calls QUIT |
| 288 | internally. */ | 300 | internally. */ |
| 289 | if (interruptible) | 301 | if (interruptible) |
| 290 | QUIT; | 302 | QUIT; |
| 291 | } | 303 | } |
| 292 | } | ||
| 293 | 304 | ||
| 294 | /* Wait for subprocess with process id `pid' to terminate and | 305 | /* If successful and status is requested, tell wait_reading_process_output |
| 295 | make sure it will get eliminated (not remain forever as a zombie) */ | 306 | that it needs to wake up and look around. */ |
| 307 | if (pid && status && input_available_clear_time) | ||
| 308 | *input_available_clear_time = make_emacs_time (0, 0); | ||
| 296 | 309 | ||
| 310 | return pid; | ||
| 311 | } | ||
| 312 | |||
| 313 | /* Wait for the subprocess with process id CHILD to terminate. | ||
| 314 | CHILD must be a child process that has not been reaped. | ||
| 315 | If STATUS is non-null, store the waitpid-style exit status into *STATUS | ||
| 316 | and tell wait_reading_process_output that it needs to look around. | ||
| 317 | If INTERRUPTIBLE, this function is interruptible by a signal. */ | ||
| 297 | void | 318 | void |
| 298 | wait_for_termination (pid_t pid) | 319 | wait_for_termination (pid_t child, int *status, bool interruptible) |
| 299 | { | 320 | { |
| 300 | wait_for_termination_1 (pid, 0); | 321 | get_child_status (child, status, 0, interruptible); |
| 301 | } | 322 | } |
| 302 | 323 | ||
| 303 | /* Like the above, but allow keyboard interruption. */ | 324 | /* Report whether the subprocess with process id CHILD has changed status. |
| 304 | void | 325 | Termination counts as a change of status. |
| 305 | interruptible_wait_for_termination (pid_t pid) | 326 | CHILD must be a child process that has not been reaped. |
| 327 | If STATUS is non-null, store the waitpid-style exit status into *STATUS | ||
| 328 | and tell wait_reading_process_output that it needs to look around. | ||
| 329 | Use waitpid-style OPTIONS to check status, but do not wait. | ||
| 330 | |||
| 331 | Return CHILD if successful, 0 if no status is available because | ||
| 332 | the process's state has not changed. */ | ||
| 333 | pid_t | ||
| 334 | child_status_changed (pid_t child, int *status, int options) | ||
| 306 | { | 335 | { |
| 307 | wait_for_termination_1 (pid, 1); | 336 | return get_child_status (child, status, WNOHANG | options, 0); |
| 308 | } | 337 | } |
| 309 | 338 | ||
| 310 | /* | 339 | /* |
| @@ -428,20 +457,15 @@ static void restore_signal_handlers (struct save_signal *); | |||
| 428 | void | 457 | void |
| 429 | sys_suspend (void) | 458 | sys_suspend (void) |
| 430 | { | 459 | { |
| 431 | #if defined (SIGTSTP) && !defined (MSDOS) | 460 | #ifndef DOS_NT |
| 432 | 461 | kill (0, SIGTSTP); | |
| 433 | { | 462 | #else |
| 434 | pid_t pgrp = getpgrp (); | ||
| 435 | EMACS_KILLPG (pgrp, SIGTSTP); | ||
| 436 | } | ||
| 437 | |||
| 438 | #else /* No SIGTSTP */ | ||
| 439 | /* On a system where suspending is not implemented, | 463 | /* On a system where suspending is not implemented, |
| 440 | instead fork a subshell and let it talk directly to the terminal | 464 | instead fork a subshell and let it talk directly to the terminal |
| 441 | while we wait. */ | 465 | while we wait. */ |
| 442 | sys_subshell (); | 466 | sys_subshell (); |
| 443 | 467 | ||
| 444 | #endif /* no SIGTSTP */ | 468 | #endif |
| 445 | } | 469 | } |
| 446 | 470 | ||
| 447 | /* Fork a subshell. */ | 471 | /* Fork a subshell. */ |
| @@ -454,6 +478,7 @@ sys_subshell (void) | |||
| 454 | char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ | 478 | char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ |
| 455 | #endif | 479 | #endif |
| 456 | pid_t pid; | 480 | pid_t pid; |
| 481 | int status; | ||
| 457 | struct save_signal saved_handlers[5]; | 482 | struct save_signal saved_handlers[5]; |
| 458 | Lisp_Object dir; | 483 | Lisp_Object dir; |
| 459 | unsigned char *volatile str_volatile = 0; | 484 | unsigned char *volatile str_volatile = 0; |
| @@ -491,7 +516,6 @@ sys_subshell (void) | |||
| 491 | #ifdef DOS_NT | 516 | #ifdef DOS_NT |
| 492 | pid = 0; | 517 | pid = 0; |
| 493 | save_signal_handlers (saved_handlers); | 518 | save_signal_handlers (saved_handlers); |
| 494 | synch_process_alive = 1; | ||
| 495 | #else | 519 | #else |
| 496 | pid = vfork (); | 520 | pid = vfork (); |
| 497 | if (pid == -1) | 521 | if (pid == -1) |
| @@ -560,14 +584,12 @@ sys_subshell (void) | |||
| 560 | /* Do this now if we did not do it before. */ | 584 | /* Do this now if we did not do it before. */ |
| 561 | #ifndef MSDOS | 585 | #ifndef MSDOS |
| 562 | save_signal_handlers (saved_handlers); | 586 | save_signal_handlers (saved_handlers); |
| 563 | synch_process_alive = 1; | ||
| 564 | #endif | 587 | #endif |
| 565 | 588 | ||
| 566 | #ifndef DOS_NT | 589 | #ifndef DOS_NT |
| 567 | wait_for_termination (pid); | 590 | wait_for_termination (pid, &status, 0); |
| 568 | #endif | 591 | #endif |
| 569 | restore_signal_handlers (saved_handlers); | 592 | restore_signal_handlers (saved_handlers); |
| 570 | synch_process_alive = 0; | ||
| 571 | } | 593 | } |
| 572 | 594 | ||
| 573 | static void | 595 | static void |
| @@ -1491,9 +1513,7 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) | |||
| 1491 | /* When handling a signal, block nonfatal system signals that are caught | 1513 | /* When handling a signal, block nonfatal system signals that are caught |
| 1492 | by Emacs. This makes race conditions less likely. */ | 1514 | by Emacs. This makes race conditions less likely. */ |
| 1493 | sigaddset (&action->sa_mask, SIGALRM); | 1515 | sigaddset (&action->sa_mask, SIGALRM); |
| 1494 | #ifdef SIGCHLD | ||
| 1495 | sigaddset (&action->sa_mask, SIGCHLD); | 1516 | sigaddset (&action->sa_mask, SIGCHLD); |
| 1496 | #endif | ||
| 1497 | #ifdef SIGDANGER | 1517 | #ifdef SIGDANGER |
| 1498 | sigaddset (&action->sa_mask, SIGDANGER); | 1518 | sigaddset (&action->sa_mask, SIGDANGER); |
| 1499 | #endif | 1519 | #endif |
| @@ -1673,18 +1693,11 @@ init_signals (bool dumping) | |||
| 1673 | # ifdef SIGAIO | 1693 | # ifdef SIGAIO |
| 1674 | sys_siglist[SIGAIO] = "LAN I/O interrupt"; | 1694 | sys_siglist[SIGAIO] = "LAN I/O interrupt"; |
| 1675 | # endif | 1695 | # endif |
| 1676 | # ifdef SIGALRM | ||
| 1677 | sys_siglist[SIGALRM] = "Alarm clock"; | 1696 | sys_siglist[SIGALRM] = "Alarm clock"; |
| 1678 | # endif | ||
| 1679 | # ifdef SIGBUS | 1697 | # ifdef SIGBUS |
| 1680 | sys_siglist[SIGBUS] = "Bus error"; | 1698 | sys_siglist[SIGBUS] = "Bus error"; |
| 1681 | # endif | 1699 | # endif |
| 1682 | # ifdef SIGCLD | ||
| 1683 | sys_siglist[SIGCLD] = "Child status changed"; | ||
| 1684 | # endif | ||
| 1685 | # ifdef SIGCHLD | ||
| 1686 | sys_siglist[SIGCHLD] = "Child status changed"; | 1700 | sys_siglist[SIGCHLD] = "Child status changed"; |
| 1687 | # endif | ||
| 1688 | # ifdef SIGCONT | 1701 | # ifdef SIGCONT |
| 1689 | sys_siglist[SIGCONT] = "Continued"; | 1702 | sys_siglist[SIGCONT] = "Continued"; |
| 1690 | # endif | 1703 | # endif |
| @@ -1704,9 +1717,7 @@ init_signals (bool dumping) | |||
| 1704 | # ifdef SIGGRANT | 1717 | # ifdef SIGGRANT |
| 1705 | sys_siglist[SIGGRANT] = "Monitor mode granted"; | 1718 | sys_siglist[SIGGRANT] = "Monitor mode granted"; |
| 1706 | # endif | 1719 | # endif |
| 1707 | # ifdef SIGHUP | ||
| 1708 | sys_siglist[SIGHUP] = "Hangup"; | 1720 | sys_siglist[SIGHUP] = "Hangup"; |
| 1709 | # endif | ||
| 1710 | sys_siglist[SIGILL] = "Illegal instruction"; | 1721 | sys_siglist[SIGILL] = "Illegal instruction"; |
| 1711 | sys_siglist[SIGINT] = "Interrupt"; | 1722 | sys_siglist[SIGINT] = "Interrupt"; |
| 1712 | # ifdef SIGIO | 1723 | # ifdef SIGIO |
| @@ -1718,9 +1729,7 @@ init_signals (bool dumping) | |||
| 1718 | # ifdef SIGIOT | 1729 | # ifdef SIGIOT |
| 1719 | sys_siglist[SIGIOT] = "IOT trap"; | 1730 | sys_siglist[SIGIOT] = "IOT trap"; |
| 1720 | # endif | 1731 | # endif |
| 1721 | # ifdef SIGKILL | ||
| 1722 | sys_siglist[SIGKILL] = "Killed"; | 1732 | sys_siglist[SIGKILL] = "Killed"; |
| 1723 | # endif | ||
| 1724 | # ifdef SIGLOST | 1733 | # ifdef SIGLOST |
| 1725 | sys_siglist[SIGLOST] = "Resource lost"; | 1734 | sys_siglist[SIGLOST] = "Resource lost"; |
| 1726 | # endif | 1735 | # endif |
| @@ -1733,9 +1742,7 @@ init_signals (bool dumping) | |||
| 1733 | # ifdef SIGPHONE | 1742 | # ifdef SIGPHONE |
| 1734 | sys_siglist[SIGWIND] = "SIGPHONE"; | 1743 | sys_siglist[SIGWIND] = "SIGPHONE"; |
| 1735 | # endif | 1744 | # endif |
| 1736 | # ifdef SIGPIPE | ||
| 1737 | sys_siglist[SIGPIPE] = "Broken pipe"; | 1745 | sys_siglist[SIGPIPE] = "Broken pipe"; |
| 1738 | # endif | ||
| 1739 | # ifdef SIGPOLL | 1746 | # ifdef SIGPOLL |
| 1740 | sys_siglist[SIGPOLL] = "Pollable event occurred"; | 1747 | sys_siglist[SIGPOLL] = "Pollable event occurred"; |
| 1741 | # endif | 1748 | # endif |
| @@ -1748,9 +1755,7 @@ init_signals (bool dumping) | |||
| 1748 | # ifdef SIGPWR | 1755 | # ifdef SIGPWR |
| 1749 | sys_siglist[SIGPWR] = "Power-fail restart"; | 1756 | sys_siglist[SIGPWR] = "Power-fail restart"; |
| 1750 | # endif | 1757 | # endif |
| 1751 | # ifdef SIGQUIT | ||
| 1752 | sys_siglist[SIGQUIT] = "Quit"; | 1758 | sys_siglist[SIGQUIT] = "Quit"; |
| 1753 | # endif | ||
| 1754 | # ifdef SIGRETRACT | 1759 | # ifdef SIGRETRACT |
| 1755 | sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode"; | 1760 | sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode"; |
| 1756 | # endif | 1761 | # endif |
diff --git a/src/syssignal.h b/src/syssignal.h index 2bf2f046aa5..8f9b5f0546a 100644 --- a/src/syssignal.h +++ b/src/syssignal.h | |||
| @@ -54,26 +54,6 @@ char const *safe_strsignal (int) ATTRIBUTE_CONST; | |||
| 54 | # define emacs_raise(sig) raise (sig) | 54 | # define emacs_raise(sig) raise (sig) |
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| 57 | /* On bsd, [man says] kill does not accept a negative number to kill a pgrp. | ||
| 58 | Must do that using the killpg call. */ | ||
| 59 | #ifdef BSD_SYSTEM | ||
| 60 | #define EMACS_KILLPG(gid, signo) (killpg ( (gid), (signo))) | ||
| 61 | #else | ||
| 62 | #ifdef WINDOWSNT | ||
| 63 | #define EMACS_KILLPG(gid, signo) (kill (gid, signo)) | ||
| 64 | #else | ||
| 65 | #define EMACS_KILLPG(gid, signo) (kill (-(gid), (signo))) | ||
| 66 | #endif | ||
| 67 | #endif | ||
| 68 | |||
| 69 | /* Define SIGCHLD as an alias for SIGCLD. There are many conditionals | ||
| 70 | testing SIGCHLD. */ | ||
| 71 | #ifdef SIGCLD | ||
| 72 | #ifndef SIGCHLD | ||
| 73 | #define SIGCHLD SIGCLD | ||
| 74 | #endif /* SIGCHLD */ | ||
| 75 | #endif /* ! defined (SIGCLD) */ | ||
| 76 | |||
| 77 | #ifndef HAVE_STRSIGNAL | 57 | #ifndef HAVE_STRSIGNAL |
| 78 | # define strsignal(sig) safe_strsignal (sig) | 58 | # define strsignal(sig) safe_strsignal (sig) |
| 79 | #endif | 59 | #endif |
diff --git a/src/syswait.h b/src/syswait.h index aa4c4bcf527..360407d558e 100644 --- a/src/syswait.h +++ b/src/syswait.h | |||
| @@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 23 | #ifndef EMACS_SYSWAIT_H | 23 | #ifndef EMACS_SYSWAIT_H |
| 24 | #define EMACS_SYSWAIT_H | 24 | #define EMACS_SYSWAIT_H |
| 25 | 25 | ||
| 26 | #include <stdbool.h> | ||
| 26 | #include <sys/types.h> | 27 | #include <sys/types.h> |
| 27 | 28 | ||
| 28 | #ifdef HAVE_SYS_WAIT_H /* We have sys/wait.h with POSIXoid definitions. */ | 29 | #ifdef HAVE_SYS_WAIT_H /* We have sys/wait.h with POSIXoid definitions. */ |
| @@ -52,10 +53,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 52 | #endif | 53 | #endif |
| 53 | 54 | ||
| 54 | /* Defined in process.c. */ | 55 | /* Defined in process.c. */ |
| 55 | extern void record_child_status_change (pid_t, int); | 56 | extern void record_deleted_pid (pid_t); |
| 56 | 57 | ||
| 57 | /* Defined in sysdep.c. */ | 58 | /* Defined in sysdep.c. */ |
| 58 | extern void wait_for_termination (pid_t); | 59 | extern void wait_for_termination (pid_t, int *, bool); |
| 59 | extern void interruptible_wait_for_termination (pid_t); | 60 | extern pid_t child_status_changed (pid_t, int *, int); |
| 60 | 61 | ||
| 61 | #endif /* EMACS_SYSWAIT_H */ | 62 | #endif /* EMACS_SYSWAIT_H */ |
diff --git a/src/term.c b/src/term.c index 481a3423989..241875de52f 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -3362,10 +3362,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ | |||
| 3362 | = tty->TS_delete_mode && tty->TS_insert_mode | 3362 | = tty->TS_delete_mode && tty->TS_insert_mode |
| 3363 | && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode); | 3363 | && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode); |
| 3364 | 3364 | ||
| 3365 | tty->se_is_so = (tty->TS_standout_mode | ||
| 3366 | && tty->TS_end_standout_mode | ||
| 3367 | && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); | ||
| 3368 | |||
| 3369 | UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8; | 3365 | UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8; |
| 3370 | 3366 | ||
| 3371 | terminal->scroll_region_ok | 3367 | terminal->scroll_region_ok |
diff --git a/src/termchar.h b/src/termchar.h index 5c57593c04f..8bffd3e546b 100644 --- a/src/termchar.h +++ b/src/termchar.h | |||
| @@ -50,8 +50,7 @@ struct tty_display_info | |||
| 50 | 50 | ||
| 51 | struct emacs_tty *old_tty; /* The initial tty mode bits */ | 51 | struct emacs_tty *old_tty; /* The initial tty mode bits */ |
| 52 | 52 | ||
| 53 | int term_initted; /* 1 if we have been through init_sys_modes. */ | 53 | unsigned term_initted : 1; /* 1 if we have been through init_sys_modes. */ |
| 54 | |||
| 55 | 54 | ||
| 56 | int reference_count; /* Number of frames that are on this display. */ | 55 | int reference_count; /* Number of frames that are on this display. */ |
| 57 | 56 | ||
| @@ -164,17 +163,12 @@ struct tty_display_info | |||
| 164 | 163 | ||
| 165 | int RPov; /* # chars to start a TS_repeat */ | 164 | int RPov; /* # chars to start a TS_repeat */ |
| 166 | 165 | ||
| 167 | int delete_in_insert_mode; /* delete mode == insert mode */ | 166 | unsigned delete_in_insert_mode : 1; /* delete mode == insert mode */ |
| 168 | |||
| 169 | int se_is_so; /* 1 if same string both enters and leaves | ||
| 170 | standout mode */ | ||
| 171 | |||
| 172 | int costs_set; /* Nonzero if costs have been calculated. */ | ||
| 173 | |||
| 174 | int insert_mode; /* Nonzero when in insert mode. */ | ||
| 175 | int standout_mode; /* Nonzero when in standout mode. */ | ||
| 176 | 167 | ||
| 168 | unsigned costs_set : 1; /* Nonzero if costs have been calculated. */ | ||
| 177 | 169 | ||
| 170 | unsigned insert_mode : 1; /* Nonzero when in insert mode. */ | ||
| 171 | unsigned standout_mode : 1; /* Nonzero when in standout mode. */ | ||
| 178 | 172 | ||
| 179 | /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should | 173 | /* 1 if should obey 0200 bit in input chars as "Meta", 2 if should |
| 180 | keep 0200 bit in input chars. 0 to ignore the 0200 bit. */ | 174 | keep 0200 bit in input chars. 0 to ignore the 0200 bit. */ |
| @@ -192,11 +186,11 @@ struct tty_display_info | |||
| 192 | 186 | ||
| 193 | /* Flag used in tty_show/hide_cursor. */ | 187 | /* Flag used in tty_show/hide_cursor. */ |
| 194 | 188 | ||
| 195 | int cursor_hidden; | 189 | unsigned cursor_hidden : 1; |
| 196 | 190 | ||
| 197 | /* Nonzero means use ^S/^Q for flow control. */ | 191 | /* Nonzero means use ^S/^Q for flow control. */ |
| 198 | int flow_control; | ||
| 199 | 192 | ||
| 193 | unsigned flow_control : 1; | ||
| 200 | }; | 194 | }; |
| 201 | 195 | ||
| 202 | /* A chain of structures for all tty devices currently in use. */ | 196 | /* A chain of structures for all tty devices currently in use. */ |
diff --git a/src/textprop.c b/src/textprop.c index 379eafb73f7..1ce44ad60ac 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -85,8 +85,18 @@ text_read_only (Lisp_Object propval) | |||
| 85 | xsignal0 (Qtext_read_only); | 85 | xsignal0 (Qtext_read_only); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /* Prepare to modify the region of BUFFER from START to END. */ | ||
| 89 | |||
| 90 | static void | ||
| 91 | modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) | ||
| 92 | { | ||
| 93 | struct buffer *buf = XBUFFER (buffer), *old = current_buffer; | ||
| 94 | |||
| 95 | set_buffer_internal (buf); | ||
| 96 | modify_region_1 (XINT (start), XINT (end), true); | ||
| 97 | set_buffer_internal (old); | ||
| 98 | } | ||
| 88 | 99 | ||
| 89 | |||
| 90 | /* Extract the interval at the position pointed to by BEGIN from | 100 | /* Extract the interval at the position pointed to by BEGIN from |
| 91 | OBJECT, a string or buffer. Additionally, check that the positions | 101 | OBJECT, a string or buffer. Additionally, check that the positions |
| 92 | pointed to by BEGIN and END are within the bounds of OBJECT, and | 102 | pointed to by BEGIN and END are within the bounds of OBJECT, and |
| @@ -1164,7 +1174,7 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1164 | } | 1174 | } |
| 1165 | 1175 | ||
| 1166 | if (BUFFERP (object)) | 1176 | if (BUFFERP (object)) |
| 1167 | modify_region (XBUFFER (object), XINT (start), XINT (end), 1); | 1177 | modify_region (object, start, end); |
| 1168 | 1178 | ||
| 1169 | /* We are at the beginning of interval I, with LEN chars to scan. */ | 1179 | /* We are at the beginning of interval I, with LEN chars to scan. */ |
| 1170 | for (;;) | 1180 | for (;;) |
| @@ -1302,7 +1312,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | |||
| 1302 | } | 1312 | } |
| 1303 | 1313 | ||
| 1304 | if (BUFFERP (object) && !NILP (coherent_change_p)) | 1314 | if (BUFFERP (object) && !NILP (coherent_change_p)) |
| 1305 | modify_region (XBUFFER (object), XINT (start), XINT (end), 1); | 1315 | modify_region (object, start, end); |
| 1306 | 1316 | ||
| 1307 | set_text_properties_1 (start, end, properties, object, i); | 1317 | set_text_properties_1 (start, end, properties, object, i); |
| 1308 | 1318 | ||
| @@ -1451,7 +1461,7 @@ Use `set-text-properties' if you want to remove all text properties. */) | |||
| 1451 | } | 1461 | } |
| 1452 | 1462 | ||
| 1453 | if (BUFFERP (object)) | 1463 | if (BUFFERP (object)) |
| 1454 | modify_region (XBUFFER (object), XINT (start), XINT (end), 1); | 1464 | modify_region (object, start, end); |
| 1455 | 1465 | ||
| 1456 | /* We are at the beginning of an interval, with len to scan */ | 1466 | /* We are at the beginning of an interval, with len to scan */ |
| 1457 | for (;;) | 1467 | for (;;) |
| @@ -1565,7 +1575,7 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1565 | else if (LENGTH (i) == len) | 1575 | else if (LENGTH (i) == len) |
| 1566 | { | 1576 | { |
| 1567 | if (!modified && BUFFERP (object)) | 1577 | if (!modified && BUFFERP (object)) |
| 1568 | modify_region (XBUFFER (object), XINT (start), XINT (end), 1); | 1578 | modify_region (object, start, end); |
| 1569 | remove_properties (Qnil, properties, i, object); | 1579 | remove_properties (Qnil, properties, i, object); |
| 1570 | if (BUFFERP (object)) | 1580 | if (BUFFERP (object)) |
| 1571 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1581 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| @@ -1578,7 +1588,7 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1578 | i = split_interval_left (i, len); | 1588 | i = split_interval_left (i, len); |
| 1579 | copy_properties (unchanged, i); | 1589 | copy_properties (unchanged, i); |
| 1580 | if (!modified && BUFFERP (object)) | 1590 | if (!modified && BUFFERP (object)) |
| 1581 | modify_region (XBUFFER (object), XINT (start), XINT (end), 1); | 1591 | modify_region (object, start, end); |
| 1582 | remove_properties (Qnil, properties, i, object); | 1592 | remove_properties (Qnil, properties, i, object); |
| 1583 | if (BUFFERP (object)) | 1593 | if (BUFFERP (object)) |
| 1584 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1594 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| @@ -1589,7 +1599,7 @@ Return t if any property was actually removed, nil otherwise. */) | |||
| 1589 | if (interval_has_some_properties_list (properties, i)) | 1599 | if (interval_has_some_properties_list (properties, i)) |
| 1590 | { | 1600 | { |
| 1591 | if (!modified && BUFFERP (object)) | 1601 | if (!modified && BUFFERP (object)) |
| 1592 | modify_region (XBUFFER (object), XINT (start), XINT (end), 1); | 1602 | modify_region (object, start, end); |
| 1593 | remove_properties (Qnil, properties, i, object); | 1603 | remove_properties (Qnil, properties, i, object); |
| 1594 | modified = 1; | 1604 | modified = 1; |
| 1595 | } | 1605 | } |
diff --git a/src/unexcoff.c b/src/unexcoff.c index 966dd58cb6e..6e29951a962 100644 --- a/src/unexcoff.c +++ b/src/unexcoff.c | |||
| @@ -332,11 +332,7 @@ write_segment (int new, const char *ptr, const char *end) | |||
| 332 | a gap between the old text segment and the old data segment. | 332 | a gap between the old text segment and the old data segment. |
| 333 | This gap has probably been remapped into part of the text segment. | 333 | This gap has probably been remapped into part of the text segment. |
| 334 | So write zeros for it. */ | 334 | So write zeros for it. */ |
| 335 | if (ret == -1 | 335 | if (ret == -1 && errno == EFAULT) |
| 336 | #ifdef EFAULT | ||
| 337 | && errno == EFAULT | ||
| 338 | #endif | ||
| 339 | ) | ||
| 340 | { | 336 | { |
| 341 | /* Write only a page of zeros at once, | 337 | /* Write only a page of zeros at once, |
| 342 | so that we don't overshoot the start | 338 | so that we don't overshoot the start |
diff --git a/src/vm-limit.c b/src/vm-limit.c index 2a71e88695a..befc01d400f 100644 --- a/src/vm-limit.c +++ b/src/vm-limit.c | |||
| @@ -44,46 +44,26 @@ static POINTER data_space_start; | |||
| 44 | static size_t lim_data; | 44 | static size_t lim_data; |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | #if defined (HAVE_GETRLIMIT) && defined (RLIMIT_AS) | 47 | #ifdef HAVE_GETRLIMIT |
| 48 | static void | ||
| 49 | get_lim_data (void) | ||
| 50 | { | ||
| 51 | struct rlimit rlimit; | ||
| 52 | |||
| 53 | getrlimit (RLIMIT_AS, &rlimit); | ||
| 54 | if (rlimit.rlim_cur == RLIM_INFINITY) | ||
| 55 | lim_data = -1; | ||
| 56 | else | ||
| 57 | lim_data = rlimit.rlim_cur; | ||
| 58 | } | ||
| 59 | 48 | ||
| 60 | #else /* not HAVE_GETRLIMIT */ | 49 | # ifndef RLIMIT_AS |
| 61 | 50 | # define RLIMIT_AS RLIMIT_DATA | |
| 62 | #ifdef USG | 51 | # endif |
| 63 | 52 | ||
| 64 | static void | 53 | static void |
| 65 | get_lim_data (void) | 54 | get_lim_data (void) |
| 66 | { | 55 | { |
| 67 | extern long ulimit (); | 56 | /* Set LIM_DATA to the minimum of the maximum object size and the |
| 68 | 57 | maximum address space. Don't bother to check for values like | |
| 69 | lim_data = -1; | 58 | RLIM_INFINITY since in practice they are not much less than SIZE_MAX. */ |
| 70 | 59 | struct rlimit rlimit; | |
| 71 | /* Use the ulimit call, if we seem to have it. */ | 60 | lim_data |
| 72 | #if !defined (ULIMIT_BREAK_VALUE) || defined (GNU_LINUX) | 61 | = (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur <= SIZE_MAX |
| 73 | lim_data = ulimit (3, 0); | 62 | ? rlimit.rlim_cur |
| 74 | #endif | 63 | : SIZE_MAX); |
| 75 | |||
| 76 | /* If that didn't work, just use the macro's value. */ | ||
| 77 | #ifdef ULIMIT_BREAK_VALUE | ||
| 78 | if (lim_data == -1) | ||
| 79 | lim_data = ULIMIT_BREAK_VALUE; | ||
| 80 | #endif | ||
| 81 | |||
| 82 | lim_data -= (long) data_space_start; | ||
| 83 | } | 64 | } |
| 84 | 65 | ||
| 85 | #else /* not USG */ | 66 | #elif defined WINDOWSNT |
| 86 | #ifdef WINDOWSNT | ||
| 87 | 67 | ||
| 88 | #include "w32heap.h" | 68 | #include "w32heap.h" |
| 89 | 69 | ||
| @@ -94,10 +74,8 @@ get_lim_data (void) | |||
| 94 | lim_data = reserved_heap_size; | 74 | lim_data = reserved_heap_size; |
| 95 | } | 75 | } |
| 96 | 76 | ||
| 97 | #else | 77 | #elif defined MSDOS |
| 98 | #if !defined (BSD4_2) && !defined (CYGWIN) | ||
| 99 | 78 | ||
| 100 | #ifdef MSDOS | ||
| 101 | void | 79 | void |
| 102 | get_lim_data (void) | 80 | get_lim_data (void) |
| 103 | { | 81 | { |
| @@ -135,32 +113,9 @@ ret_lim_data (void) | |||
| 135 | get_lim_data (); | 113 | get_lim_data (); |
| 136 | return lim_data; | 114 | return lim_data; |
| 137 | } | 115 | } |
| 138 | #else /* not MSDOS */ | ||
| 139 | static void | ||
| 140 | get_lim_data (void) | ||
| 141 | { | ||
| 142 | lim_data = vlimit (LIM_DATA, -1); | ||
| 143 | } | ||
| 144 | #endif /* not MSDOS */ | ||
| 145 | |||
| 146 | #else /* BSD4_2 || CYGWIN */ | ||
| 147 | |||
| 148 | static void | ||
| 149 | get_lim_data (void) | ||
| 150 | { | ||
| 151 | struct rlimit XXrlimit; | ||
| 152 | |||
| 153 | getrlimit (RLIMIT_DATA, &XXrlimit); | ||
| 154 | #ifdef RLIM_INFINITY | ||
| 155 | lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */ | ||
| 156 | #else | 116 | #else |
| 157 | lim_data = XXrlimit.rlim_cur; /* soft limit */ | 117 | # error "get_lim_data not implemented on this machine" |
| 158 | #endif | 118 | #endif |
| 159 | } | ||
| 160 | #endif /* BSD4_2 */ | ||
| 161 | #endif /* not WINDOWSNT */ | ||
| 162 | #endif /* not USG */ | ||
| 163 | #endif /* not HAVE_GETRLIMIT */ | ||
| 164 | 119 | ||
| 165 | /* Verify amount of memory available, complaining if we're near the end. */ | 120 | /* Verify amount of memory available, complaining if we're near the end. */ |
| 166 | 121 | ||
| @@ -150,10 +150,18 @@ typedef struct _REPARSE_DATA_BUFFER { | |||
| 150 | } DUMMYUNIONNAME; | 150 | } DUMMYUNIONNAME; |
| 151 | } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; | 151 | } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; |
| 152 | 152 | ||
| 153 | #ifndef FILE_DEVICE_FILE_SYSTEM | ||
| 153 | #define FILE_DEVICE_FILE_SYSTEM 9 | 154 | #define FILE_DEVICE_FILE_SYSTEM 9 |
| 155 | #endif | ||
| 156 | #ifndef METHOD_BUFFERED | ||
| 154 | #define METHOD_BUFFERED 0 | 157 | #define METHOD_BUFFERED 0 |
| 158 | #endif | ||
| 159 | #ifndef FILE_ANY_ACCESS | ||
| 155 | #define FILE_ANY_ACCESS 0x00000000 | 160 | #define FILE_ANY_ACCESS 0x00000000 |
| 161 | #endif | ||
| 162 | #ifndef CTL_CODE | ||
| 156 | #define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) | 163 | #define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) |
| 164 | #endif | ||
| 157 | #define FSCTL_GET_REPARSE_POINT \ | 165 | #define FSCTL_GET_REPARSE_POINT \ |
| 158 | CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) | 166 | CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) |
| 159 | #endif | 167 | #endif |
| @@ -1536,6 +1544,50 @@ is_unc_volume (const char *filename) | |||
| 1536 | return 1; | 1544 | return 1; |
| 1537 | } | 1545 | } |
| 1538 | 1546 | ||
| 1547 | /* Emulate the Posix unsetenv. */ | ||
| 1548 | int | ||
| 1549 | unsetenv (const char *name) | ||
| 1550 | { | ||
| 1551 | char *var; | ||
| 1552 | size_t name_len; | ||
| 1553 | int retval; | ||
| 1554 | |||
| 1555 | if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) | ||
| 1556 | { | ||
| 1557 | errno = EINVAL; | ||
| 1558 | return -1; | ||
| 1559 | } | ||
| 1560 | name_len = strlen (name); | ||
| 1561 | /* MS docs says an environment variable cannot be longer than 32K. */ | ||
| 1562 | if (name_len > 32767) | ||
| 1563 | { | ||
| 1564 | errno = ENOMEM; | ||
| 1565 | return 0; | ||
| 1566 | } | ||
| 1567 | /* It is safe to use 'alloca' with 32K size, since the stack is at | ||
| 1568 | least 2MB, and we set it to 8MB in the link command line. */ | ||
| 1569 | var = alloca (name_len + 2); | ||
| 1570 | var[name_len++] = '='; | ||
| 1571 | var[name_len] = '\0'; | ||
| 1572 | return _putenv (var); | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | /* MS _putenv doesn't support removing a variable when the argument | ||
| 1576 | does not include the '=' character, so we fix that here. */ | ||
| 1577 | int | ||
| 1578 | sys_putenv (char *str) | ||
| 1579 | { | ||
| 1580 | const char *const name_end = strchr (str, '='); | ||
| 1581 | |||
| 1582 | if (name_end == NULL) | ||
| 1583 | { | ||
| 1584 | /* Remove the variable from the environment. */ | ||
| 1585 | return unsetenv (str); | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | return _putenv (str); | ||
| 1589 | } | ||
| 1590 | |||
| 1539 | #define REG_ROOT "SOFTWARE\\GNU\\Emacs" | 1591 | #define REG_ROOT "SOFTWARE\\GNU\\Emacs" |
| 1540 | 1592 | ||
| 1541 | LPBYTE | 1593 | LPBYTE |
diff --git a/src/w32common.h b/src/w32common.h index 50724e5553c..5e9b61824ae 100644 --- a/src/w32common.h +++ b/src/w32common.h | |||
| @@ -34,7 +34,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |||
| 34 | 34 | ||
| 35 | extern SYSTEM_INFO sysinfo_cache; | 35 | extern SYSTEM_INFO sysinfo_cache; |
| 36 | extern OSVERSIONINFO osinfo_cache; | 36 | extern OSVERSIONINFO osinfo_cache; |
| 37 | extern unsigned long syspage_mask; | 37 | extern DWORD_PTR syspage_mask; |
| 38 | 38 | ||
| 39 | extern int w32_major_version; | 39 | extern int w32_major_version; |
| 40 | extern int w32_minor_version; | 40 | extern int w32_minor_version; |
diff --git a/src/w32fns.c b/src/w32fns.c index 90f5b1695ea..1a181079c82 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -82,7 +82,6 @@ void syms_of_w32fns (void); | |||
| 82 | void globals_of_w32fns (void); | 82 | void globals_of_w32fns (void); |
| 83 | 83 | ||
| 84 | extern void free_frame_menubar (struct frame *); | 84 | extern void free_frame_menubar (struct frame *); |
| 85 | extern double atof (const char *); | ||
| 86 | extern int w32_console_toggle_lock_key (int, Lisp_Object); | 85 | extern int w32_console_toggle_lock_key (int, Lisp_Object); |
| 87 | extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); | 86 | extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); |
| 88 | extern void w32_free_menu_strings (HWND); | 87 | extern void w32_free_menu_strings (HWND); |
| @@ -223,7 +222,7 @@ SYSTEM_INFO sysinfo_cache; | |||
| 223 | /* This gives us version, build, and platform identification. */ | 222 | /* This gives us version, build, and platform identification. */ |
| 224 | OSVERSIONINFO osinfo_cache; | 223 | OSVERSIONINFO osinfo_cache; |
| 225 | 224 | ||
| 226 | unsigned long syspage_mask = 0; | 225 | DWORD_PTR syspage_mask = 0; |
| 227 | 226 | ||
| 228 | /* The major and minor versions of NT. */ | 227 | /* The major and minor versions of NT. */ |
| 229 | int w32_major_version; | 228 | int w32_major_version; |
| @@ -4867,18 +4866,6 @@ x_pixel_height (register struct frame *f) | |||
| 4867 | } | 4866 | } |
| 4868 | 4867 | ||
| 4869 | int | 4868 | int |
| 4870 | x_char_width (register struct frame *f) | ||
| 4871 | { | ||
| 4872 | return FRAME_COLUMN_WIDTH (f); | ||
| 4873 | } | ||
| 4874 | |||
| 4875 | int | ||
| 4876 | x_char_height (register struct frame *f) | ||
| 4877 | { | ||
| 4878 | return FRAME_LINE_HEIGHT (f); | ||
| 4879 | } | ||
| 4880 | |||
| 4881 | int | ||
| 4882 | x_screen_planes (register struct frame *f) | 4869 | x_screen_planes (register struct frame *f) |
| 4883 | { | 4870 | { |
| 4884 | return FRAME_W32_DISPLAY_INFO (f)->n_planes; | 4871 | return FRAME_W32_DISPLAY_INFO (f)->n_planes; |
| @@ -6035,7 +6022,7 @@ typedef char guichar_t; | |||
| 6035 | read-only when "Directories" is selected in the filter. This | 6022 | read-only when "Directories" is selected in the filter. This |
| 6036 | allows us to work around the fact that the standard Open File | 6023 | allows us to work around the fact that the standard Open File |
| 6037 | dialog does not support directories. */ | 6024 | dialog does not support directories. */ |
| 6038 | static UINT CALLBACK | 6025 | static UINT_PTR CALLBACK |
| 6039 | file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | 6026 | file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) |
| 6040 | { | 6027 | { |
| 6041 | if (msg == WM_NOTIFY) | 6028 | if (msg == WM_NOTIFY) |
| @@ -7797,7 +7784,7 @@ emacs_abort (void) | |||
| 7797 | /* stack[] gives the return addresses, whereas we want | 7784 | /* stack[] gives the return addresses, whereas we want |
| 7798 | the address of the call, so decrease each address | 7785 | the address of the call, so decrease each address |
| 7799 | by approximate size of 1 CALL instruction. */ | 7786 | by approximate size of 1 CALL instruction. */ |
| 7800 | sprintf (buf, "0x%p\r\n", stack[j] - sizeof(void *)); | 7787 | sprintf (buf, "0x%p\r\n", (char *)stack[j] - sizeof(void *)); |
| 7801 | if (stderr_fd >= 0) | 7788 | if (stderr_fd >= 0) |
| 7802 | write (stderr_fd, buf, strlen (buf)); | 7789 | write (stderr_fd, buf, strlen (buf)); |
| 7803 | if (errfile_fd >= 0) | 7790 | if (errfile_fd >= 0) |
diff --git a/src/w32proc.c b/src/w32proc.c index 9b111b40e36..d888200c556 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -1220,13 +1220,22 @@ waitpid (pid_t pid, int *status, int options) | |||
| 1220 | { | 1220 | { |
| 1221 | QUIT; | 1221 | QUIT; |
| 1222 | active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms); | 1222 | active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms); |
| 1223 | } while (active == WAIT_TIMEOUT); | 1223 | } while (active == WAIT_TIMEOUT && !dont_wait); |
| 1224 | 1224 | ||
| 1225 | if (active == WAIT_FAILED) | 1225 | if (active == WAIT_FAILED) |
| 1226 | { | 1226 | { |
| 1227 | errno = EBADF; | 1227 | errno = EBADF; |
| 1228 | return -1; | 1228 | return -1; |
| 1229 | } | 1229 | } |
| 1230 | else if (active == WAIT_TIMEOUT && dont_wait) | ||
| 1231 | { | ||
| 1232 | /* PID specifies our subprocess, but it didn't exit yet, so its | ||
| 1233 | status is not yet available. */ | ||
| 1234 | #ifdef FULL_DEBUG | ||
| 1235 | DebPrint (("Wait: PID %d not reap yet\n", cp->pid)); | ||
| 1236 | #endif | ||
| 1237 | return 0; | ||
| 1238 | } | ||
| 1230 | else if (active >= WAIT_OBJECT_0 | 1239 | else if (active >= WAIT_OBJECT_0 |
| 1231 | && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS) | 1240 | && active < WAIT_OBJECT_0+MAXIMUM_WAIT_OBJECTS) |
| 1232 | { | 1241 | { |
| @@ -1274,33 +1283,7 @@ waitpid (pid_t pid, int *status, int options) | |||
| 1274 | #endif | 1283 | #endif |
| 1275 | 1284 | ||
| 1276 | if (status) | 1285 | if (status) |
| 1277 | { | 1286 | *status = retval; |
| 1278 | *status = retval; | ||
| 1279 | } | ||
| 1280 | else if (synch_process_alive) | ||
| 1281 | { | ||
| 1282 | synch_process_alive = 0; | ||
| 1283 | |||
| 1284 | /* Report the status of the synchronous process. */ | ||
| 1285 | if (WIFEXITED (retval)) | ||
| 1286 | synch_process_retcode = WEXITSTATUS (retval); | ||
| 1287 | else if (WIFSIGNALED (retval)) | ||
| 1288 | { | ||
| 1289 | int code = WTERMSIG (retval); | ||
| 1290 | const char *signame; | ||
| 1291 | |||
| 1292 | synchronize_system_messages_locale (); | ||
| 1293 | signame = strsignal (code); | ||
| 1294 | |||
| 1295 | if (signame == 0) | ||
| 1296 | signame = "unknown"; | ||
| 1297 | |||
| 1298 | synch_process_death = signame; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | reap_subprocess (cp); | ||
| 1302 | } | ||
| 1303 | |||
| 1304 | reap_subprocess (cp); | 1287 | reap_subprocess (cp); |
| 1305 | 1288 | ||
| 1306 | return pid; | 1289 | return pid; |
| @@ -2139,6 +2122,10 @@ sys_kill (int pid, int sig) | |||
| 2139 | int need_to_free = 0; | 2122 | int need_to_free = 0; |
| 2140 | int rc = 0; | 2123 | int rc = 0; |
| 2141 | 2124 | ||
| 2125 | /* Each process is in its own process group. */ | ||
| 2126 | if (pid < 0) | ||
| 2127 | pid = -pid; | ||
| 2128 | |||
| 2142 | /* Only handle signals that will result in the process dying */ | 2129 | /* Only handle signals that will result in the process dying */ |
| 2143 | if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) | 2130 | if (sig != SIGINT && sig != SIGKILL && sig != SIGQUIT && sig != SIGHUP) |
| 2144 | { | 2131 | { |
diff --git a/src/w32term.c b/src/w32term.c index ab6afd32c75..e26777543fb 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -1738,8 +1738,8 @@ w32_draw_relief_rect (struct frame *f, | |||
| 1738 | if (left_p) | 1738 | if (left_p) |
| 1739 | for (i = 0; i < width; ++i) | 1739 | for (i = 0; i < width; ++i) |
| 1740 | w32_fill_area (f, hdc, gc.foreground, | 1740 | w32_fill_area (f, hdc, gc.foreground, |
| 1741 | left_x + i, top_y + i, 1, | 1741 | left_x + i, top_y + (i + 1) * top_p, 1, |
| 1742 | bottom_y - top_y - 2 * i + 1); | 1742 | bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1); |
| 1743 | 1743 | ||
| 1744 | if (raised_p) | 1744 | if (raised_p) |
| 1745 | gc.foreground = f->output_data.w32->black_relief.gc->foreground; | 1745 | gc.foreground = f->output_data.w32->black_relief.gc->foreground; |
| @@ -1757,8 +1757,8 @@ w32_draw_relief_rect (struct frame *f, | |||
| 1757 | if (right_p) | 1757 | if (right_p) |
| 1758 | for (i = 0; i < width; ++i) | 1758 | for (i = 0; i < width; ++i) |
| 1759 | w32_fill_area (f, hdc, gc.foreground, | 1759 | w32_fill_area (f, hdc, gc.foreground, |
| 1760 | right_x - i, top_y + i + 1, 1, | 1760 | right_x - i, top_y + (i + 1) * top_p, 1, |
| 1761 | bottom_y - top_y - 2 * i - 1); | 1761 | bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1); |
| 1762 | 1762 | ||
| 1763 | w32_set_clip_rectangle (hdc, NULL); | 1763 | w32_set_clip_rectangle (hdc, NULL); |
| 1764 | 1764 | ||
| @@ -1952,7 +1952,7 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 1952 | static void | 1952 | static void |
| 1953 | x_draw_image_relief (struct glyph_string *s) | 1953 | x_draw_image_relief (struct glyph_string *s) |
| 1954 | { | 1954 | { |
| 1955 | int x0, y0, x1, y1, thick, raised_p; | 1955 | int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p; |
| 1956 | RECT r; | 1956 | RECT r; |
| 1957 | int x = s->x; | 1957 | int x = s->x; |
| 1958 | int y = s->ybase - image_ascent (s->img, s->face, &s->slice); | 1958 | int y = s->ybase - image_ascent (s->img, s->face, &s->slice); |
| @@ -1984,19 +1984,23 @@ x_draw_image_relief (struct glyph_string *s) | |||
| 1984 | raised_p = s->img->relief > 0; | 1984 | raised_p = s->img->relief > 0; |
| 1985 | } | 1985 | } |
| 1986 | 1986 | ||
| 1987 | x0 = x - thick; | 1987 | x1 = x + s->slice.width - 1; |
| 1988 | y0 = y - thick; | 1988 | y1 = y + s->slice.height - 1; |
| 1989 | x1 = x + s->slice.width + thick - 1; | 1989 | top_p = bot_p = left_p = right_p = 0; |
| 1990 | y1 = y + s->slice.height + thick - 1; | 1990 | |
| 1991 | if (s->slice.x == 0) | ||
| 1992 | x -= thick, left_p = 1; | ||
| 1993 | if (s->slice.y == 0) | ||
| 1994 | y -= thick, top_p = 1; | ||
| 1995 | if (s->slice.x + s->slice.width == s->img->width) | ||
| 1996 | x1 += thick, right_p = 1; | ||
| 1997 | if (s->slice.y + s->slice.height == s->img->height) | ||
| 1998 | y1 += thick, bot_p = 1; | ||
| 1991 | 1999 | ||
| 1992 | x_setup_relief_colors (s); | 2000 | x_setup_relief_colors (s); |
| 1993 | get_glyph_string_clip_rect (s, &r); | 2001 | get_glyph_string_clip_rect (s, &r); |
| 1994 | w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, | 2002 | w32_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p, |
| 1995 | s->slice.y == 0, | 2003 | top_p, bot_p, left_p, right_p, &r); |
| 1996 | s->slice.y + s->slice.height == s->img->height, | ||
| 1997 | s->slice.x == 0, | ||
| 1998 | s->slice.x + s->slice.width == s->img->width, | ||
| 1999 | &r); | ||
| 2000 | } | 2004 | } |
| 2001 | 2005 | ||
| 2002 | 2006 | ||
| @@ -5344,7 +5348,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) | |||
| 5344 | FRAME_FONT (f) = font; | 5348 | FRAME_FONT (f) = font; |
| 5345 | FRAME_BASELINE_OFFSET (f) = font->baseline_offset; | 5349 | FRAME_BASELINE_OFFSET (f) = font->baseline_offset; |
| 5346 | FRAME_COLUMN_WIDTH (f) = font->average_width; | 5350 | FRAME_COLUMN_WIDTH (f) = font->average_width; |
| 5347 | FRAME_SPACE_WIDTH (f) = font->space_width; | ||
| 5348 | FRAME_LINE_HEIGHT (f) = font->height; | 5351 | FRAME_LINE_HEIGHT (f) = font->height; |
| 5349 | 5352 | ||
| 5350 | compute_fringe_widths (f, 1); | 5353 | compute_fringe_widths (f, 1); |
diff --git a/src/w32term.h b/src/w32term.h index 28d4ca6c490..af1a79e21c9 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -217,8 +217,6 @@ extern void x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); | |||
| 217 | extern void x_make_frame_visible (struct frame *f); | 217 | extern void x_make_frame_visible (struct frame *f); |
| 218 | extern void x_make_frame_invisible (struct frame *f); | 218 | extern void x_make_frame_invisible (struct frame *f); |
| 219 | extern void x_iconify_frame (struct frame *f); | 219 | extern void x_iconify_frame (struct frame *f); |
| 220 | extern int x_char_width (struct frame *f); | ||
| 221 | extern int x_char_height (struct frame *f); | ||
| 222 | extern int x_pixel_width (struct frame *f); | 220 | extern int x_pixel_width (struct frame *f); |
| 223 | extern int x_pixel_height (struct frame *f); | 221 | extern int x_pixel_height (struct frame *f); |
| 224 | extern void x_set_frame_alpha (struct frame *f); | 222 | extern void x_set_frame_alpha (struct frame *f); |
diff --git a/src/window.c b/src/window.c index 9f3474fcd53..d7c2e8b236e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -3250,8 +3250,7 @@ This function runs `window-scroll-functions' before running | |||
| 3250 | tem = w->buffer; | 3250 | tem = w->buffer; |
| 3251 | if (NILP (tem)) | 3251 | if (NILP (tem)) |
| 3252 | error ("Window is deleted"); | 3252 | error ("Window is deleted"); |
| 3253 | else if (!EQ (tem, Qt)) | 3253 | else |
| 3254 | /* w->buffer is t when the window is first being set up. */ | ||
| 3255 | { | 3254 | { |
| 3256 | if (!EQ (tem, buffer)) | 3255 | if (!EQ (tem, buffer)) |
| 3257 | { | 3256 | { |
| @@ -3914,7 +3913,6 @@ set correctly. See the code of `split-window' for how this is done. */) | |||
| 3914 | wset_next (o, new); | 3913 | wset_next (o, new); |
| 3915 | } | 3914 | } |
| 3916 | 3915 | ||
| 3917 | wset_buffer (n, Qt); | ||
| 3918 | wset_window_end_valid (n, Qnil); | 3916 | wset_window_end_valid (n, Qnil); |
| 3919 | memset (&n->last_cursor, 0, sizeof n->last_cursor); | 3917 | memset (&n->last_cursor, 0, sizeof n->last_cursor); |
| 3920 | 3918 | ||
diff --git a/src/xdisp.c b/src/xdisp.c index 2390475ca77..9464e87b362 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -10888,22 +10888,24 @@ echo_area_display (int update_frame_p) | |||
| 10888 | return window_height_changed_p; | 10888 | return window_height_changed_p; |
| 10889 | } | 10889 | } |
| 10890 | 10890 | ||
| 10891 | /* Nonzero if the current buffer is shown in more than | 10891 | /* Nonzero if the current window's buffer is shown in more than one |
| 10892 | one window and was modified since last display. */ | 10892 | window and was modified since last redisplay. */ |
| 10893 | 10893 | ||
| 10894 | static int | 10894 | static int |
| 10895 | buffer_shared_and_changed (void) | 10895 | buffer_shared_and_changed (void) |
| 10896 | { | 10896 | { |
| 10897 | /* The variable buffer_shared is set in redisplay_window and | ||
| 10898 | indicates that we redisplay a buffer in different windows. */ | ||
| 10897 | return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); | 10899 | return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); |
| 10898 | } | 10900 | } |
| 10899 | 10901 | ||
| 10900 | /* Nonzero if W doesn't reflect the actual state of | 10902 | /* Nonzero if W doesn't reflect the actual state of current buffer due |
| 10901 | current buffer due to its text or overlays change. */ | 10903 | to its text or overlays change. FIXME: this may be called when |
| 10904 | XBUFFER (w->buffer) != current_buffer, which looks suspicious. */ | ||
| 10902 | 10905 | ||
| 10903 | static int | 10906 | static int |
| 10904 | window_outdated (struct window *w) | 10907 | window_outdated (struct window *w) |
| 10905 | { | 10908 | { |
| 10906 | eassert (XBUFFER (w->buffer) == current_buffer); | ||
| 10907 | return (w->last_modified < MODIFF | 10909 | return (w->last_modified < MODIFF |
| 10908 | || w->last_overlay_modified < OVERLAY_MODIFF); | 10910 | || w->last_overlay_modified < OVERLAY_MODIFF); |
| 10909 | } | 10911 | } |
| @@ -10923,6 +10925,16 @@ window_buffer_changed (struct window *w) | |||
| 10923 | != !NILP (w->region_showing))); | 10925 | != !NILP (w->region_showing))); |
| 10924 | } | 10926 | } |
| 10925 | 10927 | ||
| 10928 | /* Nonzero if W has %c in its mode line and mode line should be updated. */ | ||
| 10929 | |||
| 10930 | static int | ||
| 10931 | mode_line_update_needed (struct window *w) | ||
| 10932 | { | ||
| 10933 | return (!NILP (w->column_number_displayed) | ||
| 10934 | && !(PT == w->last_point && !window_outdated (w)) | ||
| 10935 | && (XFASTINT (w->column_number_displayed) != current_column ())); | ||
| 10936 | } | ||
| 10937 | |||
| 10926 | /*********************************************************************** | 10938 | /*********************************************************************** |
| 10927 | Mode Lines and Frame Titles | 10939 | Mode Lines and Frame Titles |
| 10928 | ***********************************************************************/ | 10940 | ***********************************************************************/ |
| @@ -12253,7 +12265,6 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p, | |||
| 12253 | { | 12265 | { |
| 12254 | /* Show item in pressed state. */ | 12266 | /* Show item in pressed state. */ |
| 12255 | show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN); | 12267 | show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN); |
| 12256 | hlinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; | ||
| 12257 | last_tool_bar_item = prop_idx; | 12268 | last_tool_bar_item = prop_idx; |
| 12258 | } | 12269 | } |
| 12259 | else | 12270 | else |
| @@ -12264,7 +12275,6 @@ handle_tool_bar_click (struct frame *f, int x, int y, int down_p, | |||
| 12264 | 12275 | ||
| 12265 | /* Show item in released state. */ | 12276 | /* Show item in released state. */ |
| 12266 | show_mouse_face (hlinfo, DRAW_IMAGE_RAISED); | 12277 | show_mouse_face (hlinfo, DRAW_IMAGE_RAISED); |
| 12267 | hlinfo->mouse_face_image_state = DRAW_IMAGE_RAISED; | ||
| 12268 | 12278 | ||
| 12269 | key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY); | 12279 | key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY); |
| 12270 | 12280 | ||
| @@ -12333,7 +12343,6 @@ note_tool_bar_highlight (struct frame *f, int x, int y) | |||
| 12333 | && last_tool_bar_item != prop_idx) | 12343 | && last_tool_bar_item != prop_idx) |
| 12334 | return; | 12344 | return; |
| 12335 | 12345 | ||
| 12336 | hlinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; | ||
| 12337 | draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; | 12346 | draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; |
| 12338 | 12347 | ||
| 12339 | /* If tool-bar item is not enabled, don't highlight it. */ | 12348 | /* If tool-bar item is not enabled, don't highlight it. */ |
| @@ -12362,7 +12371,6 @@ note_tool_bar_highlight (struct frame *f, int x, int y) | |||
| 12362 | 12371 | ||
| 12363 | /* Display it as active. */ | 12372 | /* Display it as active. */ |
| 12364 | show_mouse_face (hlinfo, draw); | 12373 | show_mouse_face (hlinfo, draw); |
| 12365 | hlinfo->mouse_face_image_state = draw; | ||
| 12366 | } | 12374 | } |
| 12367 | 12375 | ||
| 12368 | set_help_echo: | 12376 | set_help_echo: |
| @@ -12967,6 +12975,15 @@ select_frame_for_redisplay (Lisp_Object frame) | |||
| 12967 | } while (!EQ (frame, old) && (frame = old, 1)); | 12975 | } while (!EQ (frame, old) && (frame = old, 1)); |
| 12968 | } | 12976 | } |
| 12969 | 12977 | ||
| 12978 | /* Make sure that previously selected OLD_FRAME is selected unless it has been | ||
| 12979 | deleted (by an X connection failure during redisplay, for example). */ | ||
| 12980 | |||
| 12981 | static void | ||
| 12982 | ensure_selected_frame (Lisp_Object old_frame) | ||
| 12983 | { | ||
| 12984 | if (!EQ (old_frame, selected_frame) && FRAME_LIVE_P (XFRAME (old_frame))) | ||
| 12985 | select_frame_for_redisplay (old_frame); | ||
| 12986 | } | ||
| 12970 | 12987 | ||
| 12971 | #define STOP_POLLING \ | 12988 | #define STOP_POLLING \ |
| 12972 | do { if (! polling_stopped_here) stop_polling (); \ | 12989 | do { if (! polling_stopped_here) stop_polling (); \ |
| @@ -13052,13 +13069,11 @@ redisplay_internal (void) | |||
| 13052 | /* Remember the currently selected window. */ | 13069 | /* Remember the currently selected window. */ |
| 13053 | sw = w; | 13070 | sw = w; |
| 13054 | 13071 | ||
| 13055 | if (!EQ (old_frame, selected_frame) | 13072 | /* When running redisplay, we play a bit fast-and-loose and allow e.g. |
| 13056 | && FRAME_LIVE_P (XFRAME (old_frame))) | 13073 | selected_frame and selected_window to be temporarily out-of-sync so |
| 13057 | /* When running redisplay, we play a bit fast-and-loose and allow e.g. | 13074 | when we come back here via `goto retry', we need to resync because we |
| 13058 | selected_frame and selected_window to be temporarily out-of-sync so | 13075 | may need to run Elisp code (via prepare_menu_bars). */ |
| 13059 | when we come back here via `goto retry', we need to resync because we | 13076 | ensure_selected_frame (old_frame); |
| 13060 | may need to run Elisp code (via prepare_menu_bars). */ | ||
| 13061 | select_frame_for_redisplay (old_frame); | ||
| 13062 | 13077 | ||
| 13063 | pending = 0; | 13078 | pending = 0; |
| 13064 | reconsider_clip_changes (w, current_buffer); | 13079 | reconsider_clip_changes (w, current_buffer); |
| @@ -13144,21 +13159,13 @@ redisplay_internal (void) | |||
| 13144 | count1 = SPECPDL_INDEX (); | 13159 | count1 = SPECPDL_INDEX (); |
| 13145 | specbind (Qinhibit_point_motion_hooks, Qt); | 13160 | specbind (Qinhibit_point_motion_hooks, Qt); |
| 13146 | 13161 | ||
| 13147 | /* If %c is in the mode line, update it if needed. */ | 13162 | if (mode_line_update_needed (w)) |
| 13148 | if (!NILP (w->column_number_displayed) | ||
| 13149 | /* This alternative quickly identifies a common case | ||
| 13150 | where no change is needed. */ | ||
| 13151 | && !(PT == w->last_point && !window_outdated (w)) | ||
| 13152 | && (XFASTINT (w->column_number_displayed) != current_column ())) | ||
| 13153 | w->update_mode_line = 1; | 13163 | w->update_mode_line = 1; |
| 13154 | 13164 | ||
| 13155 | unbind_to (count1, Qnil); | 13165 | unbind_to (count1, Qnil); |
| 13156 | 13166 | ||
| 13157 | FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1; | 13167 | FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1; |
| 13158 | 13168 | ||
| 13159 | /* The variable buffer_shared is set in redisplay_window and | ||
| 13160 | indicates that we redisplay a buffer in different windows. See | ||
| 13161 | there. */ | ||
| 13162 | consider_all_windows_p = (update_mode_lines | 13169 | consider_all_windows_p = (update_mode_lines |
| 13163 | || buffer_shared_and_changed () | 13170 | || buffer_shared_and_changed () |
| 13164 | || cursor_type_changed); | 13171 | || cursor_type_changed); |
| @@ -13533,14 +13540,11 @@ redisplay_internal (void) | |||
| 13533 | } | 13540 | } |
| 13534 | } | 13541 | } |
| 13535 | 13542 | ||
| 13536 | if (!EQ (old_frame, selected_frame) | 13543 | /* We played a bit fast-and-loose above and allowed selected_frame |
| 13537 | && FRAME_LIVE_P (XFRAME (old_frame))) | 13544 | and selected_window to be temporarily out-of-sync but let's make |
| 13538 | /* We played a bit fast-and-loose above and allowed selected_frame | 13545 | sure this stays contained. */ |
| 13539 | and selected_window to be temporarily out-of-sync but let's make | 13546 | ensure_selected_frame (old_frame); |
| 13540 | sure this stays contained. */ | 13547 | eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); |
| 13541 | select_frame_for_redisplay (old_frame); | ||
| 13542 | eassert (EQ (XFRAME (selected_frame)->selected_window, | ||
| 13543 | selected_window)); | ||
| 13544 | 13548 | ||
| 13545 | if (!pending) | 13549 | if (!pending) |
| 13546 | { | 13550 | { |
| @@ -13759,17 +13763,13 @@ redisplay_preserve_echo_area (int from_where) | |||
| 13759 | 13763 | ||
| 13760 | 13764 | ||
| 13761 | /* Function registered with record_unwind_protect in redisplay_internal. | 13765 | /* Function registered with record_unwind_protect in redisplay_internal. |
| 13762 | Clear redisplaying_p. Also, select the previously | 13766 | Clear redisplaying_p. Also select the previously selected frame. */ |
| 13763 | selected frame, unless it has been deleted (by an X connection | ||
| 13764 | failure during redisplay, for example). */ | ||
| 13765 | 13767 | ||
| 13766 | static Lisp_Object | 13768 | static Lisp_Object |
| 13767 | unwind_redisplay (Lisp_Object old_frame) | 13769 | unwind_redisplay (Lisp_Object old_frame) |
| 13768 | { | 13770 | { |
| 13769 | redisplaying_p = 0; | 13771 | redisplaying_p = 0; |
| 13770 | if (! EQ (old_frame, selected_frame) | 13772 | ensure_selected_frame (old_frame); |
| 13771 | && FRAME_LIVE_P (XFRAME (old_frame))) | ||
| 13772 | select_frame_for_redisplay (old_frame); | ||
| 13773 | return Qnil; | 13773 | return Qnil; |
| 13774 | } | 13774 | } |
| 13775 | 13775 | ||
| @@ -15565,12 +15565,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15565 | if (BYTEPOS (opoint) < CHARPOS (opoint)) | 15565 | if (BYTEPOS (opoint) < CHARPOS (opoint)) |
| 15566 | emacs_abort (); | 15566 | emacs_abort (); |
| 15567 | 15567 | ||
| 15568 | /* If %c is in mode line, update it if needed. */ | 15568 | if (mode_line_update_needed (w)) |
| 15569 | if (!NILP (w->column_number_displayed) | ||
| 15570 | /* This alternative quickly identifies a common case | ||
| 15571 | where no change is needed. */ | ||
| 15572 | && !(PT == w->last_point && !window_outdated (w)) | ||
| 15573 | && (XFASTINT (w->column_number_displayed) != current_column ())) | ||
| 15574 | update_mode_line = 1; | 15569 | update_mode_line = 1; |
| 15575 | 15570 | ||
| 15576 | /* Count number of windows showing the selected buffer. An indirect | 15571 | /* Count number of windows showing the selected buffer. An indirect |
| @@ -15718,6 +15713,35 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15718 | Move it back to a fully-visible line. */ | 15713 | Move it back to a fully-visible line. */ |
| 15719 | new_vpos = window_box_height (w); | 15714 | new_vpos = window_box_height (w); |
| 15720 | } | 15715 | } |
| 15716 | else if (w->cursor.vpos >=0) | ||
| 15717 | { | ||
| 15718 | /* Some people insist on not letting point enter the scroll | ||
| 15719 | margin, even though this part handles windows that didn't | ||
| 15720 | scroll at all. */ | ||
| 15721 | struct frame *f = XFRAME (w->frame); | ||
| 15722 | int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); | ||
| 15723 | int pixel_margin = margin * FRAME_LINE_HEIGHT (f); | ||
| 15724 | bool header_line = WINDOW_WANTS_HEADER_LINE_P (w); | ||
| 15725 | |||
| 15726 | /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop | ||
| 15727 | below, which finds the row to move point to, advances by | ||
| 15728 | the Y coordinate of the _next_ row, see the definition of | ||
| 15729 | MATRIX_ROW_BOTTOM_Y. */ | ||
| 15730 | if (w->cursor.vpos < margin + header_line) | ||
| 15731 | new_vpos | ||
| 15732 | = pixel_margin + (header_line | ||
| 15733 | ? CURRENT_HEADER_LINE_HEIGHT (w) | ||
| 15734 | : 0) + FRAME_LINE_HEIGHT (f); | ||
| 15735 | else | ||
| 15736 | { | ||
| 15737 | int window_height = window_box_height (w); | ||
| 15738 | |||
| 15739 | if (header_line) | ||
| 15740 | window_height += CURRENT_HEADER_LINE_HEIGHT (w); | ||
| 15741 | if (w->cursor.y >= window_height - pixel_margin) | ||
| 15742 | new_vpos = window_height - pixel_margin; | ||
| 15743 | } | ||
| 15744 | } | ||
| 15721 | 15745 | ||
| 15722 | /* If we need to move point for either of the above reasons, | 15746 | /* If we need to move point for either of the above reasons, |
| 15723 | now actually do it. */ | 15747 | now actually do it. */ |
| @@ -23506,7 +23530,9 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row, | |||
| 23506 | 23530 | ||
| 23507 | /* If mouse highlighting is on, we may need to draw adjacent | 23531 | /* If mouse highlighting is on, we may need to draw adjacent |
| 23508 | glyphs using mouse-face highlighting. */ | 23532 | glyphs using mouse-face highlighting. */ |
| 23509 | if (area == TEXT_AREA && row->mouse_face_p) | 23533 | if (area == TEXT_AREA && row->mouse_face_p |
| 23534 | && hlinfo->mouse_face_beg_row >= 0 | ||
| 23535 | && hlinfo->mouse_face_end_row >= 0) | ||
| 23510 | { | 23536 | { |
| 23511 | struct glyph_row *mouse_beg_row, *mouse_end_row; | 23537 | struct glyph_row *mouse_beg_row, *mouse_end_row; |
| 23512 | 23538 | ||
diff --git a/src/xfns.c b/src/xfns.c index 1f98e9fc8c7..7e832c3a95f 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3848,20 +3848,6 @@ x_pixel_height (register struct frame *f) | |||
| 3848 | return FRAME_PIXEL_HEIGHT (f); | 3848 | return FRAME_PIXEL_HEIGHT (f); |
| 3849 | } | 3849 | } |
| 3850 | 3850 | ||
| 3851 | int | ||
| 3852 | x_char_width (register struct frame *f) | ||
| 3853 | { | ||
| 3854 | return FRAME_COLUMN_WIDTH (f); | ||
| 3855 | } | ||
| 3856 | |||
| 3857 | int | ||
| 3858 | x_char_height (register struct frame *f) | ||
| 3859 | { | ||
| 3860 | return FRAME_LINE_HEIGHT (f); | ||
| 3861 | } | ||
| 3862 | |||
| 3863 | |||
| 3864 | |||
| 3865 | /************************************************************************ | 3851 | /************************************************************************ |
| 3866 | X Displays | 3852 | X Displays |
| 3867 | ************************************************************************/ | 3853 | ************************************************************************/ |
diff --git a/src/xterm.c b/src/xterm.c index 61e942e10d2..e9e99574663 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -2019,7 +2019,8 @@ x_draw_relief_rect (struct frame *f, | |||
| 2019 | 2019 | ||
| 2020 | for (i = (width > 1 ? 1 : 0); i < width; ++i) | 2020 | for (i = (width > 1 ? 1 : 0); i < width; ++i) |
| 2021 | XDrawLine (dpy, window, gc, | 2021 | XDrawLine (dpy, window, gc, |
| 2022 | left_x + i, top_y + i, left_x + i, bottom_y - i + 1); | 2022 | left_x + i, top_y + (i + 1) * top_p, |
| 2023 | left_x + i, bottom_y + 1 - (i + 1) * bot_p); | ||
| 2023 | } | 2024 | } |
| 2024 | 2025 | ||
| 2025 | XSetClipMask (dpy, gc, None); | 2026 | XSetClipMask (dpy, gc, None); |
| @@ -2061,7 +2062,8 @@ x_draw_relief_rect (struct frame *f, | |||
| 2061 | XClearArea (dpy, window, right_x, bottom_y, 1, 1, False); | 2062 | XClearArea (dpy, window, right_x, bottom_y, 1, 1, False); |
| 2062 | for (i = 0; i < width; ++i) | 2063 | for (i = 0; i < width; ++i) |
| 2063 | XDrawLine (dpy, window, gc, | 2064 | XDrawLine (dpy, window, gc, |
| 2064 | right_x - i, top_y + i + 1, right_x - i, bottom_y - i); | 2065 | right_x - i, top_y + (i + 1) * top_p, |
| 2066 | right_x - i, bottom_y + 1 - (i + 1) * bot_p); | ||
| 2065 | } | 2067 | } |
| 2066 | 2068 | ||
| 2067 | XSetClipMask (dpy, gc, None); | 2069 | XSetClipMask (dpy, gc, None); |
| @@ -2255,8 +2257,7 @@ x_draw_image_foreground (struct glyph_string *s) | |||
| 2255 | static void | 2257 | static void |
| 2256 | x_draw_image_relief (struct glyph_string *s) | 2258 | x_draw_image_relief (struct glyph_string *s) |
| 2257 | { | 2259 | { |
| 2258 | int x0, y0, x1, y1, thick, raised_p; | 2260 | int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p; |
| 2259 | int extra_x, extra_y; | ||
| 2260 | XRectangle r; | 2261 | XRectangle r; |
| 2261 | int x = s->x; | 2262 | int x = s->x; |
| 2262 | int y = s->ybase - image_ascent (s->img, s->face, &s->slice); | 2263 | int y = s->ybase - image_ascent (s->img, s->face, &s->slice); |
| @@ -2287,33 +2288,23 @@ x_draw_image_relief (struct glyph_string *s) | |||
| 2287 | raised_p = s->img->relief > 0; | 2288 | raised_p = s->img->relief > 0; |
| 2288 | } | 2289 | } |
| 2289 | 2290 | ||
| 2290 | extra_x = extra_y = 0; | 2291 | x1 = x + s->slice.width - 1; |
| 2291 | if (s->face->id == TOOL_BAR_FACE_ID) | 2292 | y1 = y + s->slice.height - 1; |
| 2292 | { | 2293 | top_p = bot_p = left_p = right_p = 0; |
| 2293 | if (CONSP (Vtool_bar_button_margin) | ||
| 2294 | && INTEGERP (XCAR (Vtool_bar_button_margin)) | ||
| 2295 | && INTEGERP (XCDR (Vtool_bar_button_margin))) | ||
| 2296 | { | ||
| 2297 | extra_x = XINT (XCAR (Vtool_bar_button_margin)); | ||
| 2298 | extra_y = XINT (XCDR (Vtool_bar_button_margin)); | ||
| 2299 | } | ||
| 2300 | else if (INTEGERP (Vtool_bar_button_margin)) | ||
| 2301 | extra_x = extra_y = XINT (Vtool_bar_button_margin); | ||
| 2302 | } | ||
| 2303 | 2294 | ||
| 2304 | x0 = x - thick - extra_x; | 2295 | if (s->slice.x == 0) |
| 2305 | y0 = y - thick - extra_y; | 2296 | x -= thick, left_p = 1; |
| 2306 | x1 = x + s->slice.width + thick - 1 + extra_x; | 2297 | if (s->slice.y == 0) |
| 2307 | y1 = y + s->slice.height + thick - 1 + extra_y; | 2298 | y -= thick, top_p = 1; |
| 2299 | if (s->slice.x + s->slice.width == s->img->width) | ||
| 2300 | x1 += thick, right_p = 1; | ||
| 2301 | if (s->slice.y + s->slice.height == s->img->height) | ||
| 2302 | y1 += thick, bot_p = 1; | ||
| 2308 | 2303 | ||
| 2309 | x_setup_relief_colors (s); | 2304 | x_setup_relief_colors (s); |
| 2310 | get_glyph_string_clip_rect (s, &r); | 2305 | get_glyph_string_clip_rect (s, &r); |
| 2311 | x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, | 2306 | x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p, |
| 2312 | s->slice.y == 0, | 2307 | top_p, bot_p, left_p, right_p, &r); |
| 2313 | s->slice.y + s->slice.height == s->img->height, | ||
| 2314 | s->slice.x == 0, | ||
| 2315 | s->slice.x + s->slice.width == s->img->width, | ||
| 2316 | &r); | ||
| 2317 | } | 2308 | } |
| 2318 | 2309 | ||
| 2319 | 2310 | ||
| @@ -7911,7 +7902,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) | |||
| 7911 | FRAME_FONT (f) = font; | 7902 | FRAME_FONT (f) = font; |
| 7912 | FRAME_BASELINE_OFFSET (f) = font->baseline_offset; | 7903 | FRAME_BASELINE_OFFSET (f) = font->baseline_offset; |
| 7913 | FRAME_COLUMN_WIDTH (f) = font->average_width; | 7904 | FRAME_COLUMN_WIDTH (f) = font->average_width; |
| 7914 | FRAME_SPACE_WIDTH (f) = font->space_width; | ||
| 7915 | FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); | 7905 | FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); |
| 7916 | 7906 | ||
| 7917 | compute_fringe_widths (f, 1); | 7907 | compute_fringe_widths (f, 1); |
| @@ -9918,10 +9908,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 9918 | 9908 | ||
| 9919 | /* Emacs can only handle core input events, so make sure | 9909 | /* Emacs can only handle core input events, so make sure |
| 9920 | Gtk doesn't use Xinput or Xinput2 extensions. */ | 9910 | Gtk doesn't use Xinput or Xinput2 extensions. */ |
| 9921 | { | 9911 | xputenv ("GDK_CORE_DEVICE_EVENTS=1"); |
| 9922 | static char fix_events[] = "GDK_CORE_DEVICE_EVENTS=1"; | ||
| 9923 | putenv (fix_events); | ||
| 9924 | } | ||
| 9925 | 9912 | ||
| 9926 | /* Work around GLib bug that outputs a faulty warning. See | 9913 | /* Work around GLib bug that outputs a faulty warning. See |
| 9927 | https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ | 9914 | https://bugzilla.gnome.org/show_bug.cgi?id=563627. */ |