aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBill Wohler2012-12-08 17:19:00 -0800
committerBill Wohler2012-12-08 17:19:00 -0800
commite1b489df7af8f7034f8c2ef275b786e93a39df31 (patch)
tree2edc9307185e2c77b98fe75f6d7eb0476c58c7e3 /src
parentce974958f93ffa2e1bd01b4dd85dcb8ec1395787 (diff)
parentc6c08d3f8fe4d2c9e588189e46d60a30ef3e8d20 (diff)
downloademacs-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/ChangeLog377
-rw-r--r--src/alloc.c41
-rw-r--r--src/buffer.c25
-rw-r--r--src/buffer.h5
-rw-r--r--src/bytecode.c4
-rw-r--r--src/callproc.c363
-rw-r--r--src/casefiddle.c2
-rw-r--r--src/charset.c4
-rw-r--r--src/data.c8
-rw-r--r--src/dbusbind.c2
-rw-r--r--src/dired.c46
-rw-r--r--src/dispextern.h12
-rw-r--r--src/doc.c8
-rw-r--r--src/doprnt.c5
-rw-r--r--src/editfns.c302
-rw-r--r--src/emacs.c9
-rw-r--r--src/fileio.c28
-rw-r--r--src/font.c15
-rw-r--r--src/fontset.c2
-rw-r--r--src/frame.c188
-rw-r--r--src/frame.h10
-rw-r--r--src/gmalloc.c8
-rw-r--r--src/gnutls.c14
-rw-r--r--src/gtkutil.c15
-rw-r--r--src/insdel.c21
-rw-r--r--src/keyboard.c14
-rw-r--r--src/lisp.h16
-rw-r--r--src/lread.c2
-rw-r--r--src/nsfns.m14
-rw-r--r--src/nsterm.m1
-rw-r--r--src/process.c354
-rw-r--r--src/process.h23
-rw-r--r--src/sysdep.c113
-rw-r--r--src/syssignal.h20
-rw-r--r--src/syswait.h7
-rw-r--r--src/term.c4
-rw-r--r--src/termchar.h20
-rw-r--r--src/textprop.c24
-rw-r--r--src/unexcoff.c6
-rw-r--r--src/vm-limit.c75
-rw-r--r--src/w32.c52
-rw-r--r--src/w32common.h2
-rw-r--r--src/w32fns.c19
-rw-r--r--src/w32proc.c43
-rw-r--r--src/w32term.c35
-rw-r--r--src/w32term.h2
-rw-r--r--src/window.c4
-rw-r--r--src/xdisp.c118
-rw-r--r--src/xfns.c14
-rw-r--r--src/xterm.c51
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 @@
12012-12-08 Eli Zaretskii <eliz@gnu.org>
2
3 * w32.c (unsetenv): Return 0 if the input string is too long.
4
52012-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
312012-12-08 Fabrice Popineau <fabrice.popineau@gmail.com>
32
33 * w32fns.c (emacs_abort): Don't do arithmetics on void pointers.
34
352012-12-08 Eli Zaretskii <eliz@gnu.org>
36
37 * w32.c (unsetenv, sys_putenv): New functions.
38
392012-12-08 Chong Yidong <cyd@gnu.org>
40
41 * editfns.c (Finsert_char): Make the error message more
42 informative (Bug#12992).
43
442012-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
722012-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
782012-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
862012-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
942012-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
1002012-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
1132012-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
1232012-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
1292012-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
1422012-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
1502012-12-04 Andreas Schwab <schwab@linux-m68k.org>
151
152 * callproc.c (Fcall_process): Fix specpdl nesting for asynchronous
153 processes.
154
1552012-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
1682012-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
2302012-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
2352012-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
2402012-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
2492012-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
2602012-12-03 Chong Yidong <cyd@gnu.org>
261
262 * fileio.c (Vauto_save_list_file_name): Doc fix.
263
2642012-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
2782012-12-03 Glenn Morris <rgm@gnu.org>
279
280 * data.c (Fboundp, Fsymbol_value): Doc fix re lexical-binding.
281
2822012-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
2982012-12-01 Paul Eggert <eggert@cs.ucla.edu>
299
300 * xterm.c (x_draw_image_relief): Remove unused locals (Bug#10500).
301
3022012-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
3092012-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
3142012-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
3252012-11-29 Paul Eggert <eggert@cs.ucla.edu>
326
327 * callproc.c (Fcall_process): Don't misreport vfork failure.
328
3292012-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
3402012-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
3452012-11-13 Kenichi Handa <handa@gnu.org>
346
347 * font.c (font_unparse_xlfd): Exclude special characters from the
348 generating XLFD name.
349
3502012-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
3682012-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
12012-11-25 Paul Eggert <eggert@cs.ucla.edu> 3782012-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
772void * 776void *
773xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, 777xpalloc (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
826void
827xputenv (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
822Lisp_Object 835Lisp_Object
823safe_alloca_unwind (Lisp_Object arg) 836safe_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
3374void
3375free_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
3366Lisp_Object 3387Lisp_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
1534static bool
1535candidate_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
1532DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0, 1542DEFUN ("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.
1534Buffers not visible in windows are preferred to visible buffers, unless 1544Buffers 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
90Lisp_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,
1963void 1961void
1964syms_of_bytecode (void) 1962syms_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. */
68static Lisp_Object Vtemp_file_name_pattern; 68static 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
72bool 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. */
80static pid_t synch_process_pid;
81
82/* If nonnegative, a file descriptor that has not been closed. */
83static int synch_process_fd;
84
85/* Block SIGCHLD. */
73 86
74/* Nonzero => this is a string explaining death of synchronous subprocess. */ 87static void
75const char *synch_process_death; 88block_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. */
78int synch_process_termsig;
79 97
80/* If synch_process_death is zero, 98static void
81 this is exit code of synchronous subprocess. */ 99unblock_child_signal (void)
82int 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. */ 108void
90static bool call_process_exited; 109record_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
92static Lisp_Object 125static Lisp_Object
93call_process_kill (Lisp_Object fdpid) 126call_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
105static Lisp_Object 146static Lisp_Object
106call_process_cleanup (Lisp_Object arg) 147call_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.
181usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) 215usage: (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
887static Lisp_Object 921static 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
508DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, 508DEFUN ("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.
510Note that if `lexical-binding' is in effect, this refers to the
511global 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
1049DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, 1051DEFUN ("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.
1053Note that if `lexical-binding' is in effect, this returns the
1054global 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
diff --git a/src/doc.c b/src/doc.c
index 1d3d1e64442..76008295add 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -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
79static Lisp_Object Qboundary; 79static 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. */
84static char const *initial_tz;
85
86/* True if the static variable tzvalbuf (defined in
87 set_time_zone_rule) is part of 'environ'. */
88static bool tzvalbuf_in_environ;
89
81 90
82void 91void
83init_editfns (void) 92init_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
817Lisp_Object 832Lisp_Object
818save_excursion_save (void) 833save_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
834Lisp_Object 854Lisp_Object
835save_excursion_restore (Lisp_Object info) 855save_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. */
2080static 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. */
2085static char *initial_tz;
2086
2087DEFUN ("set-time-zone-rule", Fset_time_zone_rule, Sset_time_zone_rule, 1, 1, 0, 2088DEFUN ("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.
2089If TZ is nil, use implementation-defined default time zone information. 2090If 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
2138static char set_time_zone_rule_tz1[] = "TZ=GMT+0";
2139static 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
2147void 2125void
2148set_time_zone_rule (const char *tzstring) 2126set_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
2360DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3, 2344DEFUN ("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.
2365Interactively, prompt for CHARACTER. You can specify CHARACTER in one 2350Interactively, prompt for CHARACTER. You can specify CHARACTER in one
2366of these ways: 2351of 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. */)
4806void 4791void
4807syms_of_editfns (void) 4792syms_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. */
538static char dump_tz[] = "UtC0"; 538static 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
460static ptrdiff_t 460static ptrdiff_t
461file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen) 461file_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
524static ptrdiff_t 531static ptrdiff_t
525directory_file_name (char *dst, char *src, ptrdiff_t srclen) 532directory_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.
5775This variable is initialized automatically from `auto-save-list-file-prefix' 5787This variable is initialized automatically from `auto-save-list-file-prefix'
5776shortly after Emacs reads your `.emacs' file, if you have not yet given it 5788shortly after Emacs reads your init file, if you have not yet given it
5777a non-nil value. */); 5789a 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
902static Lisp_Object
903candidate_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
906static Lisp_Object 945static Lisp_Object
907next_frame (Lisp_Object frame, Lisp_Object minibuf) 946next_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
980static Lisp_Object 971static Lisp_Object
981prev_frame (Lisp_Object frame, Lisp_Object minibuf) 972prev_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);
1263extern void x_make_frame_visible (struct frame *f); 1255extern void x_make_frame_visible (struct frame *f);
1264extern void x_make_frame_invisible (struct frame *f); 1256extern void x_make_frame_invisible (struct frame *f);
1265extern void x_iconify_frame (struct frame *f); 1257extern void x_iconify_frame (struct frame *f);
1266extern int x_char_width (struct frame *f);
1267extern int x_char_height (struct frame *f);
1268extern int x_pixel_width (struct frame *f); 1258extern int x_pixel_width (struct frame *f);
1269extern int x_pixel_height (struct frame *f); 1259extern int x_pixel_height (struct frame *f);
1270extern void x_set_frame_alpha (struct frame *f); 1260extern 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
1656int 1648int
1657posix_memalign (void **memptr, size_t alignment, size_t size) 1649posix_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
816static void
817my_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
1768void 1768void
1769modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, 1769modify_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
1120Lisp_Object command_loop_1 (void);
1121static Lisp_Object command_loop_2 (Lisp_Object); 1120static Lisp_Object command_loop_2 (Lisp_Object);
1122static Lisp_Object top_level_1 (Lisp_Object); 1121static 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
1157Lisp_Object 1156static Lisp_Object
1158command_loop_2 (Lisp_Object ignore) 1157command_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
1175Lisp_Object 1174static Lisp_Object
1176top_level_1 (Lisp_Object ignore) 1175top_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);
2796extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); 2797extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);
2797extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, 2798extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t,
2798 ptrdiff_t, ptrdiff_t, bool); 2799 ptrdiff_t, ptrdiff_t, bool);
2799extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, bool); 2800extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool);
2800extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); 2801extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
2801extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); 2802extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
2802extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, 2803extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t,
@@ -2963,6 +2964,7 @@ extern Lisp_Object make_float (double);
2963extern void display_malloc_warning (void); 2964extern void display_malloc_warning (void);
2964extern ptrdiff_t inhibit_garbage_collection (void); 2965extern ptrdiff_t inhibit_garbage_collection (void);
2965extern Lisp_Object make_save_value (void *, ptrdiff_t); 2966extern Lisp_Object make_save_value (void *, ptrdiff_t);
2967extern void free_save_value (Lisp_Object);
2966extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 2968extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
2967extern void free_marker (Lisp_Object); 2969extern void free_marker (Lisp_Object);
2968extern void free_cons (struct Lisp_Cons *); 2970extern void free_cons (struct Lisp_Cons *);
@@ -3393,7 +3395,6 @@ extern void syms_of_doc (void);
3393extern int read_bytecode_char (bool); 3395extern int read_bytecode_char (bool);
3394 3396
3395/* Defined in bytecode.c. */ 3397/* Defined in bytecode.c. */
3396extern Lisp_Object Qbytecode;
3397extern void syms_of_bytecode (void); 3398extern void syms_of_bytecode (void);
3398extern struct byte_stack *byte_stack_list; 3399extern 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);
3593extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); 3594extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
3594 3595
3595extern char *xstrdup (const char *); 3596extern char *xstrdup (const char *);
3597extern void xputenv (const char *);
3596 3598
3597extern char *egetenv (const char *); 3599extern 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
2245int 2245int
2246x_char_width (struct frame *f)
2247{
2248 return FRAME_COLUMN_WIDTH (f);
2249}
2250
2251
2252int
2253x_char_height (struct frame *f)
2254{
2255 return FRAME_LINE_HEIGHT (f);
2256}
2257
2258
2259int
2260x_screen_planes (struct frame *f) 2246x_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. */
781static Lisp_Object deleted_pid_list; 785static Lisp_Object deleted_pid_list;
782#endif 786
787void
788record_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
784DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, 796DEFUN ("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
5700static void 5670static void
5701process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group, 5671process_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. */
5921static int
5922abbr_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
5949DEFUN ("signal-process", Fsignal_process, Ssignal_process, 5940DEFUN ("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
6093DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, 6000DEFUN ("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
6177static bool 6084 - deleted_pid_list, for child processes invisible to Lisp,
6178process_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
6223void 6130static void
6224record_child_status_change (pid_t pid, int w) 6131handle_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
6320static void
6321handle_child_signal (int sig)
6322{
6323 record_child_status_change (-1, 0);
6324} 6188}
6325 6189
6326static void 6190static 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
6335static Lisp_Object 6197static 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. */
190extern 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. */
196extern const char *synch_process_death;
197
198/* Nonzero => this is the signal number that terminated the subprocess. */
199extern int synch_process_termsig;
200
201/* If synch_process_death is zero,
202 this is exit code of synchronous subprocess. */
203extern 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. */
207extern int inhibit_sentinels; 190extern int inhibit_sentinels;
@@ -215,6 +198,12 @@ extern Lisp_Object QCspeed;
215extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; 198extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
216extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; 199extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
217 200
201/* Defined in callproc.c. */
202
203extern void record_kill_process (struct Lisp_Process *);
204
205/* Defined in process.c. */
206
218extern Lisp_Object list_system_processes (void); 207extern Lisp_Object list_system_processes (void);
219extern Lisp_Object system_process_attributes (Lisp_Object); 208extern 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
269static void 269/* Wait for the subprocess with process id CHILD to terminate or change status.
270wait_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. */
278static pid_t
279get_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. */
297void 318void
298wait_for_termination (pid_t pid) 319wait_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.
304void 325 Termination counts as a change of status.
305interruptible_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. */
333pid_t
334child_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 *);
428void 457void
429sys_suspend (void) 458sys_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
573static void 595static 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. */
55extern void record_child_status_change (pid_t, int); 56extern void record_deleted_pid (pid_t);
56 57
57/* Defined in sysdep.c. */ 58/* Defined in sysdep.c. */
58extern void wait_for_termination (pid_t); 59extern void wait_for_termination (pid_t, int *, bool);
59extern void interruptible_wait_for_termination (pid_t); 60extern 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
90static void
91modify_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;
44static size_t lim_data; 44static size_t lim_data;
45 45
46 46
47#if defined (HAVE_GETRLIMIT) && defined (RLIMIT_AS) 47#ifdef HAVE_GETRLIMIT
48static void
49get_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
64static void 53static void
65get_lim_data (void) 54get_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
101void 79void
102get_lim_data (void) 80get_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 */
139static void
140get_lim_data (void)
141{
142 lim_data = vlimit (LIM_DATA, -1);
143}
144#endif /* not MSDOS */
145
146#else /* BSD4_2 || CYGWIN */
147
148static void
149get_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
diff --git a/src/w32.c b/src/w32.c
index c8e16dfaa94..b6bb653369d 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -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. */
1548int
1549unsetenv (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. */
1577int
1578sys_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
1541LPBYTE 1593LPBYTE
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
35extern SYSTEM_INFO sysinfo_cache; 35extern SYSTEM_INFO sysinfo_cache;
36extern OSVERSIONINFO osinfo_cache; 36extern OSVERSIONINFO osinfo_cache;
37extern unsigned long syspage_mask; 37extern DWORD_PTR syspage_mask;
38 38
39extern int w32_major_version; 39extern int w32_major_version;
40extern int w32_minor_version; 40extern 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);
82void globals_of_w32fns (void); 82void globals_of_w32fns (void);
83 83
84extern void free_frame_menubar (struct frame *); 84extern void free_frame_menubar (struct frame *);
85extern double atof (const char *);
86extern int w32_console_toggle_lock_key (int, Lisp_Object); 85extern int w32_console_toggle_lock_key (int, Lisp_Object);
87extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); 86extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
88extern void w32_free_menu_strings (HWND); 87extern 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. */
224OSVERSIONINFO osinfo_cache; 223OSVERSIONINFO osinfo_cache;
225 224
226unsigned long syspage_mask = 0; 225DWORD_PTR syspage_mask = 0;
227 226
228/* The major and minor versions of NT. */ 227/* The major and minor versions of NT. */
229int w32_major_version; 228int w32_major_version;
@@ -4867,18 +4866,6 @@ x_pixel_height (register struct frame *f)
4867} 4866}
4868 4867
4869int 4868int
4870x_char_width (register struct frame *f)
4871{
4872 return FRAME_COLUMN_WIDTH (f);
4873}
4874
4875int
4876x_char_height (register struct frame *f)
4877{
4878 return FRAME_LINE_HEIGHT (f);
4879}
4880
4881int
4882x_screen_planes (register struct frame *f) 4869x_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. */
6038static UINT CALLBACK 6025static UINT_PTR CALLBACK
6039file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 6026file_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)
1952static void 1952static void
1953x_draw_image_relief (struct glyph_string *s) 1953x_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);
217extern void x_make_frame_visible (struct frame *f); 217extern void x_make_frame_visible (struct frame *f);
218extern void x_make_frame_invisible (struct frame *f); 218extern void x_make_frame_invisible (struct frame *f);
219extern void x_iconify_frame (struct frame *f); 219extern void x_iconify_frame (struct frame *f);
220extern int x_char_width (struct frame *f);
221extern int x_char_height (struct frame *f);
222extern int x_pixel_width (struct frame *f); 220extern int x_pixel_width (struct frame *f);
223extern int x_pixel_height (struct frame *f); 221extern int x_pixel_height (struct frame *f);
224extern void x_set_frame_alpha (struct frame *f); 222extern 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
10894static int 10894static int
10895buffer_shared_and_changed (void) 10895buffer_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
10903static int 10906static int
10904window_outdated (struct window *w) 10907window_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
10930static int
10931mode_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
12981static void
12982ensure_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 \
12972do { if (! polling_stopped_here) stop_polling (); \ 12989do { 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
13766static Lisp_Object 13768static Lisp_Object
13767unwind_redisplay (Lisp_Object old_frame) 13769unwind_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
3851int
3852x_char_width (register struct frame *f)
3853{
3854 return FRAME_COLUMN_WIDTH (f);
3855}
3856
3857int
3858x_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)
2255static void 2257static void
2256x_draw_image_relief (struct glyph_string *s) 2258x_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. */