aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Tromey2013-07-12 18:44:13 -0600
committerTom Tromey2013-07-12 18:44:13 -0600
commitb34a529f177a6ea32da5cb1254f91bf9d71838db (patch)
tree477131abc15d3107b30b635223d87a22550b480b /src
parente6f63071a3f7721f55220514b6d9a8ee8c1232d8 (diff)
parent5e301d7651c0691bb2bc7f3fbe711fdbe26ac471 (diff)
downloademacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.tar.gz
emacs-b34a529f177a6ea32da5cb1254f91bf9d71838db.zip
Merge from trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog308
-rw-r--r--src/alloc.c2
-rw-r--r--src/atimer.c2
-rw-r--r--src/buffer.c5
-rw-r--r--src/bytecode.c7
-rw-r--r--src/callproc.c115
-rw-r--r--src/dbusbind.c8
-rw-r--r--src/dired.c2
-rw-r--r--src/dispextern.h7
-rw-r--r--src/dispnew.c6
-rw-r--r--src/emacs.c89
-rw-r--r--src/eval.c71
-rw-r--r--src/fileio.c139
-rw-r--r--src/filelock.c20
-rw-r--r--src/fns.c26
-rw-r--r--src/frame.c2
-rw-r--r--src/gnutls.h2
-rw-r--r--src/image.c10
-rw-r--r--src/inotify.c33
-rw-r--r--src/keyboard.c2
-rw-r--r--src/lisp.h25
-rw-r--r--src/lread.c96
-rw-r--r--src/makefile.w32-in2
-rw-r--r--src/nsfns.m6
-rw-r--r--src/nsmenu.m6
-rw-r--r--src/nsterm.m16
-rw-r--r--src/print.c13
-rw-r--r--src/process.c157
-rw-r--r--src/process.h8
-rw-r--r--src/profiler.c12
-rw-r--r--src/regex.c33
-rw-r--r--src/regex.h46
-rw-r--r--src/search.c2
-rw-r--r--src/sheap.c4
-rw-r--r--src/sound.c2
-rw-r--r--src/syntax.c272
-rw-r--r--src/syntax.h296
-rw-r--r--src/sysdep.c235
-rw-r--r--src/systime.h23
-rw-r--r--src/term.c51
-rw-r--r--src/termcap.c108
-rw-r--r--src/termhooks.h2
-rw-r--r--src/terminal.c4
-rw-r--r--src/undo.c7
-rw-r--r--src/unexaix.c19
-rw-r--r--src/unexcoff.c15
-rw-r--r--src/unexcw.c4
-rw-r--r--src/unexelf.c6
-rw-r--r--src/unexhp9k800.c4
-rw-r--r--src/unexmacosx.c4
-rw-r--r--src/w32.c15
-rw-r--r--src/w32.h2
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xrdb.c5
-rw-r--r--src/xsettings.c6
-rw-r--r--src/xterm.c125
56 files changed, 1453 insertions, 1037 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b95488c1e70..60e7e376729 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,309 @@
12013-07-13 Paul Eggert <eggert@cs.ucla.edu>
2
3 Don't lose top specpdl entry when memory is exhausted.
4 * eval.c (grow_specpdl): Increment specpdl top by 1 and check for
5 specpdl overflow here, to simplify callers; all callers changed.
6 Always reserve an unused entry at the stack top; this avoids
7 losing the top entry's information when memory is exhausted.
8
92013-07-12 Paul Eggert <eggert@cs.ucla.edu>
10
11 Clean up errno reporting and fix some errno-reporting bugs.
12 * callproc.c (Fcall_process):
13 * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
14 * process.c (create_process, Fmake_network_process):
15 * unexaix.c (report_error):
16 * unexcoff.c (report_error):
17 Be more careful about reporting the errno of failed operations.
18 The code previously reported the wrong errno sometimes.
19 Also, prefer report_file_errno to setting errno + report_file_error.
20 (Fcall_process): Look at openp return value rather than at path,
21 as that's a bit faster and clearer when there's a numeric predicate.
22 * fileio.c (report_file_errno): New function, with most of the
23 old contents of report_file_error.
24 (report_file_error): Use it.
25 (Ffile_exists_p, Ffile_accessible_directory_p):
26 Set errno to 0 when it is junk.
27 * fileio.c (Faccess_file):
28 * image.c (x_create_bitmap_from_file):
29 Use faccessat rather than opening the file, to avoid the hassle of
30 having a file descriptor open.
31 * lisp.h (report_file_errno): New decl.
32 * lread.c (Flocate_file_internal): File descriptor 0 is valid, too.
33
34 Minor EBADF fixes.
35 * process.c (create_process, wait_reading_process_output) [AIX]:
36 Remove obsolete SIGHUP-related code, as Emacs no longer disables
37 SIGHUP, so EBADF is no longer acceptable here (it wouldn't work in
38 a multithreaded environment anyway).
39 * sysdep.c (emacs_close): It's not dangerous to invoke emacs_close (-1).
40
412013-07-12 Andreas Schwab <schwab@linux-m68k.org>
42
43 * image.c (x_find_image_file): Don't close a remote file handle.
44
452013-07-12 Paul Eggert <eggert@cs.ucla.edu>
46
47 Fix races with threads and file descriptors.
48 * callproc.c (Fcall_process_region):
49 * dired.c (open_directory):
50 * emacs.c (main, Fdaemon_initialized):
51 * image.c (x_find_image_file):
52 * inotify.c (Finotify_rm_watch):
53 * lread.c (Flocate_file_internal):
54 * process.c (Fnetwork_interface_list, Fnetwork_interface_info):
55 * term.c (term_mouse_moveto, init_tty):
56 * termcap.c (tgetent):
57 * unexaix.c, unexcoff.c (report_error, report_error_1, adjust_lnnoptrs)
58 * unexaix.c, unexcoff.c, unexcw.c, unexelf.c (unexec):
59 * unexhp9k800.c, unexmacosx.c (unexec):
60 * callproc.c (Fcall_process_region):
61 Use emacs_close, not close.
62 * sysdep.c (POSIX_CLOSE_RESTART, posix_close) [!POSIX_CLOSE_RESTART]:
63 New macro and function, which emulates the POSIX_CLOSE_RESTART macro
64 and posix_close function on current platforms (which all lack them).
65 (emacs_close): Use it. This should fix the races on GNU/Linux and
66 on AIX and on future platforms that support POSIX_CLOSE_RESTART,
67 and it should avoid closing random victim file descriptors on
68 other platforms.
69
702013-07-11 Paul Eggert <eggert@cs.ucla.edu>
71
72 * inotify.c (uninitialized): Remove. All uses replaced by -1.
73 (Finotify_add_watch): Simplify, since -1 means uninitialized now.
74 Touch up doc a bit.
75
76 * eval.c (backtrace_function, backtrace_args): Now EXTERNALLY_VISIBLE.
77 This is for .gdbinit xbacktrace.
78
79 * sysdep.c, term.c, termcap.c, terminal.c: Integer-related minor fixes.
80 * sysdep.c (emacs_get_tty): Return void, since nobody uses the value.
81 (emacs_set_tty): Now static.
82 * sysdep.c (emacs_set_tty, tabs_safe_p, emacs_close):
83 * term.c (tty_capable_p, tty_default_color_capabilities)
84 (get_tty_terminal, term_mouse_movement)
85 (handle_one_term_event, init_tty, maybe_fatal):
86 * termcap.c (tgetst1, struct termcap_buffer, valid_filename_p)
87 (tgetent, scan_file, name_match, compare_contin):
88 * terminal.c (get_terminal):
89 Use bool for boolean.
90 * sysdep.c (init_system_name): Don't overflow stack on huge hostname.
91 Prefer char to unsigned char if either will do.
92 * term.c (OUTPUT, turn_on_face): Omit unnecessary casts to int.
93 (tty_write_glyphs): Prefer int to unsigned.
94 (produce_glyphless_glyph): Remove 2nd (unused) int arg.
95 All callers changed.
96 * termcap.c (tprint, main) [TEST]: Remove non-working test.
97
982013-07-10 Paul Eggert <eggert@cs.ucla.edu>
99
100 Port to C89.
101 * bytecode.c (BYTE_CODE_THREADED): Do not define if __STRICT_ANSI__.
102 (B__dummy__): New dummy symbol, to pacify C89.
103 * dbusbind.c (XD_DEBUG_MESSAGE): Omit debugging on C89 hosts, since
104 they can't grok varargs macros.
105 * dispnew.c (add_window_display_history)
106 (add_frame_display_history):
107 * print.c (print_object):
108 * xdisp.c (debug_method_add):
109 Use %p printf format only for void pointers.
110 * emacs.c (usage_message): New constant, replacing ...
111 (USAGE1, USAGE2, USAGE3): Remove; they were too long for C89.
112 (main): Adjust to usage reorg.
113 * fns.c (syms_of_fns):
114 * profiler.c (syms_of_profiler):
115 Don't use non-constant struct initializers.
116 * gnutls.h (gnutls_initstage_t):
117 * lisp.h (enum Lisp_Fwd_Type):
118 * lread.c (lisp_file_lexically_bound_p):
119 * xsettings.c (anonymous enum):
120 Remove trailing comma.
121 * xsettings.c (apply_xft_settings): Use %f, not %lf; %lf is a C99ism.
122 * lisp.h (ENUM_BF): Use unsigned if pedantic.
123 (DEFUN_FUNCTION_INIT): New macro, that falls back on a cast if pre-C99.
124 (DEFUN): Use it.
125 * regex.c (const_re_char): New type, to pacify strict C89.
126 All uses of 'const re_char' replaced to use it.
127 * regex.h (_Restrict_): Rename from __restrict, to avoid clash
128 with glibc when strict C89. This change is imported from gnulib.
129 All uses changed.
130 (_Restrict_arr_): Rename from __restrict_arr, similarly.
131 * sysdep.c (time_from_jiffies) [!HAVE_LONG_LONG_INT]:
132 Omit GNU_LINUX implementation, since it requires long long.
133 * xterm.c (x_draw_underwave):
134 Do not assume the traditional order of struct's members.
135 (x_term_init): Rewrite to avoid the need for non-constant structure
136 initializers.
137
138 Syntax cleanup, mostly replacing macros with functions.
139` This removes the need for the syntax_temp hack.
140 * search.c: Include syntax.h after buffer.h, since syntax.h uses BVAR.
141 * syntax.c (SYNTAX_INLINE): New macro.
142 (SYNTAX_FLAGS_COMSTART_FIRST, SYNTAX_FLAGS_COMSTART_SECOND)
143 (SYNTAX_FLAGS_COMEND_FIRST, SYNTAX_FLAGS_COMEND_SECOND)
144 (SYNTAX_FLAGS_PREFIX, SYNTAX_FLAGS_COMMENT_STYLEB)
145 (SYNTAX_FLAGS_COMMENT_STYLEC, SYNTAX_FLAGS_COMMENT_STYLEC2)
146 (SYNTAX_FLAGS_COMMENT_NESTED, SYNTAX_FLAGS_COMMENT_STYLE)
147 (SYNTAX_COMEND_FIRST): Now functions, not macros.
148 (ST_COMMENT_STYLE, ST_STRING_STYLE, INTERVALS_AT_ONCE):
149 Now constants, not macros.
150 (syntax_temp) [!__GNUC__]: Remove.
151 (SYNTAX_PREFIX): Remove; all uses replaced by syntax_prefix_flag_p.
152 (syntax_prefix_flag_p): Move implementation of SYNTAX_PREFIX here.
153 (SET_RAW_SYNTAX_ENTRY, SET_RAW_SYNTAX_ENTRY_RANGE, SYNTAX_MATCH)
154 (SETUP_SYNTAX_TABLE, SETUP_SYNTAX_TABLE_FOR_OBJECT):
155 Move here from syntax.h; now functions, not macros. Except for the
156 last function, these are static since only syntax.c uses them.
157 (syntax_multibyte): Rename from SYNTAX_WITH_MULTIBYTE_CHECK.
158 All uses changed. Now a function, not a macro; use this fact
159 to simplify the code.
160 (scan_lists, scan_sexps_forward): Remove workarounds for ancient
161 compiler bugs; no longer relevant.
162 * syntax.h: Use INLINE_HEADER_BEGIN, INLINE_HEADER_END.
163 (SYNTAX_INLINE): New macro.
164 (struct gl_state_s, gl_state): Move earlier, so that it's in scope
165 for the new functions. Use bool for boolean member.
166 (SYNTAX_ENTRY, SYNTAX, SYNTAX_WITH_FLAGS, SYNTAX_MATCH)
167 (SYNTAX_TABLE_BYTE_TO_CHAR, UPDATE_SYNTAX_TABLE_FORWARD)
168 (UPDATE_SYNTAX_TABLE_BACKWARD, UPDATE_SYNTAX_TABLE)
169 (SETUP_BUFFER_SYNTAX_TABLE):
170 Now extern inline functions, not macros.
171 (CURRENT_SYNTAX_TABLE, SYNTAX_ENTRY_INT):
172 Remove; all uses replaced by implementation.
173 (syntax_temp) [!__GNUC__]: Remove decl.
174 (SETUP_SYNTAX_TABLE_FOR_OBJECT): New decl.
175
1762013-07-10 Jan Djärv <jan.h.d@swipnet.se>
177
178 * emacs.c (main): Fix syntax error.
179
1802013-07-10 Paul Eggert <eggert@cs.ucla.edu>
181
182 Timestamp fixes for undo (Bug#14824).
183 * atimer.c (schedule_atimer):
184 * fileio.c (Ffile_newer_than_file_p):
185 Minor cleanup: use EMACS_TIME_LT so that we can remove EMACS_TIME_GT.
186 * buffer.c (buffer-undo-list): Document (t . 0) and (t . -1).
187 * fileio.c (Fclear_visited_file_modtime): Move to lisp/files.el.
188 (syms_of_fileio): Remove Sclear_visited_file_name.
189 (Fvisited_file_modtime): Return -1, not (-1 ...), when the visited
190 file doesn't exist; this avoids an ambiguity with negative timestamps.
191 (Fset_visited_file_modtime): Accept -1 and 0 as time-list arg.
192 * systime.h (make_emacs_time, invalid_emacs_time):
193 Don't assume struct timespec layout; POSIX doesn't guarantee it.
194 (EMACS_TIME_NE, EMACS_TIME_GT, EMACS_TIME_GE): Remove.
195 * undo.c (record_first_change): Push (visited-file-modtime) onto
196 undo list rather than reimplementing it by hand, incorrectly.
197
1982013-07-09 Ken Brown <kbrown@cornell.edu>
199
200 * sheap.c (STATIC_HEAP_SIZE) [__x86_64__]: Increase to 18MB.
201
2022013-07-09 Juanma Barranquero <lekktu@gmail.com>
203
204 * makefile.w32-in ($(BLD)/emacs.$(O), $(BLD)/sysdep.$(O)): Update.
205
2062013-07-09 Paul Eggert <eggert@cs.ucla.edu>
207
208 Handle errno and exit status a bit more carefully.
209 * callproc.c (child_setup) [!DOS_NT]: Don't try to stuff an error
210 number into an exit status. Instead, use EXIT_CANCELED.
211 (child_setup) [!MSDOS]: Avoid possible deadlock with vfork.
212 * callproc.c (relocate_fd):
213 * emacs.c (close_output_streams, main):
214 * process.c (create_process):
215 * sysdep.c (sys_subshell) [!DOS_NT || !WINDOWSNT]:
216 Use emacs_perror for simplicity.
217 * callproc.c (relocate_fd, main):
218 * sysdep.c (sys_subshell):
219 Exit with EXIT_CANCELED etc., not 1, when exec setup fails.
220 (shut_down_emacs): Use emacs_write, not write.
221 * emacs.c, sysdep.c: Don't include <ignore-value.h>.
222 * fileio.c (Fcopy_file, e_write):
223 * nsterm.m (ns_select):
224 * process.c (send_process):
225 * sound.c (vox_write):
226 Use emacs_write_sig, not emacs_write.
227 * lisp.h (emacs_write_sig, emacs_perror): New decls.
228 * process.h (EXIT_CANCELED), EXIT_CANNOT_INVOKE, EXIT_ENOENT):
229 New constants.
230 * sysdep.c (emacs_backtrace): Use emacs_write, not ignore_value
231 of write.
232 (emacs_full_write): New function.
233 (emacs_write): Rewrite to use it.
234 (emacswrite_sig, emacs_perror): New functions.
235 * xrdb.c (fatal): Don't invoke perror, since errno might be garbage.
236
2372013-07-08 Magnus Henoch <magnus.henoch@gmail.com> (tiny change).
238
239 * image.c (imagemagick_load_image): Do not use MagickExportImagePixels
240 on NS even if it is present. Pixmap on NS is a void*.
241
2422013-07-07 Paul Eggert <eggert@cs.ucla.edu>
243
244 Port to Ubuntu 10 (Bug#14803).
245 Problem reported by T.V. Raman.
246 * process.c (close_on_exec, accept4, process_socket):
247 Define these if !HAVE_ACCEPT4, not if !SOCK_CLOEXEC.
248
2492013-07-07 Eli Zaretskii <eliz@gnu.org>
250
251 * w32.c (sys_dup): Declare prototype.
252
253 * filelock.c:
254 * emacs.c:
255 * callproc.c [WINDOWSNT]: Include sys/socket.h.
256
2572013-07-07 Paul Eggert <eggert@cs.ucla.edu>
258
259 Make file descriptors close-on-exec when possible (Bug#14803).
260 This simplifies Emacs a bit, since it no longer needs to worry
261 about closing file descriptors by hand in some cases.
262 It also fixes some unlikely races. Not all such races, as
263 libraries often open files internally without setting
264 close-on-exec, but it's an improvement.
265 * alloc.c (valid_pointer_p) [!WINDOWSNT]:
266 * callproc.c (Fcall_process) [!MSDOS]:
267 * emacs.c (main) [!DOS_NT]:
268 * nsterm.m (ns_term_init):
269 * process.c (create_process):
270 Use 'pipe2' with O_CLOEXEC instead of 'pipe'.
271 * emacs.c (Fcall_process_region) [HAVE_MKOSTEMP]:
272 * filelock.c (create_lock_file) [HAVE_MKOSTEMP]:
273 Prefer mkostemp with O_CLOEXEC to mkstemp.
274 * callproc.c (relocate_fd) [!WINDOWSNT]:
275 * emacs.c (main): Use F_DUPFD_CLOEXEC, not plain F_DUPFD.
276 No need to use fcntl (..., F_SETFD, FD_CLOEXEC), since we're
277 now using pipe2.
278 * filelock.c (create_lock_file) [! HAVE_MKOSTEMP]:
279 Make the resulting file descriptor close-on-exec.
280 * lisp.h, lread.c, process.c (close_load_descs, close_process_descs):
281 * lread.c (load_descriptor_list, load_descriptor_unwind):
282 Remove; no longer needed. All uses removed.
283 * process.c (SOCK_CLOEXEC): Define to 0 if not supplied by system.
284 (close_on_exec, accept4, process_socket) [!SOCK_CLOEXEC]:
285 New functions.
286 (socket) [!SOCK_CLOEXEC]: Supply a substitute.
287 (Fmake_network_process, Fnetwork_interface_list):
288 (Fnetwork_interface_info, server_accept_connection):
289 Make newly-created socket close-on-exec.
290 * sysdep.c (emacs_open, emacs_fopen):
291 Make new-created descriptor close-on-exec.
292 * w32.c (fcntl): Support F_DUPFD_CLOEXEC well enough for Emacs.
293 * w32.c, w32.h (pipe2): Rename from 'pipe', with new flags arg.
294
2952013-07-07 Jan Djärv <jan.h.d@swipnet.se>
296
297 * nsterm.m (sendEvent:): Propagate keyboard events to modal windows
298 for NS_IMPL_GNUSTEP.
299
3002013-07-07 Paul Eggert <eggert@cs.ucla.edu>
301
302 Fix openp errno handling.
303 * callproc.c (Fcall_process): Preserve openp errno around close.
304 * lread.c (openp): Set errno when returning -1, as some callers
305 expect this.
306
12013-07-06 Jan Djärv <jan.h.d@swipnet.se> 3072013-07-06 Jan Djärv <jan.h.d@swipnet.se>
2 308
3 * nsterm.m (sendEvent:): Handle NSAPP_DATA2_RUNFILEDIALOG. 309 * nsterm.m (sendEvent:): Handle NSAPP_DATA2_RUNFILEDIALOG.
@@ -655,7 +961,7 @@
655 (VALMASK): Also a constant, for benefit of old GDB. 961 (VALMASK): Also a constant, for benefit of old GDB.
656 (LISP_INT_TAG_P): Remove; no longer needed as the only caller 962 (LISP_INT_TAG_P): Remove; no longer needed as the only caller
657 is INTEGERP, which can fold it in. 963 is INTEGERP, which can fold it in.
658 (XLI, XIL, XHASH, XTYPE,XINT, XFASTINT, XUINT) 964 (XLI, XIL, XHASH, XTYPE, XINT, XFASTINT, XUINT)
659 (make_number, XPNTR, XUNTAG, EQ, XCONS, XVECTOR, XSTRING, XSYMBOL) 965 (make_number, XPNTR, XUNTAG, EQ, XCONS, XVECTOR, XSTRING, XSYMBOL)
660 (XFLOAT, XPROCESS, XWINDOW, XTERMINAL, XSUBR, XBUFFER, XCHAR_TABLE) 966 (XFLOAT, XPROCESS, XWINDOW, XTERMINAL, XSUBR, XBUFFER, XCHAR_TABLE)
661 (XSUB_CHAR_TABLE, XBOOL_VECTOR, make_lisp_ptr, CHECK_TYPE) 967 (XSUB_CHAR_TABLE, XBOOL_VECTOR, make_lisp_ptr, CHECK_TYPE)
diff --git a/src/alloc.c b/src/alloc.c
index 230b3b614d7..6ef6af1e3a1 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4750,7 +4750,7 @@ valid_pointer_p (void *p)
4750 Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may 4750 Unfortunately, we cannot use NULL_DEVICE here, as emacs_write may
4751 not validate p in that case. */ 4751 not validate p in that case. */
4752 4752
4753 if (pipe (fd) == 0) 4753 if (pipe2 (fd, O_CLOEXEC) == 0)
4754 { 4754 {
4755 bool valid = emacs_write (fd[1], (char *) p, 16) == 16; 4755 bool valid = emacs_write (fd[1], (char *) p, 16) == 16;
4756 emacs_close (fd[1]); 4756 emacs_close (fd[1]);
diff --git a/src/atimer.c b/src/atimer.c
index 73c7aa5686b..bb5294670d3 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -336,7 +336,7 @@ schedule_atimer (struct atimer *t)
336 struct atimer *a = atimers, *prev = NULL; 336 struct atimer *a = atimers, *prev = NULL;
337 337
338 /* Look for the first atimer that is ripe after T. */ 338 /* Look for the first atimer that is ripe after T. */
339 while (a && EMACS_TIME_GT (t->expiration, a->expiration)) 339 while (a && EMACS_TIME_LT (a->expiration, t->expiration))
340 prev = a, a = a->next; 340 prev = a, a = a->next;
341 341
342 /* Insert T in front of the atimer found, if any. */ 342 /* Insert T in front of the atimer found, if any. */
diff --git a/src/buffer.c b/src/buffer.c
index 2555b5c17ac..19e3982a8a4 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -6096,6 +6096,11 @@ and is the visited file's modification time, as of that time. If the
6096modification time of the most recent save is different, this entry is 6096modification time of the most recent save is different, this entry is
6097obsolete. 6097obsolete.
6098 6098
6099An entry (t . 0) means means the buffer was previously unmodified but
6100its time stamp was unknown because it was not associated with a file.
6101An entry (t . -1) is similar, except that it means the buffer's visited
6102file did not exist.
6103
6099An entry (nil PROPERTY VALUE BEG . END) indicates that a text property 6104An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
6100was modified between BEG and END. PROPERTY is the property name, 6105was modified between BEG and END. PROPERTY is the property name,
6101and VALUE is the old value. 6106and VALUE is the old value.
diff --git a/src/bytecode.c b/src/bytecode.c
index a22be984b44..f186f7d1bc3 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -59,7 +59,8 @@ by Hallvard:
59 indirect threaded, using GCC's computed goto extension. This code, 59 indirect threaded, using GCC's computed goto extension. This code,
60 as currently implemented, is incompatible with BYTE_CODE_SAFE and 60 as currently implemented, is incompatible with BYTE_CODE_SAFE and
61 BYTE_CODE_METER. */ 61 BYTE_CODE_METER. */
62#if defined (__GNUC__) && !defined (BYTE_CODE_SAFE) && !defined (BYTE_CODE_METER) 62#if (defined __GNUC__ && !defined __STRICT_ANSI__ \
63 && !defined BYTE_CODE_SAFE && !defined BYTE_CODE_METER)
63#define BYTE_CODE_THREADED 64#define BYTE_CODE_THREADED
64#endif 65#endif
65 66
@@ -285,8 +286,10 @@ enum byte_code_op
285 286
286#ifdef BYTE_CODE_SAFE 287#ifdef BYTE_CODE_SAFE
287 Bscan_buffer = 0153, /* No longer generated as of v18. */ 288 Bscan_buffer = 0153, /* No longer generated as of v18. */
288 Bset_mark = 0163 /* this loser is no longer generated as of v18 */ 289 Bset_mark = 0163, /* this loser is no longer generated as of v18 */
289#endif 290#endif
291
292 B__dummy__ = 0 /* Pacify C89. */
290}; 293};
291 294
292/* Whether to maintain a `top' and `bottom' field in the stack frame. */ 295/* Whether to maintain a `top' and `bottom' field in the stack frame. */
diff --git a/src/callproc.c b/src/callproc.c
index 6de8113dc14..30f9dc58d46 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31 31
32#ifdef WINDOWSNT 32#ifdef WINDOWSNT
33#define NOMINMAX 33#define NOMINMAX
34#include <sys/socket.h> /* for fcntl */
34#include <windows.h> 35#include <windows.h>
35#include "w32.h" 36#include "w32.h"
36#define _P_NOWAIT 1 /* from process.h */ 37#define _P_NOWAIT 1 /* from process.h */
@@ -418,9 +419,10 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
418 default_output_mode); 419 default_output_mode);
419 if (fd_output < 0) 420 if (fd_output < 0)
420 { 421 {
422 int open_errno = errno;
421 output_file = DECODE_FILE (output_file); 423 output_file = DECODE_FILE (output_file);
422 report_file_error ("Opening process output file", 424 report_file_errno ("Opening process output file",
423 Fcons (output_file, Qnil)); 425 Fcons (output_file, Qnil), open_errno);
424 } 426 }
425 if (STRINGP (error_file) || NILP (error_file)) 427 if (STRINGP (error_file) || NILP (error_file))
426 output_to_buffer = 0; 428 output_to_buffer = 0;
@@ -429,16 +431,19 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
429 /* Search for program; barf if not found. */ 431 /* Search for program; barf if not found. */
430 { 432 {
431 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 433 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
434 int ok;
432 435
433 GCPRO4 (infile, buffer, current_dir, error_file); 436 GCPRO4 (infile, buffer, current_dir, error_file);
434 openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK)); 437 ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK));
435 UNGCPRO; 438 UNGCPRO;
439 if (ok < 0)
440 {
441 int openp_errno = errno;
442 emacs_close (filefd);
443 report_file_errno ("Searching for program",
444 Fcons (args[0], Qnil), openp_errno);
445 }
436 } 446 }
437 if (NILP (path))
438 {
439 emacs_close (filefd);
440 report_file_error ("Searching for program", Fcons (args[0], Qnil));
441 }
442 447
443 /* If program file name starts with /: for quoting a magic name, 448 /* If program file name starts with /: for quoting a magic name,
444 discard that. */ 449 discard that. */
@@ -496,11 +501,13 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
496 mktemp (tempfile); 501 mktemp (tempfile);
497 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, 502 outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC,
498 S_IREAD | S_IWRITE); 503 S_IREAD | S_IWRITE);
499 if (outfilefd < 0) { 504 if (outfilefd < 0)
500 emacs_close (filefd); 505 {
501 report_file_error ("Opening process output file", 506 int open_errno = errno;
502 Fcons (build_string (tempfile), Qnil)); 507 emacs_close (filefd);
503 } 508 report_file_errno ("Opening process output file",
509 Fcons (build_string (tempfile), Qnil), open_errno);
510 }
504 } 511 }
505 else 512 else
506 outfilefd = fd_output; 513 outfilefd = fd_output;
@@ -517,12 +524,11 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
517 { 524 {
518#ifndef MSDOS 525#ifndef MSDOS
519 int fd[2]; 526 int fd[2];
520 if (pipe (fd) == -1) 527 if (pipe2 (fd, O_CLOEXEC) != 0)
521 { 528 {
522 int pipe_errno = errno; 529 int pipe_errno = errno;
523 emacs_close (filefd); 530 emacs_close (filefd);
524 errno = pipe_errno; 531 report_file_errno ("Creating process pipe", Qnil, pipe_errno);
525 report_file_error ("Creating process pipe", Qnil);
526 } 532 }
527 fd0 = fd[0]; 533 fd0 = fd[0];
528 fd1 = fd[1]; 534 fd1 = fd[1];
@@ -544,6 +550,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
544 550
545 if (fd_error < 0) 551 if (fd_error < 0)
546 { 552 {
553 int open_errno = errno;
547 emacs_close (filefd); 554 emacs_close (filefd);
548 if (fd0 != filefd) 555 if (fd0 != filefd)
549 emacs_close (fd0); 556 emacs_close (fd0);
@@ -556,7 +563,8 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
556 error_file = build_string (NULL_DEVICE); 563 error_file = build_string (NULL_DEVICE);
557 else if (STRINGP (error_file)) 564 else if (STRINGP (error_file))
558 error_file = DECODE_FILE (error_file); 565 error_file = DECODE_FILE (error_file);
559 report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil)); 566 report_file_errno ("Cannot redirect stderr",
567 Fcons (error_file, Qnil), open_errno);
560 } 568 }
561 569
562#ifdef MSDOS /* MW, July 1993 */ 570#ifdef MSDOS /* MW, July 1993 */
@@ -584,10 +592,12 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
584 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0); 592 fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
585 if (fd0 < 0) 593 if (fd0 < 0)
586 { 594 {
595 int open_errno = errno;
587 unlink (tempfile); 596 unlink (tempfile);
588 emacs_close (filefd); 597 emacs_close (filefd);
589 report_file_error ("Cannot re-open temporary file", 598 report_file_errno ("Cannot re-open temporary file",
590 Fcons (build_string (tempfile), Qnil)); 599 Fcons (build_string (tempfile), Qnil),
600 open_errno);
591 } 601 }
592 } 602 }
593 else 603 else
@@ -705,10 +715,7 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
705 } 715 }
706 716
707 if (pid < 0) 717 if (pid < 0)
708 { 718 report_file_errno ("Doing vfork", Qnil, child_errno);
709 errno = child_errno;
710 report_file_error ("Doing vfork", Qnil);
711 }
712 719
713 if (INTEGERP (buffer)) 720 if (INTEGERP (buffer))
714 return unbind_to (count, Qnil); 721 return unbind_to (count, Qnil);
@@ -1034,29 +1041,29 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
1034 memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1); 1041 memcpy (tempfile, SDATA (encoded_tem), SBYTES (encoded_tem) + 1);
1035 coding_systems = Qt; 1042 coding_systems = Qt;
1036 1043
1037#ifdef HAVE_MKSTEMP 1044#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
1038 { 1045 {
1039 int fd; 1046 int fd, open_errno;
1040 1047
1041 block_input (); 1048 block_input ();
1049# ifdef HAVE_MKOSTEMP
1050 fd = mkostemp (tempfile, O_CLOEXEC);
1051# else
1042 fd = mkstemp (tempfile); 1052 fd = mkstemp (tempfile);
1053# endif
1054 open_errno = errno;
1043 unblock_input (); 1055 unblock_input ();
1044 if (fd == -1) 1056 if (fd < 0)
1045 report_file_error ("Failed to open temporary file", 1057 report_file_errno ("Failed to open temporary file",
1046 Fcons (build_string (tempfile), Qnil)); 1058 Fcons (build_string (tempfile), Qnil), open_errno);
1047 else 1059 emacs_close (fd);
1048 close (fd);
1049 } 1060 }
1050#else 1061#else
1051 errno = 0; 1062 errno = EEXIST;
1052 mktemp (tempfile); 1063 mktemp (tempfile);
1053 if (!*tempfile) 1064 if (!*tempfile)
1054 { 1065 report_file_error ("Failed to open temporary file using pattern",
1055 if (!errno) 1066 Fcons (pattern, Qnil));
1056 errno = EEXIST;
1057 report_file_error ("Failed to open temporary file using pattern",
1058 Fcons (pattern, Qnil));
1059 }
1060#endif 1067#endif
1061 1068
1062 filename_string = build_string (tempfile); 1069 filename_string = build_string (tempfile);
@@ -1182,15 +1189,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1182 1189
1183 pid_t pid = getpid (); 1190 pid_t pid = getpid ();
1184 1191
1185 /* Close Emacs's descriptors that this process should not have. */
1186 close_process_descs ();
1187
1188 /* DOS_NT isn't in a vfork, so if we are in the middle of load-file,
1189 we will lose if we call close_load_descs here. */
1190#ifndef DOS_NT
1191 close_load_descs ();
1192#endif
1193
1194 /* Note that use of alloca is always safe here. It's obvious for systems 1192 /* Note that use of alloca is always safe here. It's obvious for systems
1195 that do not have true vfork or that have true (stack) alloca. 1193 that do not have true vfork or that have true (stack) alloca.
1196 If using vfork and C_ALLOCA (when Emacs used to include 1194 If using vfork and C_ALLOCA (when Emacs used to include
@@ -1223,7 +1221,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1223 are changed between the check and this chdir, but we should 1221 are changed between the check and this chdir, but we should
1224 at least check. */ 1222 at least check. */
1225 if (chdir (temp) < 0) 1223 if (chdir (temp) < 0)
1226 _exit (errno); 1224 _exit (EXIT_CANCELED);
1227#else /* DOS_NT */ 1225#else /* DOS_NT */
1228 /* Get past the drive letter, so that d:/ is left alone. */ 1226 /* Get past the drive letter, so that d:/ is left alone. */
1229 if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2])) 1227 if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2]))
@@ -1352,9 +1350,11 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1352 emacs_close (1); 1350 emacs_close (1);
1353 emacs_close (2); 1351 emacs_close (2);
1354 1352
1353 /* Redirect file descriptors and clear FD_CLOEXEC on the redirected ones. */
1355 dup2 (in, 0); 1354 dup2 (in, 0);
1356 dup2 (out, 1); 1355 dup2 (out, 1);
1357 dup2 (err, 2); 1356 dup2 (err, 2);
1357
1358 emacs_close (in); 1358 emacs_close (in);
1359 if (out != in) 1359 if (out != in)
1360 emacs_close (out); 1360 emacs_close (out);
@@ -1366,10 +1366,12 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1366 1366
1367 execve (new_argv[0], new_argv, env); 1367 execve (new_argv[0], new_argv, env);
1368 1368
1369 emacs_write (1, "Can't exec program: ", 20); 1369 /* Don't output the program name here, as it can be arbitrarily long,
1370 emacs_write (1, new_argv[0], strlen (new_argv[0])); 1370 and a long write from a vforked child to its parent can cause a
1371 emacs_write (1, "\n", 1); 1371 deadlock. */
1372 _exit (1); 1372 emacs_perror ("child process");
1373
1374 _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1373 1375
1374#else /* MSDOS */ 1376#else /* MSDOS */
1375 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); 1377 pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
@@ -1392,16 +1394,11 @@ relocate_fd (int fd, int minfd)
1392 return fd; 1394 return fd;
1393 else 1395 else
1394 { 1396 {
1395 int new = fcntl (fd, F_DUPFD, minfd); 1397 int new = fcntl (fd, F_DUPFD_CLOEXEC, minfd);
1396 if (new == -1) 1398 if (new == -1)
1397 { 1399 {
1398 const char *message_1 = "Error while setting up child: "; 1400 emacs_perror ("while setting up child");
1399 const char *errmessage = strerror (errno); 1401 _exit (EXIT_CANCELED);
1400 const char *message_2 = "\n";
1401 emacs_write (2, message_1, strlen (message_1));
1402 emacs_write (2, errmessage, strlen (errmessage));
1403 emacs_write (2, message_2, strlen (message_2));
1404 _exit (1);
1405 } 1402 }
1406 emacs_close (fd); 1403 emacs_close (fd);
1407 return new; 1404 return new;
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 3ec3c28431b..523544d56ca 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -142,7 +142,10 @@ static bool xd_in_read_queued_messages = 0;
142 } while (0) 142 } while (0)
143 143
144#else /* !DBUS_DEBUG */ 144#else /* !DBUS_DEBUG */
145#define XD_DEBUG_MESSAGE(...) \ 145# if __STDC_VERSION__ < 199901
146# define XD_DEBUG_MESSAGE (void) /* Pre-C99 compilers cannot debug. */
147# else
148# define XD_DEBUG_MESSAGE(...) \
146 do { \ 149 do { \
147 if (!NILP (Vdbus_debug)) \ 150 if (!NILP (Vdbus_debug)) \
148 { \ 151 { \
@@ -151,7 +154,8 @@ static bool xd_in_read_queued_messages = 0;
151 message ("%s: %s", __func__, s); \ 154 message ("%s: %s", __func__, s); \
152 } \ 155 } \
153 } while (0) 156 } while (0)
154#define XD_DEBUG_VALID_LISP_OBJECT_P(object) 157# endif
158# define XD_DEBUG_VALID_LISP_OBJECT_P(object)
155#endif 159#endif
156 160
157/* Check whether TYPE is a basic DBusType. */ 161/* Check whether TYPE is a basic DBusType. */
diff --git a/src/dired.c b/src/dired.c
index 7bbfee7e5b0..b3348b0aff0 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -95,7 +95,7 @@ open_directory (char const *name, int *fdp)
95 d = fdopendir (fd); 95 d = fdopendir (fd);
96 opendir_errno = errno; 96 opendir_errno = errno;
97 if (! d) 97 if (! d)
98 close (fd); 98 emacs_close (fd);
99 } 99 }
100#endif 100#endif
101 101
diff --git a/src/dispextern.h b/src/dispextern.h
index 1dd96c6638d..e0d04231d3a 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3298,7 +3298,7 @@ int image_ascent (struct image *, struct face *, struct glyph_slice *);
3298void get_tty_size (int, int *, int *); 3298void get_tty_size (int, int *, int *);
3299void request_sigio (void); 3299void request_sigio (void);
3300void unrequest_sigio (void); 3300void unrequest_sigio (void);
3301int tabs_safe_p (int); 3301bool tabs_safe_p (int);
3302void init_baud_rate (int); 3302void init_baud_rate (int);
3303void init_sigio (int); 3303void init_sigio (int);
3304void ignore_sigio (void); 3304void ignore_sigio (void);
@@ -3470,11 +3470,12 @@ extern int string_cost (const char *);
3470extern int per_line_cost (const char *); 3470extern int per_line_cost (const char *);
3471extern void calculate_costs (struct frame *); 3471extern void calculate_costs (struct frame *);
3472extern void produce_glyphs (struct it *); 3472extern void produce_glyphs (struct it *);
3473extern int tty_capable_p (struct tty_display_info *, unsigned, unsigned long, unsigned long); 3473extern bool tty_capable_p (struct tty_display_info *, unsigned,
3474 unsigned long, unsigned long);
3474extern void set_tty_color_mode (struct tty_display_info *, struct frame *); 3475extern void set_tty_color_mode (struct tty_display_info *, struct frame *);
3475extern struct terminal *get_named_tty (const char *); 3476extern struct terminal *get_named_tty (const char *);
3476extern void create_tty_output (struct frame *); 3477extern void create_tty_output (struct frame *);
3477extern struct terminal *init_tty (const char *, const char *, int); 3478extern struct terminal *init_tty (const char *, const char *, bool);
3478extern void tty_append_glyph (struct it *); 3479extern void tty_append_glyph (struct it *);
3479 3480
3480 3481
diff --git a/src/dispnew.c b/src/dispnew.c
index 31b8a1310ea..1eb097f05ab 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -213,6 +213,7 @@ static void
213add_window_display_history (struct window *w, const char *msg, bool paused_p) 213add_window_display_history (struct window *w, const char *msg, bool paused_p)
214{ 214{
215 char *buf; 215 char *buf;
216 void *ptr = w;
216 217
217 if (history_idx >= REDISPLAY_HISTORY_SIZE) 218 if (history_idx >= REDISPLAY_HISTORY_SIZE)
218 history_idx = 0; 219 history_idx = 0;
@@ -222,7 +223,7 @@ add_window_display_history (struct window *w, const char *msg, bool paused_p)
222 snprintf (buf, sizeof redisplay_history[0].trace, 223 snprintf (buf, sizeof redisplay_history[0].trace,
223 "%"pMu": window %p (`%s')%s\n%s", 224 "%"pMu": window %p (`%s')%s\n%s",
224 history_tick++, 225 history_tick++,
225 w, 226 ptr,
226 ((BUFFERP (w->contents) 227 ((BUFFERP (w->contents)
227 && STRINGP (BVAR (XBUFFER (w->contents), name))) 228 && STRINGP (BVAR (XBUFFER (w->contents), name)))
228 ? SSDATA (BVAR (XBUFFER (w->contents), name)) 229 ? SSDATA (BVAR (XBUFFER (w->contents), name))
@@ -240,6 +241,7 @@ static void
240add_frame_display_history (struct frame *f, bool paused_p) 241add_frame_display_history (struct frame *f, bool paused_p)
241{ 242{
242 char *buf; 243 char *buf;
244 void *ptr = f;
243 245
244 if (history_idx >= REDISPLAY_HISTORY_SIZE) 246 if (history_idx >= REDISPLAY_HISTORY_SIZE)
245 history_idx = 0; 247 history_idx = 0;
@@ -248,7 +250,7 @@ add_frame_display_history (struct frame *f, bool paused_p)
248 250
249 sprintf (buf, "%"pMu": update frame %p%s", 251 sprintf (buf, "%"pMu": update frame %p%s",
250 history_tick++, 252 history_tick++,
251 f, paused_p ? " ***paused***" : ""); 253 ptr, paused_p ? " ***paused***" : "");
252} 254}
253 255
254 256
diff --git a/src/emacs.c b/src/emacs.c
index ec17322f57a..274321482e1 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -28,12 +28,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
28#include <unistd.h> 28#include <unistd.h>
29 29
30#include <close-stream.h> 30#include <close-stream.h>
31#include <ignore-value.h>
32 31
33#include "lisp.h" 32#include "lisp.h"
34 33
35#ifdef WINDOWSNT 34#ifdef WINDOWSNT
36#include <fcntl.h> 35#include <fcntl.h>
36#include <sys/socket.h>
37#include "w32.h" 37#include "w32.h"
38#include "w32heap.h" 38#include "w32heap.h"
39#endif 39#endif
@@ -197,10 +197,10 @@ int initial_argc;
197static void sort_args (int argc, char **argv); 197static void sort_args (int argc, char **argv);
198static void syms_of_emacs (void); 198static void syms_of_emacs (void);
199 199
200/* MSVC needs each string be shorter than 2048 bytes, so the usage 200/* C89 needs each string be at most 509 characters, so the usage
201 strings below are split to not overflow this limit. */ 201 strings below are split to not overflow this limit. */
202#define USAGE1 "\ 202static char const *const usage_message[] =
203Usage: %s [OPTION-OR-FILENAME]...\n\ 203 { "\
204\n\ 204\n\
205Run Emacs, the extensible, customizable, self-documenting real-time\n\ 205Run Emacs, the extensible, customizable, self-documenting real-time\n\
206display editor. The recommended way to start Emacs for normal editing\n\ 206display editor. The recommended way to start Emacs for normal editing\n\
@@ -211,11 +211,15 @@ read the main documentation for these command-line arguments.\n\
211\n\ 211\n\
212Initialization options:\n\ 212Initialization options:\n\
213\n\ 213\n\
214",
215 "\
214--batch do not do interactive display; implies -q\n\ 216--batch do not do interactive display; implies -q\n\
215--chdir DIR change to directory DIR\n\ 217--chdir DIR change to directory DIR\n\
216--daemon start a server in the background\n\ 218--daemon start a server in the background\n\
217--debug-init enable Emacs Lisp debugger for init file\n\ 219--debug-init enable Emacs Lisp debugger for init file\n\
218--display, -d DISPLAY use X server DISPLAY\n\ 220--display, -d DISPLAY use X server DISPLAY\n\
221",
222 "\
219--no-desktop do not load a saved desktop\n\ 223--no-desktop do not load a saved desktop\n\
220--no-init-file, -q load neither ~/.emacs nor default.el\n\ 224--no-init-file, -q load neither ~/.emacs nor default.el\n\
221--no-shared-memory, -nl do not use shared memory\n\ 225--no-shared-memory, -nl do not use shared memory\n\
@@ -223,14 +227,16 @@ Initialization options:\n\
223--no-site-lisp, -nsl do not add site-lisp directories to load-path\n\ 227--no-site-lisp, -nsl do not add site-lisp directories to load-path\n\
224--no-splash do not display a splash screen on startup\n\ 228--no-splash do not display a splash screen on startup\n\
225--no-window-system, -nw do not communicate with X, ignoring $DISPLAY\n\ 229--no-window-system, -nw do not communicate with X, ignoring $DISPLAY\n\
230",
231 "\
226--quick, -Q equivalent to:\n\ 232--quick, -Q equivalent to:\n\
227 -q --no-site-file --no-site-lisp --no-splash\n\ 233 -q --no-site-file --no-site-lisp --no-splash\n\
228--script FILE run FILE as an Emacs Lisp script\n\ 234--script FILE run FILE as an Emacs Lisp script\n\
229--terminal, -t DEVICE use DEVICE for terminal I/O\n\ 235--terminal, -t DEVICE use DEVICE for terminal I/O\n\
230--user, -u USER load ~USER/.emacs instead of your own\n\ 236--user, -u USER load ~USER/.emacs instead of your own\n\
231\n%s" 237\n\
232 238",
233#define USAGE2 "\ 239 "\
234Action options:\n\ 240Action options:\n\
235\n\ 241\n\
236FILE visit FILE using find-file\n\ 242FILE visit FILE using find-file\n\
@@ -239,6 +245,8 @@ FILE visit FILE using find-file\n\
239--directory, -L DIR add DIR to variable load-path\n\ 245--directory, -L DIR add DIR to variable load-path\n\
240--eval EXPR evaluate Emacs Lisp expression EXPR\n\ 246--eval EXPR evaluate Emacs Lisp expression EXPR\n\
241--execute EXPR evaluate Emacs Lisp expression EXPR\n\ 247--execute EXPR evaluate Emacs Lisp expression EXPR\n\
248",
249 "\
242--file FILE visit FILE using find-file\n\ 250--file FILE visit FILE using find-file\n\
243--find-file FILE visit FILE using find-file\n\ 251--find-file FILE visit FILE using find-file\n\
244--funcall, -f FUNC call Emacs Lisp function FUNC with no arguments\n\ 252--funcall, -f FUNC call Emacs Lisp function FUNC with no arguments\n\
@@ -246,9 +254,9 @@ FILE visit FILE using find-file\n\
246--kill exit without asking for confirmation\n\ 254--kill exit without asking for confirmation\n\
247--load, -l FILE load Emacs Lisp FILE using the load function\n\ 255--load, -l FILE load Emacs Lisp FILE using the load function\n\
248--visit FILE visit FILE using find-file\n\ 256--visit FILE visit FILE using find-file\n\
249\n" 257\n\
250 258",
251#define USAGE3 "\ 259 "\
252Display options:\n\ 260Display options:\n\
253\n\ 261\n\
254--background-color, -bg COLOR window background color\n\ 262--background-color, -bg COLOR window background color\n\
@@ -256,6 +264,8 @@ Display options:\n\
256 used for debugging Emacs\n\ 264 used for debugging Emacs\n\
257--border-color, -bd COLOR main border color\n\ 265--border-color, -bd COLOR main border color\n\
258--border-width, -bw WIDTH width of main border\n\ 266--border-width, -bw WIDTH width of main border\n\
267",
268 "\
259--color, --color=MODE override color mode for character terminals;\n\ 269--color, --color=MODE override color mode for character terminals;\n\
260 MODE defaults to `auto', and\n\ 270 MODE defaults to `auto', and\n\
261 can also be `never', `always',\n\ 271 can also be `never', `always',\n\
@@ -263,17 +273,23 @@ Display options:\n\
263--cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\ 273--cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\
264--font, -fn FONT default font; must be fixed-width\n\ 274--font, -fn FONT default font; must be fixed-width\n\
265--foreground-color, -fg COLOR window foreground color\n\ 275--foreground-color, -fg COLOR window foreground color\n\
276",
277 "\
266--fullheight, -fh make the first frame high as the screen\n\ 278--fullheight, -fh make the first frame high as the screen\n\
267--fullscreen, -fs make the first frame fullscreen\n\ 279--fullscreen, -fs make the first frame fullscreen\n\
268--fullwidth, -fw make the first frame wide as the screen\n\ 280--fullwidth, -fw make the first frame wide as the screen\n\
269--maximized, -mm make the first frame maximized\n\ 281--maximized, -mm make the first frame maximized\n\
270--geometry, -g GEOMETRY window geometry\n\ 282--geometry, -g GEOMETRY window geometry\n\
283",
284 "\
271--no-bitmap-icon, -nbi do not use picture of gnu for Emacs icon\n\ 285--no-bitmap-icon, -nbi do not use picture of gnu for Emacs icon\n\
272--iconic start Emacs in iconified state\n\ 286--iconic start Emacs in iconified state\n\
273--internal-border, -ib WIDTH width between text and main border\n\ 287--internal-border, -ib WIDTH width between text and main border\n\
274--line-spacing, -lsp PIXELS additional space to put between lines\n\ 288--line-spacing, -lsp PIXELS additional space to put between lines\n\
275--mouse-color, -ms COLOR mouse cursor color in Emacs window\n\ 289--mouse-color, -ms COLOR mouse cursor color in Emacs window\n\
276--name NAME title for initial Emacs frame\n\ 290--name NAME title for initial Emacs frame\n\
291",
292 "\
277--no-blinking-cursor, -nbc disable blinking cursor\n\ 293--no-blinking-cursor, -nbc disable blinking cursor\n\
278--reverse-video, -r, -rv switch foreground and background\n\ 294--reverse-video, -r, -rv switch foreground and background\n\
279--title, -T TITLE title for initial Emacs frame\n\ 295--title, -T TITLE title for initial Emacs frame\n\
@@ -282,9 +298,9 @@ Display options:\n\
282--parent-id XID set parent window\n\ 298--parent-id XID set parent window\n\
283--help display this help and exit\n\ 299--help display this help and exit\n\
284--version output version information and exit\n\ 300--version output version information and exit\n\
285\n" 301\n\
286 302",
287#define USAGE4 "\ 303 "\
288You can generally also specify long option names with a single -; for\n\ 304You can generally also specify long option names with a single -; for\n\
289example, -batch as well as --batch. You can use any unambiguous\n\ 305example, -batch as well as --batch. You can use any unambiguous\n\
290abbreviation for a --option.\n\ 306abbreviation for a --option.\n\
@@ -294,6 +310,7 @@ Emacs' operation. See the main documentation.\n\
294\n\ 310\n\
295Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\ 311Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\
296section of the Emacs manual or the file BUGS.\n" 312section of the Emacs manual or the file BUGS.\n"
313 };
297 314
298 315
299/* True if handling a fatal error already. */ 316/* True if handling a fatal error already. */
@@ -641,9 +658,7 @@ close_output_streams (void)
641{ 658{
642 if (close_stream (stdout) != 0) 659 if (close_stream (stdout) != 0)
643 { 660 {
644 fprintf (stderr, "Write error to standard output: %s\n", 661 emacs_perror ("Write error to standard output");
645 strerror (errno));
646 fflush (stderr);
647 _exit (EXIT_FAILURE); 662 _exit (EXIT_FAILURE);
648 } 663 }
649 664
@@ -780,7 +795,7 @@ main (int argc, char **argv)
780 execvp (argv[0], argv); 795 execvp (argv[0], argv);
781 796
782 /* If the exec fails, try to dump anyway. */ 797 /* If the exec fails, try to dump anyway. */
783 perror ("execvp"); 798 emacs_perror (argv[0]);
784 } 799 }
785#endif /* HAVE_PERSONALITY_LINUX32 */ 800#endif /* HAVE_PERSONALITY_LINUX32 */
786 801
@@ -878,7 +893,7 @@ main (int argc, char **argv)
878 emacs_close (0); 893 emacs_close (0);
879 emacs_close (1); 894 emacs_close (1);
880 result = emacs_open (term, O_RDWR, 0); 895 result = emacs_open (term, O_RDWR, 0);
881 if (result < 0 || dup (0) < 0) 896 if (result < 0 || fcntl (0, F_DUPFD_CLOEXEC, 1) < 0)
882 { 897 {
883 char *errstring = strerror (errno); 898 char *errstring = strerror (errno);
884 fprintf (stderr, "%s: %s: %s\n", argv[0], term, errstring); 899 fprintf (stderr, "%s: %s: %s\n", argv[0], term, errstring);
@@ -925,9 +940,10 @@ main (int argc, char **argv)
925 /* Handle the --help option, which gives a usage message. */ 940 /* Handle the --help option, which gives a usage message. */
926 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args)) 941 if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
927 { 942 {
928 printf (USAGE1, argv[0], USAGE2); 943 int i;
929 printf (USAGE3); 944 printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
930 printf (USAGE4); 945 for (i = 0; i < sizeof usage_message / sizeof *usage_message; i++)
946 fputs (usage_message[i], stdout);
931 exit (0); 947 exit (0);
932 } 948 }
933 949
@@ -958,7 +974,7 @@ main (int argc, char **argv)
958 use a pipe for synchronization. The parent waits for the child 974 use a pipe for synchronization. The parent waits for the child
959 to close its end of the pipe (using `daemon-initialized') 975 to close its end of the pipe (using `daemon-initialized')
960 before exiting. */ 976 before exiting. */
961 if (pipe (daemon_pipe) == -1) 977 if (pipe2 (daemon_pipe, O_CLOEXEC) != 0)
962 { 978 {
963 fprintf (stderr, "Cannot pipe!\n"); 979 fprintf (stderr, "Cannot pipe!\n");
964 exit (1); 980 exit (1);
@@ -983,7 +999,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
983 char buf[1]; 999 char buf[1];
984 1000
985 /* Close unused writing end of the pipe. */ 1001 /* Close unused writing end of the pipe. */
986 close (daemon_pipe[1]); 1002 emacs_close (daemon_pipe[1]);
987 1003
988 /* Just wait for the child to close its end of the pipe. */ 1004 /* Just wait for the child to close its end of the pipe. */
989 do 1005 do
@@ -1003,13 +1019,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1003 exit (1); 1019 exit (1);
1004 } 1020 }
1005 1021
1006 close (daemon_pipe[0]); 1022 emacs_close (daemon_pipe[0]);
1007 exit (0); 1023 exit (0);
1008 } 1024 }
1009 if (f < 0) 1025 if (f < 0)
1010 { 1026 {
1011 fprintf (stderr, "Cannot fork!\n"); 1027 emacs_perror ("fork");
1012 exit (1); 1028 exit (EXIT_CANCELED);
1013 } 1029 }
1014 1030
1015#ifdef DAEMON_MUST_EXEC 1031#ifdef DAEMON_MUST_EXEC
@@ -1026,14 +1042,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1026 if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr)) 1042 if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr))
1027 { 1043 {
1028 fprintf (stderr, "daemon: child name too long\n"); 1044 fprintf (stderr, "daemon: child name too long\n");
1029 exit (1); 1045 exit (EXIT_CANNOT_INVOKE);
1030 } 1046 }
1031 1047
1032 argv[skip_args] = fdStr; 1048 argv[skip_args] = fdStr;
1033 1049
1034 execvp (argv[0], argv); 1050 execvp (argv[0], argv);
1035 fprintf (stderr, "emacs daemon: exec failed: %d\n", errno); 1051 emacs_perror (argv[0]);
1036 exit (1); 1052 exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
1037 } 1053 }
1038 1054
1039 /* In exec'd: parse special dname into pipe and name info. */ 1055 /* In exec'd: parse special dname into pipe and name info. */
@@ -1041,7 +1057,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1041 || strlen (dname_arg) < 1 || strlen (dname_arg) > 70) 1057 || strlen (dname_arg) < 1 || strlen (dname_arg) > 70)
1042 { 1058 {
1043 fprintf (stderr, "emacs daemon: daemon name absent or too long\n"); 1059 fprintf (stderr, "emacs daemon: daemon name absent or too long\n");
1044 exit (1); 1060 exit (EXIT_CANNOT_INVOKE);
1045 } 1061 }
1046 dname_arg2[0] = '\0'; 1062 dname_arg2[0] = '\0';
1047 sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]), 1063 sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]),
@@ -1053,10 +1069,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1053 if (dname_arg) 1069 if (dname_arg)
1054 daemon_name = xstrdup (dname_arg); 1070 daemon_name = xstrdup (dname_arg);
1055 /* Close unused reading end of the pipe. */ 1071 /* Close unused reading end of the pipe. */
1056 close (daemon_pipe[0]); 1072 emacs_close (daemon_pipe[0]);
1057 /* Make sure that the used end of the pipe is closed on exec, so
1058 that it is not accessible to programs started from .emacs. */
1059 fcntl (daemon_pipe[1], F_SETFD, FD_CLOEXEC);
1060 1073
1061 setsid (); 1074 setsid ();
1062#else /* DOS_NT */ 1075#else /* DOS_NT */
@@ -1910,8 +1923,8 @@ shut_down_emacs (int sig, Lisp_Object stuff)
1910 char buf[sizeof format - 2 + INT_STRLEN_BOUND (int)]; 1923 char buf[sizeof format - 2 + INT_STRLEN_BOUND (int)];
1911 int buflen = sprintf (buf, format, sig); 1924 int buflen = sprintf (buf, format, sig);
1912 char const *sig_desc = safe_strsignal (sig); 1925 char const *sig_desc = safe_strsignal (sig);
1913 ignore_value (write (STDERR_FILENO, buf, buflen)); 1926 emacs_write (STDERR_FILENO, buf, buflen);
1914 ignore_value (write (STDERR_FILENO, sig_desc, strlen (sig_desc))); 1927 emacs_write (STDERR_FILENO, sig_desc, strlen (sig_desc));
1915 } 1928 }
1916 } 1929 }
1917 } 1930 }
@@ -2233,7 +2246,7 @@ from the parent process and its tty file descriptors. */)
2233 err |= dup2 (nfd, 0) < 0; 2246 err |= dup2 (nfd, 0) < 0;
2234 err |= dup2 (nfd, 1) < 0; 2247 err |= dup2 (nfd, 1) < 0;
2235 err |= dup2 (nfd, 2) < 0; 2248 err |= dup2 (nfd, 2) < 0;
2236 err |= close (nfd) != 0; 2249 err |= emacs_close (nfd) != 0;
2237 2250
2238 /* Closing the pipe will notify the parent that it can exit. 2251 /* Closing the pipe will notify the parent that it can exit.
2239 FIXME: In case some other process inherited the pipe, closing it here 2252 FIXME: In case some other process inherited the pipe, closing it here
@@ -2243,7 +2256,7 @@ from the parent process and its tty file descriptors. */)
2243 call-process to make sure the pipe is never inherited by 2256 call-process to make sure the pipe is never inherited by
2244 subprocesses. */ 2257 subprocesses. */
2245 err |= write (daemon_pipe[1], "\n", 1) < 0; 2258 err |= write (daemon_pipe[1], "\n", 1) < 0;
2246 err |= close (daemon_pipe[1]) != 0; 2259 err |= emacs_close (daemon_pipe[1]) != 0;
2247 /* Set it to an invalid value so we know we've already run this function. */ 2260 /* Set it to an invalid value so we know we've already run this function. */
2248 daemon_pipe[1] = -1; 2261 daemon_pipe[1] = -1;
2249 2262
diff --git a/src/eval.c b/src/eval.c
index 451a7b0cc28..97e812dd890 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -114,6 +114,13 @@ Lisp_Object Vsignaling_function;
114 frame is half-initialized. */ 114 frame is half-initialized. */
115Lisp_Object inhibit_lisp_code; 115Lisp_Object inhibit_lisp_code;
116 116
117/* These would ordinarily be static, but they need to be visible to GDB. */
118bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
119Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE;
120Lisp_Object backtrace_function (union specbinding *) EXTERNALLY_VISIBLE;
121union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE;
122union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
123
117static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); 124static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *);
118static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); 125static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args);
119 126
@@ -159,7 +166,7 @@ specpdl_func (union specbinding *pdl)
159 return pdl->unwind.func; 166 return pdl->unwind.func;
160} 167}
161 168
162static Lisp_Object 169Lisp_Object
163backtrace_function (union specbinding *pdl) 170backtrace_function (union specbinding *pdl)
164{ 171{
165 eassert (pdl->kind == SPECPDL_BACKTRACE); 172 eassert (pdl->kind == SPECPDL_BACKTRACE);
@@ -173,7 +180,7 @@ backtrace_nargs (union specbinding *pdl)
173 return pdl->bt.nargs; 180 return pdl->bt.nargs;
174} 181}
175 182
176static Lisp_Object * 183Lisp_Object *
177backtrace_args (union specbinding *pdl) 184backtrace_args (union specbinding *pdl)
178{ 185{
179 eassert (pdl->kind == SPECPDL_BACKTRACE); 186 eassert (pdl->kind == SPECPDL_BACKTRACE);
@@ -212,10 +219,6 @@ set_backtrace_debug_on_exit (union specbinding *pdl, bool doe)
212 219
213/* Helper functions to scan the backtrace. */ 220/* Helper functions to scan the backtrace. */
214 221
215bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
216union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE;
217union specbinding *backtrace_next (union specbinding *pdl) EXTERNALLY_VISIBLE;
218
219bool 222bool
220backtrace_p (union specbinding *pdl) 223backtrace_p (union specbinding *pdl)
221{ return pdl >= specpdl; } 224{ return pdl >= specpdl; }
@@ -2013,38 +2016,52 @@ If LEXICAL is t, evaluate using lexical scoping. */)
2013 return unbind_to (count, eval_sub (form)); 2016 return unbind_to (count, eval_sub (form));
2014} 2017}
2015 2018
2019/* Grow the specpdl stack by one entry.
2020 The caller should have already initialized the entry.
2021 Signal an error on stack overflow.
2022
2023 Make sure that there is always one unused entry past the top of the
2024 stack, so that the just-initialized entry is safely unwound if
2025 memory exhausted and an error is signaled here. Also, allocate a
2026 never-used entry just before the bottom of the stack; sometimes its
2027 address is taken. */
2028
2016static void 2029static void
2017grow_specpdl (void) 2030grow_specpdl (void)
2018{ 2031{
2019 ptrdiff_t count = SPECPDL_INDEX (); 2032 specpdl_ptr++;
2020 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000); 2033
2021 union specbinding *pdlvec = specpdl - 1; 2034 if (specpdl_ptr == specpdl + specpdl_size)
2022 ptrdiff_t pdlvecsize = specpdl_size + 1;
2023 if (max_size <= specpdl_size)
2024 { 2035 {
2025 if (max_specpdl_size < 400) 2036 ptrdiff_t count = SPECPDL_INDEX ();
2026 max_size = max_specpdl_size = 400; 2037 ptrdiff_t max_size = min (max_specpdl_size, PTRDIFF_MAX - 1000);
2038 union specbinding *pdlvec = specpdl - 1;
2039 ptrdiff_t pdlvecsize = specpdl_size + 1;
2027 if (max_size <= specpdl_size) 2040 if (max_size <= specpdl_size)
2028 signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil); 2041 {
2042 if (max_specpdl_size < 400)
2043 max_size = max_specpdl_size = 400;
2044 if (max_size <= specpdl_size)
2045 signal_error ("Variable binding depth exceeds max-specpdl-size",
2046 Qnil);
2047 }
2048 pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
2049 specpdl = pdlvec + 1;
2050 specpdl_size = pdlvecsize - 1;
2051 specpdl_ptr = specpdl + count;
2029 } 2052 }
2030 pdlvec = xpalloc (pdlvec, &pdlvecsize, 1, max_size + 1, sizeof *specpdl);
2031 specpdl = pdlvec + 1;
2032 specpdl_size = pdlvecsize - 1;
2033 specpdl_ptr = specpdl + count;
2034} 2053}
2035 2054
2036void 2055void
2037record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) 2056record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
2038{ 2057{
2039 eassert (nargs >= UNEVALLED); 2058 eassert (nargs >= UNEVALLED);
2040 if (specpdl_ptr == specpdl + specpdl_size)
2041 grow_specpdl ();
2042 specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; 2059 specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
2043 specpdl_ptr->bt.debug_on_exit = false; 2060 specpdl_ptr->bt.debug_on_exit = false;
2044 specpdl_ptr->bt.function = function; 2061 specpdl_ptr->bt.function = function;
2045 specpdl_ptr->bt.args = args; 2062 specpdl_ptr->bt.args = args;
2046 specpdl_ptr->bt.nargs = nargs; 2063 specpdl_ptr->bt.nargs = nargs;
2047 specpdl_ptr++; 2064 grow_specpdl ();
2048} 2065}
2049 2066
2050/* Eval a sub-expression of the current expression (i.e. in the same 2067/* Eval a sub-expression of the current expression (i.e. in the same
@@ -3176,8 +3193,6 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3176 3193
3177 CHECK_SYMBOL (symbol); 3194 CHECK_SYMBOL (symbol);
3178 sym = XSYMBOL (symbol); 3195 sym = XSYMBOL (symbol);
3179 if (specpdl_ptr == specpdl + specpdl_size)
3180 grow_specpdl ();
3181 3196
3182 start: 3197 start:
3183 switch (sym->redirect) 3198 switch (sym->redirect)
@@ -3191,7 +3206,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3191 specpdl_ptr->let.symbol = symbol; 3206 specpdl_ptr->let.symbol = symbol;
3192 specpdl_ptr->let.old_value = SYMBOL_VAL (sym); 3207 specpdl_ptr->let.old_value = SYMBOL_VAL (sym);
3193 specpdl_ptr->let.saved_value = Qnil; 3208 specpdl_ptr->let.saved_value = Qnil;
3194 ++specpdl_ptr; 3209 grow_specpdl ();
3195 do_specbind (sym, specpdl_ptr - 1, value); 3210 do_specbind (sym, specpdl_ptr - 1, value);
3196 break; 3211 break;
3197 case SYMBOL_LOCALIZED: 3212 case SYMBOL_LOCALIZED:
@@ -3224,7 +3239,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3224 if (NILP (Flocal_variable_p (symbol, Qnil))) 3239 if (NILP (Flocal_variable_p (symbol, Qnil)))
3225 { 3240 {
3226 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; 3241 specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT;
3227 ++specpdl_ptr; 3242 grow_specpdl ();
3228 do_specbind (sym, specpdl_ptr - 1, value); 3243 do_specbind (sym, specpdl_ptr - 1, value);
3229 return; 3244 return;
3230 } 3245 }
@@ -3232,7 +3247,7 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3232 else 3247 else
3233 specpdl_ptr->let.kind = SPECPDL_LET; 3248 specpdl_ptr->let.kind = SPECPDL_LET;
3234 3249
3235 specpdl_ptr++; 3250 grow_specpdl ();
3236 do_specbind (sym, specpdl_ptr - 1, value); 3251 do_specbind (sym, specpdl_ptr - 1, value);
3237 break; 3252 break;
3238 } 3253 }
@@ -3243,12 +3258,10 @@ specbind (Lisp_Object symbol, Lisp_Object value)
3243void 3258void
3244record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) 3259record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
3245{ 3260{
3246 if (specpdl_ptr == specpdl + specpdl_size)
3247 grow_specpdl ();
3248 specpdl_ptr->unwind.kind = SPECPDL_UNWIND; 3261 specpdl_ptr->unwind.kind = SPECPDL_UNWIND;
3249 specpdl_ptr->unwind.func = function; 3262 specpdl_ptr->unwind.func = function;
3250 specpdl_ptr->unwind.arg = arg; 3263 specpdl_ptr->unwind.arg = arg;
3251 specpdl_ptr++; 3264 grow_specpdl ();
3252} 3265}
3253 3266
3254void 3267void
diff --git a/src/fileio.c b/src/fileio.c
index 89ae89e1613..c3566390130 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -159,11 +159,13 @@ static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
159 struct coding_system *); 159 struct coding_system *);
160 160
161 161
162/* Signal a file-access failure. STRING describes the failure,
163 DATA the file that was involved, and ERRORNO the errno value. */
164
162void 165void
163report_file_error (const char *string, Lisp_Object data) 166report_file_errno (char const *string, Lisp_Object data, int errorno)
164{ 167{
165 Lisp_Object errstring; 168 Lisp_Object errstring;
166 int errorno = errno;
167 char *str; 169 char *str;
168 170
169 synchronize_system_messages_locale (); 171 synchronize_system_messages_locale ();
@@ -196,6 +198,12 @@ report_file_error (const char *string, Lisp_Object data)
196 } 198 }
197} 199}
198 200
201void
202report_file_error (char const *string, Lisp_Object data)
203{
204 report_file_errno (string, data, errno);
205}
206
199Lisp_Object 207Lisp_Object
200close_file_unwind (Lisp_Object fd) 208close_file_unwind (Lisp_Object fd)
201{ 209{
@@ -2019,11 +2027,8 @@ entries (depending on how Emacs was built). */)
2019 { 2027 {
2020 /* CopyFile doesn't set errno when it fails. By far the most 2028 /* CopyFile doesn't set errno when it fails. By far the most
2021 "popular" reason is that the target is read-only. */ 2029 "popular" reason is that the target is read-only. */
2022 if (GetLastError () == 5) 2030 report_file_errno ("Copying file", Fcons (file, Fcons (newname, Qnil)),
2023 errno = EACCES; 2031 GetLastError () == 5 ? EACCES : EPERM);
2024 else
2025 errno = EPERM;
2026 report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil)));
2027 } 2032 }
2028 /* CopyFile retains the timestamp by default. */ 2033 /* CopyFile retains the timestamp by default. */
2029 else if (NILP (keep_time)) 2034 else if (NILP (keep_time))
@@ -2084,36 +2089,25 @@ entries (depending on how Emacs was built). */)
2084 2089
2085 if (out_st.st_mode != 0 2090 if (out_st.st_mode != 0
2086 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino) 2091 && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
2087 { 2092 report_file_errno ("Input and output files are the same",
2088 errno = 0; 2093 Fcons (file, Fcons (newname, Qnil)), 0);
2089 report_file_error ("Input and output files are the same",
2090 Fcons (file, Fcons (newname, Qnil)));
2091 }
2092 2094
2093 /* We can copy only regular files. */ 2095 /* We can copy only regular files. */
2094 if (!S_ISREG (st.st_mode)) 2096 if (!S_ISREG (st.st_mode))
2095 { 2097 report_file_errno ("Non-regular file", Fcons (file, Qnil),
2096 /* Get a better looking error message. */ 2098 S_ISDIR (st.st_mode) ? EISDIR : EINVAL);
2097 errno = S_ISDIR (st.st_mode) ? EISDIR : EINVAL;
2098 report_file_error ("Non-regular file", Fcons (file, Qnil));
2099 }
2100 2099
2101#ifdef MSDOS
2102 /* System's default file type was set to binary by _fmode in emacs.c. */
2103 ofd = emacs_open (SDATA (encoded_newname),
2104 O_WRONLY | O_TRUNC | O_CREAT
2105 | (NILP (ok_if_already_exists) ? O_EXCL : 0),
2106 S_IREAD | S_IWRITE);
2107#else /* not MSDOS */
2108 { 2100 {
2109 mode_t new_mask = !NILP (preserve_uid_gid) ? 0600 : 0666; 2101#ifndef MSDOS
2110 new_mask &= st.st_mode; 2102 int new_mask = st.st_mode & (!NILP (preserve_uid_gid) ? 0600 : 0666);
2103#else
2104 int new_mask = S_IREAD | S_IWRITE;
2105#endif
2111 ofd = emacs_open (SSDATA (encoded_newname), 2106 ofd = emacs_open (SSDATA (encoded_newname),
2112 (O_WRONLY | O_TRUNC | O_CREAT 2107 (O_WRONLY | O_TRUNC | O_CREAT
2113 | (NILP (ok_if_already_exists) ? O_EXCL : 0)), 2108 | (NILP (ok_if_already_exists) ? O_EXCL : 0)),
2114 new_mask); 2109 new_mask);
2115 } 2110 }
2116#endif /* not MSDOS */
2117 if (ofd < 0) 2111 if (ofd < 0)
2118 report_file_error ("Opening output file", Fcons (newname, Qnil)); 2112 report_file_error ("Opening output file", Fcons (newname, Qnil));
2119 2113
@@ -2122,7 +2116,7 @@ entries (depending on how Emacs was built). */)
2122 immediate_quit = 1; 2116 immediate_quit = 1;
2123 QUIT; 2117 QUIT;
2124 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0) 2118 while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
2125 if (emacs_write (ofd, buf, n) != n) 2119 if (emacs_write_sig (ofd, buf, n) != n)
2126 report_file_error ("I/O error", Fcons (newname, Qnil)); 2120 report_file_error ("I/O error", Fcons (newname, Qnil));
2127 immediate_quit = 0; 2121 immediate_quit = 0;
2128 2122
@@ -2609,7 +2603,11 @@ Use `file-symlink-p' to test for such links. */)
2609 call the corresponding file handler. */ 2603 call the corresponding file handler. */
2610 handler = Ffind_file_name_handler (absname, Qfile_exists_p); 2604 handler = Ffind_file_name_handler (absname, Qfile_exists_p);
2611 if (!NILP (handler)) 2605 if (!NILP (handler))
2612 return call2 (handler, Qfile_exists_p, absname); 2606 {
2607 Lisp_Object result = call2 (handler, Qfile_exists_p, absname);
2608 errno = 0;
2609 return result;
2610 }
2613 2611
2614 absname = ENCODE_FILE (absname); 2612 absname = ENCODE_FILE (absname);
2615 2613
@@ -2706,7 +2704,6 @@ If there is no error, returns nil. */)
2706 (Lisp_Object filename, Lisp_Object string) 2704 (Lisp_Object filename, Lisp_Object string)
2707{ 2705{
2708 Lisp_Object handler, encoded_filename, absname; 2706 Lisp_Object handler, encoded_filename, absname;
2709 int fd;
2710 2707
2711 CHECK_STRING (filename); 2708 CHECK_STRING (filename);
2712 absname = Fexpand_file_name (filename, Qnil); 2709 absname = Fexpand_file_name (filename, Qnil);
@@ -2721,10 +2718,8 @@ If there is no error, returns nil. */)
2721 2718
2722 encoded_filename = ENCODE_FILE (absname); 2719 encoded_filename = ENCODE_FILE (absname);
2723 2720
2724 fd = emacs_open (SSDATA (encoded_filename), O_RDONLY, 0); 2721 if (faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, AT_EACCESS) != 0)
2725 if (fd < 0)
2726 report_file_error (SSDATA (string), Fcons (filename, Qnil)); 2722 report_file_error (SSDATA (string), Fcons (filename, Qnil));
2727 emacs_close (fd);
2728 2723
2729 return Qnil; 2724 return Qnil;
2730} 2725}
@@ -2833,7 +2828,11 @@ searchable directory. */)
2833 call the corresponding file handler. */ 2828 call the corresponding file handler. */
2834 handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p); 2829 handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p);
2835 if (!NILP (handler)) 2830 if (!NILP (handler))
2836 return call2 (handler, Qfile_accessible_directory_p, absname); 2831 {
2832 Lisp_Object r = call2 (handler, Qfile_accessible_directory_p, absname);
2833 errno = 0;
2834 return r;
2835 }
2837 2836
2838 absname = ENCODE_FILE (absname); 2837 absname = ENCODE_FILE (absname);
2839 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil; 2838 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil;
@@ -3345,7 +3344,7 @@ otherwise, if FILE2 does not exist, the answer is t. */)
3345 if (stat (SSDATA (absname2), &st2) < 0) 3344 if (stat (SSDATA (absname2), &st2) < 0)
3346 return Qt; 3345 return Qt;
3347 3346
3348 return (EMACS_TIME_GT (get_stat_mtime (&st1), get_stat_mtime (&st2)) 3347 return (EMACS_TIME_LT (get_stat_mtime (&st2), get_stat_mtime (&st1))
3349 ? Qt : Qnil); 3348 ? Qt : Qnil);
3350} 3349}
3351 3350
@@ -4575,8 +4574,8 @@ by calling `format-decode', which see. */)
4575 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 4574 && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
4576 { 4575 {
4577 /* If visiting nonexistent file, return nil. */ 4576 /* If visiting nonexistent file, return nil. */
4578 errno = save_errno; 4577 report_file_errno ("Opening input file", Fcons (orig_filename, Qnil),
4579 report_file_error ("Opening input file", Fcons (orig_filename, Qnil)); 4578 save_errno);
4580 } 4579 }
4581 4580
4582 if (read_quit) 4581 if (read_quit)
@@ -4897,13 +4896,13 @@ This calls `write-region-annotate-functions' at the start, and
4897 4896
4898 if (desc < 0) 4897 if (desc < 0)
4899 { 4898 {
4899 int open_errno = errno;
4900#ifdef CLASH_DETECTION 4900#ifdef CLASH_DETECTION
4901 save_errno = errno;
4902 if (!auto_saving) unlock_file (lockname); 4901 if (!auto_saving) unlock_file (lockname);
4903 errno = save_errno;
4904#endif /* CLASH_DETECTION */ 4902#endif /* CLASH_DETECTION */
4905 UNGCPRO; 4903 UNGCPRO;
4906 report_file_error ("Opening output file", Fcons (filename, Qnil)); 4904 report_file_errno ("Opening output file", Fcons (filename, Qnil),
4905 open_errno);
4907 } 4906 }
4908 4907
4909 record_unwind_protect (close_file_unwind, make_number (desc)); 4908 record_unwind_protect (close_file_unwind, make_number (desc));
@@ -4913,13 +4912,13 @@ This calls `write-region-annotate-functions' at the start, and
4913 off_t ret = lseek (desc, offset, SEEK_SET); 4912 off_t ret = lseek (desc, offset, SEEK_SET);
4914 if (ret < 0) 4913 if (ret < 0)
4915 { 4914 {
4915 int lseek_errno = errno;
4916#ifdef CLASH_DETECTION 4916#ifdef CLASH_DETECTION
4917 save_errno = errno;
4918 if (!auto_saving) unlock_file (lockname); 4917 if (!auto_saving) unlock_file (lockname);
4919 errno = save_errno;
4920#endif /* CLASH_DETECTION */ 4918#endif /* CLASH_DETECTION */
4921 UNGCPRO; 4919 UNGCPRO;
4922 report_file_error ("Lseek error", Fcons (filename, Qnil)); 4920 report_file_errno ("Lseek error", Fcons (filename, Qnil),
4921 lseek_errno);
4923 } 4922 }
4924 } 4923 }
4925 4924
@@ -5317,12 +5316,10 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
5317 5316
5318 if (coding->produced > 0) 5317 if (coding->produced > 0)
5319 { 5318 {
5320 coding->produced 5319 char *buf = (STRINGP (coding->dst_object)
5321 -= emacs_write (desc, 5320 ? SSDATA (coding->dst_object)
5322 STRINGP (coding->dst_object) 5321 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte));
5323 ? SSDATA (coding->dst_object) 5322 coding->produced -= emacs_write_sig (desc, buf, coding->produced);
5324 : (char *) BYTE_POS_ADDR (coding->dst_pos_byte),
5325 coding->produced);
5326 5323
5327 if (coding->produced) 5324 if (coding->produced)
5328 return 0; 5325 return 0;
@@ -5377,36 +5374,19 @@ See Info node `(elisp)Modification Time' for more details. */)
5377 return Qnil; 5374 return Qnil;
5378} 5375}
5379 5376
5380DEFUN ("clear-visited-file-modtime", Fclear_visited_file_modtime,
5381 Sclear_visited_file_modtime, 0, 0, 0,
5382 doc: /* Clear out records of last mod time of visited file.
5383Next attempt to save will certainly not complain of a discrepancy. */)
5384 (void)
5385{
5386 current_buffer->modtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS);
5387 current_buffer->modtime_size = -1;
5388 return Qnil;
5389}
5390
5391DEFUN ("visited-file-modtime", Fvisited_file_modtime, 5377DEFUN ("visited-file-modtime", Fvisited_file_modtime,
5392 Svisited_file_modtime, 0, 0, 0, 5378 Svisited_file_modtime, 0, 0, 0,
5393 doc: /* Return the current buffer's recorded visited file modification time. 5379 doc: /* Return the current buffer's recorded visited file modification time.
5394The value is a list of the form (HIGH LOW USEC PSEC), like the time values that 5380The value is a list of the form (HIGH LOW USEC PSEC), like the time values that
5395`file-attributes' returns. If the current buffer has no recorded file 5381`file-attributes' returns. If the current buffer has no recorded file
5396modification time, this function returns 0. If the visited file 5382modification time, this function returns 0. If the visited file
5397doesn't exist, HIGH will be -1. 5383doesn't exist, return -1.
5398See Info node `(elisp)Modification Time' for more details. */) 5384See Info node `(elisp)Modification Time' for more details. */)
5399 (void) 5385 (void)
5400{ 5386{
5401 if (EMACS_NSECS (current_buffer->modtime) < 0) 5387 int ns = EMACS_NSECS (current_buffer->modtime);
5402 { 5388 if (ns < 0)
5403 if (EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS) 5389 return make_number (UNKNOWN_MODTIME_NSECS - ns);
5404 {
5405 /* make_lisp_time won't work here if time_t is unsigned. */
5406 return list4i (-1, 65535, 0, 0);
5407 }
5408 return make_number (0);
5409 }
5410 return make_lisp_time (current_buffer->modtime); 5390 return make_lisp_time (current_buffer->modtime);
5411} 5391}
5412 5392
@@ -5417,12 +5397,22 @@ Useful if the buffer was not read from the file normally
5417or if the file itself has been changed for some known benign reason. 5397or if the file itself has been changed for some known benign reason.
5418An argument specifies the modification time value to use 5398An argument specifies the modification time value to use
5419\(instead of that of the visited file), in the form of a list 5399\(instead of that of the visited file), in the form of a list
5420\(HIGH LOW USEC PSEC) as returned by `current-time'. */) 5400\(HIGH LOW USEC PSEC) or an integer flag as returned by
5421 (Lisp_Object time_list) 5401`visited-file-modtime'. */)
5402 (Lisp_Object time_flag)
5422{ 5403{
5423 if (!NILP (time_list)) 5404 if (!NILP (time_flag))
5424 { 5405 {
5425 current_buffer->modtime = lisp_time_argument (time_list); 5406 EMACS_TIME mtime;
5407 if (INTEGERP (time_flag))
5408 {
5409 CHECK_RANGED_INTEGER (time_flag, -1, 0);
5410 mtime = make_emacs_time (0, UNKNOWN_MODTIME_NSECS - XINT (time_flag));
5411 }
5412 else
5413 mtime = lisp_time_argument (time_flag);
5414
5415 current_buffer->modtime = mtime;
5426 current_buffer->modtime_size = -1; 5416 current_buffer->modtime_size = -1;
5427 } 5417 }
5428 else 5418 else
@@ -6123,7 +6113,6 @@ This includes interactive calls to `delete-file' and
6123 defsubr (&Swrite_region); 6113 defsubr (&Swrite_region);
6124 defsubr (&Scar_less_than_car); 6114 defsubr (&Scar_less_than_car);
6125 defsubr (&Sverify_visited_file_modtime); 6115 defsubr (&Sverify_visited_file_modtime);
6126 defsubr (&Sclear_visited_file_modtime);
6127 defsubr (&Svisited_file_modtime); 6116 defsubr (&Svisited_file_modtime);
6128 defsubr (&Sset_visited_file_modtime); 6117 defsubr (&Sset_visited_file_modtime);
6129 defsubr (&Sdo_auto_save); 6118 defsubr (&Sdo_auto_save);
diff --git a/src/filelock.c b/src/filelock.c
index de6aba8385c..244663ad20a 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -47,6 +47,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
47#include "systime.h" 47#include "systime.h"
48#ifdef WINDOWSNT 48#ifdef WINDOWSNT
49#include <share.h> 49#include <share.h>
50#include <sys/socket.h> /* for fcntl */
50#include "w32.h" /* for dostounix_filename */ 51#include "w32.h" /* for dostounix_filename */
51#endif 52#endif
52 53
@@ -380,9 +381,9 @@ rename_lock_file (char const *old, char const *new, bool force)
380#endif 381#endif
381} 382}
382 383
383/* Create the lock file FILE with contents CONTENTS. Return 0 if 384/* Create the lock file LFNAME with contents LOCK_INFO_STR. Return 0 if
384 successful, an errno value on failure. If FORCE, remove any 385 successful, an errno value on failure. If FORCE, remove any
385 existing FILE if necessary. */ 386 existing LFNAME if necessary. */
386 387
387static int 388static int
388create_lock_file (char *lfname, char *lock_info_str, bool force) 389create_lock_file (char *lfname, char *lock_info_str, bool force)
@@ -416,8 +417,13 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
416 memcpy (nonce, lfname, lfdirlen); 417 memcpy (nonce, lfname, lfdirlen);
417 strcpy (nonce + lfdirlen, nonce_base); 418 strcpy (nonce + lfdirlen, nonce_base);
418 419
419#if HAVE_MKSTEMP 420#if HAVE_MKOSTEMP
420 /* Prefer mkstemp if available, as it avoids a race between 421 /* Prefer mkostemp to mkstemp, as it avoids a window where FD is
422 temporarily open without close-on-exec. */
423 fd = mkostemp (nonce, O_BINARY | O_CLOEXEC);
424 need_fchmod = 1;
425#elif HAVE_MKSTEMP
426 /* Prefer mkstemp to mktemp, as it avoids a race between
421 mktemp and emacs_open. */ 427 mktemp and emacs_open. */
422 fd = mkstemp (nonce); 428 fd = mkstemp (nonce);
423 need_fchmod = 1; 429 need_fchmod = 1;
@@ -432,7 +438,11 @@ create_lock_file (char *lfname, char *lock_info_str, bool force)
432 err = errno; 438 err = errno;
433 else 439 else
434 { 440 {
435 ptrdiff_t lock_info_len = strlen (lock_info_str); 441 ptrdiff_t lock_info_len;
442#if ! HAVE_MKOSTEMP
443 fcntl (fd, F_SETFD, FD_CLOEXEC);
444#endif
445 lock_info_len = strlen (lock_info_str);
436 err = 0; 446 err = 0;
437 if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len 447 if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len
438 || (need_fchmod && fchmod (fd, world_readable) != 0)) 448 || (need_fchmod && fchmod (fd, world_readable) != 0))
diff --git a/src/fns.c b/src/fns.c
index 7a8ddc04540..49bd8470f7f 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5011,13 +5011,21 @@ this variable. */);
5011 defsubr (&Ssecure_hash); 5011 defsubr (&Ssecure_hash);
5012 defsubr (&Slocale_info); 5012 defsubr (&Slocale_info);
5013 5013
5014 { 5014 hashtest_eq.name = Qeq;
5015 struct hash_table_test 5015 hashtest_eq.user_hash_function = Qnil;
5016 eq = { Qeq, Qnil, Qnil, NULL, hashfn_eq }, 5016 hashtest_eq.user_cmp_function = Qnil;
5017 eql = { Qeql, Qnil, Qnil, cmpfn_eql, hashfn_eql }, 5017 hashtest_eq.cmpfn = 0;
5018 equal = { Qequal, Qnil, Qnil, cmpfn_equal, hashfn_equal }; 5018 hashtest_eq.hashfn = hashfn_eq;
5019 hashtest_eq = eq; 5019
5020 hashtest_eql = eql; 5020 hashtest_eql.name = Qeql;
5021 hashtest_equal = equal; 5021 hashtest_eql.user_hash_function = Qnil;
5022 } 5022 hashtest_eql.user_cmp_function = Qnil;
5023 hashtest_eql.cmpfn = cmpfn_eql;
5024 hashtest_eql.hashfn = hashfn_eql;
5025
5026 hashtest_equal.name = Qequal;
5027 hashtest_equal.user_hash_function = Qnil;
5028 hashtest_equal.user_cmp_function = Qnil;
5029 hashtest_equal.cmpfn = cmpfn_equal;
5030 hashtest_equal.hashfn = hashfn_equal;
5023} 5031}
diff --git a/src/frame.c b/src/frame.c
index 6ecc7147c18..648687a7cb4 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1855,7 +1855,7 @@ See `redirect-frame-focus'. */)
1855/* Return the value of frame parameter PROP in frame FRAME. */ 1855/* Return the value of frame parameter PROP in frame FRAME. */
1856 1856
1857#ifdef HAVE_WINDOW_SYSTEM 1857#ifdef HAVE_WINDOW_SYSTEM
1858#if !HAVE_NS && !defined(WINDOWSNT) 1858#if !HAVE_NS && !defined (WINDOWSNT)
1859static 1859static
1860#endif 1860#endif
1861Lisp_Object 1861Lisp_Object
diff --git a/src/gnutls.h b/src/gnutls.h
index f1a337e7b3e..86dcab77b62 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -42,7 +42,7 @@ typedef enum
42 GNUTLS_STAGE_TRANSPORT_POINTERS_SET, 42 GNUTLS_STAGE_TRANSPORT_POINTERS_SET,
43 GNUTLS_STAGE_HANDSHAKE_TRIED, 43 GNUTLS_STAGE_HANDSHAKE_TRIED,
44 44
45 GNUTLS_STAGE_READY, 45 GNUTLS_STAGE_READY
46} gnutls_initstage_t; 46} gnutls_initstage_t;
47 47
48#define GNUTLS_EMACS_ERROR_NOT_LOADED GNUTLS_E_APPLICATION_ERROR_MIN + 1 48#define GNUTLS_EMACS_ERROR_NOT_LOADED GNUTLS_E_APPLICATION_ERROR_MIN + 1
diff --git a/src/image.c b/src/image.c
index 7ecd59d27b4..c085e6e63eb 100644
--- a/src/image.c
+++ b/src/image.c
@@ -316,7 +316,6 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
316 int xhot, yhot, result; 316 int xhot, yhot, result;
317 ptrdiff_t id; 317 ptrdiff_t id;
318 Lisp_Object found; 318 Lisp_Object found;
319 int fd;
320 char *filename; 319 char *filename;
321 320
322 /* Look for an existing bitmap with the same name. */ 321 /* Look for an existing bitmap with the same name. */
@@ -332,10 +331,8 @@ x_create_bitmap_from_file (struct frame *f, Lisp_Object file)
332 } 331 }
333 332
334 /* Search bitmap-file-path for the file, if appropriate. */ 333 /* Search bitmap-file-path for the file, if appropriate. */
335 fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil); 334 if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
336 if (fd < 0)
337 return -1; 335 return -1;
338 emacs_close (fd);
339 336
340 filename = SSDATA (found); 337 filename = SSDATA (found);
341 338
@@ -2260,7 +2257,8 @@ x_find_image_file (Lisp_Object file)
2260 else 2257 else
2261 { 2258 {
2262 file_found = ENCODE_FILE (file_found); 2259 file_found = ENCODE_FILE (file_found);
2263 close (fd); 2260 if (fd != -2)
2261 emacs_close (fd);
2264 } 2262 }
2265 2263
2266 return file_found; 2264 return file_found;
@@ -8054,7 +8052,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8054 8052
8055 init_color_table (); 8053 init_color_table ();
8056 8054
8057#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS 8055#if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
8058 if (imagemagick_render_type != 0) 8056 if (imagemagick_render_type != 0)
8059 { 8057 {
8060 /* Magicexportimage is normally faster than pixelpushing. This 8058 /* Magicexportimage is normally faster than pixelpushing. This
diff --git a/src/inotify.c b/src/inotify.c
index 01fb34a5c4a..f4f850bf180 100644
--- a/src/inotify.c
+++ b/src/inotify.c
@@ -71,9 +71,8 @@ static Lisp_Object Qunmount; /* IN_UNMOUNT */
71# define IN_ONLYDIR 0 71# define IN_ONLYDIR 0
72#endif 72#endif
73 73
74enum { uninitialized = -100 };
75/* File handle for inotify. */ 74/* File handle for inotify. */
76static int inotifyfd = uninitialized; 75static int inotifyfd = -1;
77 76
78/* Assoc list of files being watched. 77/* Assoc list of files being watched.
79 Format: 78 Format:
@@ -268,8 +267,10 @@ aspect_to_inotifymask (Lisp_Object aspect)
268DEFUN ("inotify-add-watch", Finotify_add_watch, Sinotify_add_watch, 3, 3, 0, 267DEFUN ("inotify-add-watch", Finotify_add_watch, Sinotify_add_watch, 3, 3, 0,
269 doc: /* Add a watch for FILE-NAME to inotify. 268 doc: /* Add a watch for FILE-NAME to inotify.
270 269
271A WATCH-DESCRIPTOR is returned on success. ASPECT might be one of the following 270Return a watch descriptor. The watch will look for ASPECT events and
272symbols or a list of those symbols: 271invoke CALLBACK when an event occurs.
272
273ASPECT might be one of the following symbols or a list of those symbols:
273 274
274access 275access
275attrib 276attrib
@@ -288,7 +289,7 @@ all-events or t
288move 289move
289close 290close
290 291
291The following symbols can also be added to a list of aspects 292The following symbols can also be added to a list of aspects:
292 293
293dont-follow 294dont-follow
294excl-unlink 295excl-unlink
@@ -296,9 +297,8 @@ mask-add
296oneshot 297oneshot
297onlydir 298onlydir
298 299
299Watching a directory is not recursive. CALLBACK gets called in case of an 300Watching a directory is not recursive. CALLBACK is passed a single argument
300event. It gets passed a single argument EVENT which contains an event structure 301EVENT which contains an event structure of the format
301of the format
302 302
303(WATCH-DESCRIPTOR ASPECTS NAME COOKIE) 303(WATCH-DESCRIPTOR ASPECTS NAME COOKIE)
304 304
@@ -331,16 +331,13 @@ is managed internally and there is no corresponding inotify_init. Use
331 331
332 CHECK_STRING (file_name); 332 CHECK_STRING (file_name);
333 333
334 if (inotifyfd == uninitialized) 334 if (inotifyfd < 0)
335 { 335 {
336 inotifyfd = inotify_init1 (IN_NONBLOCK|IN_CLOEXEC); 336 inotifyfd = inotify_init1 (IN_NONBLOCK|IN_CLOEXEC);
337 if (inotifyfd == -1) 337 if (inotifyfd < 0)
338 { 338 xsignal1
339 inotifyfd = uninitialized; 339 (Qfile_notify_error,
340 xsignal1 340 build_string ("File watching feature (inotify) is not available"));
341 (Qfile_notify_error,
342 build_string ("File watching feature (inotify) is not available"));
343 }
344 watch_list = Qnil; 341 watch_list = Qnil;
345 add_read_fd (inotifyfd, &inotify_callback, NULL); 342 add_read_fd (inotifyfd, &inotify_callback, NULL);
346 } 343 }
@@ -390,9 +387,9 @@ See inotify_rm_watch(2) for more information.
390 /* Cleanup if no more files are watched. */ 387 /* Cleanup if no more files are watched. */
391 if (NILP (watch_list)) 388 if (NILP (watch_list))
392 { 389 {
393 close (inotifyfd); 390 emacs_close (inotifyfd);
394 delete_read_fd (inotifyfd); 391 delete_read_fd (inotifyfd);
395 inotifyfd = uninitialized; 392 inotifyfd = -1;
396 } 393 }
397 394
398 return Qt; 395 return Qt;
diff --git a/src/keyboard.c b/src/keyboard.c
index 39535f5cd71..b6eb9e6ad15 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7008,7 +7008,7 @@ tty_read_avail_input (struct terminal *terminal,
7008 { 7008 {
7009 nread = emacs_read (fileno (tty->input), (char *) cbuf, n_to_read); 7009 nread = emacs_read (fileno (tty->input), (char *) cbuf, n_to_read);
7010 /* POSIX infers that processes which are not in the session leader's 7010 /* POSIX infers that processes which are not in the session leader's
7011 process group won't get SIGHUP's at logout time. BSDI adheres to 7011 process group won't get SIGHUPs at logout time. BSDI adheres to
7012 this part standard and returns -1 from read (0) with errno==EIO 7012 this part standard and returns -1 from read (0) with errno==EIO
7013 when the control tty is taken away. 7013 when the control tty is taken away.
7014 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */ 7014 Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
diff --git a/src/lisp.h b/src/lisp.h
index 9af69c61da8..acd21089655 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -365,9 +365,9 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
365#define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) 365#define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1))
366#define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 366#define case_Lisp_Int case Lisp_Int0: case Lisp_Int1
367 367
368/* Idea stolen from GDB. MSVC doesn't support enums in bitfields, 368/* Idea stolen from GDB. Pedantic GCC complains about enum bitfields,
369 and xlc complains vociferously about them. */ 369 MSVC doesn't support them, and xlc complains vociferously about them. */
370#if defined _MSC_VER || defined __IBMC__ 370#if defined __STRICT_ANSI__ || defined _MSC_VER || defined __IBMC__
371#define ENUM_BF(TYPE) unsigned int 371#define ENUM_BF(TYPE) unsigned int
372#else 372#else
373#define ENUM_BF(TYPE) enum TYPE 373#define ENUM_BF(TYPE) enum TYPE
@@ -400,7 +400,7 @@ enum Lisp_Type
400 /* Cons. XCONS (object) points to a struct Lisp_Cons. */ 400 /* Cons. XCONS (object) points to a struct Lisp_Cons. */
401 Lisp_Cons = 6, 401 Lisp_Cons = 6,
402 402
403 Lisp_Float = 7, 403 Lisp_Float = 7
404 }; 404 };
405 405
406/* This is the set of data types that share a common structure. 406/* This is the set of data types that share a common structure.
@@ -430,7 +430,7 @@ enum Lisp_Fwd_Type
430 Lisp_Fwd_Bool, /* Fwd to a C boolean var. */ 430 Lisp_Fwd_Bool, /* Fwd to a C boolean var. */
431 Lisp_Fwd_Obj, /* Fwd to a C Lisp_Object variable. */ 431 Lisp_Fwd_Obj, /* Fwd to a C Lisp_Object variable. */
432 Lisp_Fwd_Buffer_Obj, /* Fwd to a Lisp_Object field of buffers. */ 432 Lisp_Fwd_Buffer_Obj, /* Fwd to a Lisp_Object field of buffers. */
433 Lisp_Fwd_Kboard_Obj, /* Fwd to a Lisp_Object field of kboards. */ 433 Lisp_Fwd_Kboard_Obj /* Fwd to a Lisp_Object field of kboards. */
434 }; 434 };
435 435
436/* If you want to define a new Lisp data type, here are some 436/* If you want to define a new Lisp data type, here are some
@@ -2614,11 +2614,16 @@ CHECK_NUMBER_CDR (Lisp_Object x)
2614 minargs, maxargs, lname, intspec, 0}; \ 2614 minargs, maxargs, lname, intspec, 0}; \
2615 Lisp_Object fnname 2615 Lisp_Object fnname
2616#else /* not _MSC_VER */ 2616#else /* not _MSC_VER */
2617# if __STDC_VERSION__ < 199901
2618# define DEFUN_FUNCTION_INIT(fnname, maxargs) (Lisp_Object (*) (void)) fnname
2619# else
2620# define DEFUN_FUNCTION_INIT(fnname, maxargs) .a ## maxargs = fnname
2621# endif
2617#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ 2622#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
2618 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ 2623 Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
2619 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ 2624 static struct Lisp_Subr alignas (GCALIGNMENT) sname = \
2620 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ 2625 { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
2621 { .a ## maxargs = fnname }, \ 2626 { DEFUN_FUNCTION_INIT (fnname, maxargs) }, \
2622 minargs, maxargs, lname, intspec, 0}; \ 2627 minargs, maxargs, lname, intspec, 0}; \
2623 Lisp_Object fnname 2628 Lisp_Object fnname
2624#endif 2629#endif
@@ -3740,7 +3745,6 @@ extern Lisp_Object string_to_number (char const *, int, bool);
3740extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object), 3745extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
3741 Lisp_Object); 3746 Lisp_Object);
3742extern void dir_warning (const char *, Lisp_Object); 3747extern void dir_warning (const char *, Lisp_Object);
3743extern void close_load_descs (void);
3744extern void init_obarray (void); 3748extern void init_obarray (void);
3745extern void init_lread (void); 3749extern void init_lread (void);
3746extern void syms_of_lread (void); 3750extern void syms_of_lread (void);
@@ -3896,6 +3900,7 @@ extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
3896EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ 3900EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */
3897extern Lisp_Object close_file_unwind (Lisp_Object); 3901extern Lisp_Object close_file_unwind (Lisp_Object);
3898extern Lisp_Object restore_point_unwind (Lisp_Object); 3902extern Lisp_Object restore_point_unwind (Lisp_Object);
3903extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
3899extern _Noreturn void report_file_error (const char *, Lisp_Object); 3904extern _Noreturn void report_file_error (const char *, Lisp_Object);
3900extern bool internal_delete_file (Lisp_Object); 3905extern bool internal_delete_file (Lisp_Object);
3901extern Lisp_Object emacs_readlinkat (int, const char *); 3906extern Lisp_Object emacs_readlinkat (int, const char *);
@@ -4001,7 +4006,7 @@ extern Lisp_Object Qvisible;
4001extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); 4006extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
4002extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); 4007extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
4003extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object); 4008extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
4004#if HAVE_NS || defined(WINDOWSNT) 4009#if HAVE_NS || defined WINDOWSNT
4005extern Lisp_Object get_frame_param (struct frame *, Lisp_Object); 4010extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
4006#endif 4011#endif
4007extern void frames_discard_buffer (Lisp_Object); 4012extern void frames_discard_buffer (Lisp_Object);
@@ -4073,11 +4078,11 @@ extern void delete_keyboard_wait_descriptor (int);
4073extern void add_gpm_wait_descriptor (int); 4078extern void add_gpm_wait_descriptor (int);
4074extern void delete_gpm_wait_descriptor (int); 4079extern void delete_gpm_wait_descriptor (int);
4075#endif 4080#endif
4076extern void close_process_descs (void);
4077extern void init_process_emacs (void); 4081extern void init_process_emacs (void);
4078extern void syms_of_process (void); 4082extern void syms_of_process (void);
4079extern void setup_process_coding_systems (Lisp_Object); 4083extern void setup_process_coding_systems (Lisp_Object);
4080 4084
4085/* Defined in callproc.c. */
4081#ifndef DOS_NT 4086#ifndef DOS_NT
4082 _Noreturn 4087 _Noreturn
4083#endif 4088#endif
@@ -4169,6 +4174,8 @@ extern int emacs_open (const char *, int, int);
4169extern int emacs_close (int); 4174extern int emacs_close (int);
4170extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); 4175extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
4171extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); 4176extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t);
4177extern ptrdiff_t emacs_write_sig (int, char const *, ptrdiff_t);
4178extern void emacs_perror (char const *);
4172 4179
4173extern void unlock_all_files (void); 4180extern void unlock_all_files (void);
4174extern void lock_file (Lisp_Object); 4181extern void lock_file (Lisp_Object);
diff --git a/src/lread.c b/src/lread.c
index 06badce12be..f0423f166dd 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -95,9 +95,6 @@ static Lisp_Object Qload_in_progress;
95 It must be set to nil before all top-level calls to read0. */ 95 It must be set to nil before all top-level calls to read0. */
96static Lisp_Object read_objects; 96static Lisp_Object read_objects;
97 97
98/* List of descriptors now open for Fload. */
99static Lisp_Object load_descriptor_list;
100
101/* File for get_file_char to read from. Use by load. */ 98/* File for get_file_char to read from. Use by load. */
102static FILE *instream; 99static FILE *instream;
103 100
@@ -149,7 +146,6 @@ static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool,
149 Lisp_Object, Lisp_Object, 146 Lisp_Object, Lisp_Object,
150 Lisp_Object, Lisp_Object); 147 Lisp_Object, Lisp_Object);
151static Lisp_Object load_unwind (Lisp_Object); 148static Lisp_Object load_unwind (Lisp_Object);
152static Lisp_Object load_descriptor_unwind (Lisp_Object);
153 149
154/* Functions that read one byte from the current source READCHARFUN 150/* Functions that read one byte from the current source READCHARFUN
155 or unreads one byte. If the integer argument C is -1, it returns 151 or unreads one byte. If the integer argument C is -1, it returns
@@ -827,7 +823,7 @@ lisp_file_lexically_bound_p (Lisp_Object readcharfun)
827 { 823 {
828 bool rv = 0; 824 bool rv = 0;
829 enum { 825 enum {
830 NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX, 826 NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX
831 } beg_end_state = NOMINAL; 827 } beg_end_state = NOMINAL;
832 bool in_file_vars = 0; 828 bool in_file_vars = 0;
833 829
@@ -1328,11 +1324,8 @@ Return t if the file exists and loads successfully. */)
1328 } 1324 }
1329 1325
1330 record_unwind_protect (load_unwind, make_save_pointer (stream)); 1326 record_unwind_protect (load_unwind, make_save_pointer (stream));
1331 record_unwind_protect (load_descriptor_unwind, load_descriptor_list);
1332 specbind (Qload_file_name, found); 1327 specbind (Qload_file_name, found);
1333 specbind (Qinhibit_file_name_operation, Qnil); 1328 specbind (Qinhibit_file_name_operation, Qnil);
1334 load_descriptor_list
1335 = Fcons (make_number (fileno (stream)), load_descriptor_list);
1336 specbind (Qload_in_progress, Qt); 1329 specbind (Qload_in_progress, Qt);
1337 1330
1338 instream = stream; 1331 instream = stream;
@@ -1395,26 +1388,6 @@ load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */
1395 } 1388 }
1396 return Qnil; 1389 return Qnil;
1397} 1390}
1398
1399static Lisp_Object
1400load_descriptor_unwind (Lisp_Object oldlist)
1401{
1402 load_descriptor_list = oldlist;
1403 return Qnil;
1404}
1405
1406/* Close all descriptors in use for Floads.
1407 This is used when starting a subprocess. */
1408
1409void
1410close_load_descs (void)
1411{
1412#ifndef WINDOWSNT
1413 Lisp_Object tail;
1414 for (tail = load_descriptor_list; CONSP (tail); tail = XCDR (tail))
1415 emacs_close (XFASTINT (XCAR (tail)));
1416#endif
1417}
1418 1391
1419static bool 1392static bool
1420complete_filename_p (Lisp_Object pathname) 1393complete_filename_p (Lisp_Object pathname)
@@ -1439,8 +1412,8 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
1439{ 1412{
1440 Lisp_Object file; 1413 Lisp_Object file;
1441 int fd = openp (path, filename, suffixes, &file, predicate); 1414 int fd = openp (path, filename, suffixes, &file, predicate);
1442 if (NILP (predicate) && fd > 0) 1415 if (NILP (predicate) && fd >= 0)
1443 close (fd); 1416 emacs_close (fd);
1444 return file; 1417 return file;
1445} 1418}
1446 1419
@@ -1448,14 +1421,15 @@ static Lisp_Object Qdir_ok;
1448 1421
1449/* Search for a file whose name is STR, looking in directories 1422/* Search for a file whose name is STR, looking in directories
1450 in the Lisp list PATH, and trying suffixes from SUFFIX. 1423 in the Lisp list PATH, and trying suffixes from SUFFIX.
1451 On success, returns a file descriptor. On failure, returns -1. 1424 On success, return a file descriptor (or 1 or -2 as described below).
1425 On failure, return -1 and set errno.
1452 1426
1453 SUFFIXES is a list of strings containing possible suffixes. 1427 SUFFIXES is a list of strings containing possible suffixes.
1454 The empty suffix is automatically added if the list is empty. 1428 The empty suffix is automatically added if the list is empty.
1455 1429
1456 PREDICATE non-nil means don't open the files, 1430 PREDICATE non-nil means don't open the files,
1457 just look for one that satisfies the predicate. In this case, 1431 just look for one that satisfies the predicate. In this case,
1458 returns 1 on success. The predicate can be a lisp function or 1432 return 1 on success. The predicate can be a lisp function or
1459 an integer to pass to `access' (in which case file-name-handlers 1433 an integer to pass to `access' (in which case file-name-handlers
1460 are ignored). 1434 are ignored).
1461 1435
@@ -1467,7 +1441,8 @@ static Lisp_Object Qdir_ok;
1467 but store the found remote file name in *STOREPTR. */ 1441 but store the found remote file name in *STOREPTR. */
1468 1442
1469int 1443int
1470openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) 1444openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1445 Lisp_Object *storeptr, Lisp_Object predicate)
1471{ 1446{
1472 ptrdiff_t fn_size = 100; 1447 ptrdiff_t fn_size = 100;
1473 char buf[100]; 1448 char buf[100];
@@ -1478,6 +1453,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1478 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 1453 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1479 Lisp_Object string, tail, encoded_fn; 1454 Lisp_Object string, tail, encoded_fn;
1480 ptrdiff_t max_suffix_len = 0; 1455 ptrdiff_t max_suffix_len = 0;
1456 int last_errno = ENOENT;
1481 1457
1482 CHECK_STRING (str); 1458 CHECK_STRING (str);
1483 1459
@@ -1547,14 +1523,22 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1547 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1523 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1548 { 1524 {
1549 bool exists; 1525 bool exists;
1526 last_errno = ENOENT;
1550 if (NILP (predicate)) 1527 if (NILP (predicate))
1551 exists = !NILP (Ffile_readable_p (string)); 1528 exists = !NILP (Ffile_readable_p (string));
1552 else 1529 else
1553 { 1530 {
1554 Lisp_Object tmp = call1 (predicate, string); 1531 Lisp_Object tmp = call1 (predicate, string);
1555 exists = !NILP (tmp) 1532 if (NILP (tmp))
1556 && (EQ (tmp, Qdir_ok) 1533 exists = 0;
1557 || NILP (Ffile_directory_p (string))); 1534 else if (EQ (tmp, Qdir_ok)
1535 || NILP (Ffile_directory_p (string)))
1536 exists = 1;
1537 else
1538 {
1539 exists = 0;
1540 last_errno = EISDIR;
1541 }
1558 } 1542 }
1559 1543
1560 if (exists) 1544 if (exists)
@@ -1576,21 +1560,36 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1576 1560
1577 /* Check that we can access or open it. */ 1561 /* Check that we can access or open it. */
1578 if (NATNUMP (predicate)) 1562 if (NATNUMP (predicate))
1579 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 1563 {
1580 && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate), 1564 fd = -1;
1565 if (INT_MAX < XFASTINT (predicate))
1566 last_errno = EINVAL;
1567 else if (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
1581 AT_EACCESS) 1568 AT_EACCESS)
1582 == 0) 1569 == 0)
1583 && ! file_directory_p (pfn)) 1570 {
1584 ? 1 : -1); 1571 if (file_directory_p (pfn))
1572 last_errno = EISDIR;
1573 else
1574 fd = 1;
1575 }
1576 }
1585 else 1577 else
1586 { 1578 {
1587 struct stat st;
1588 fd = emacs_open (pfn, O_RDONLY, 0); 1579 fd = emacs_open (pfn, O_RDONLY, 0);
1589 if (fd >= 0 1580 if (fd < 0)
1590 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode))) 1581 last_errno = errno;
1582 else
1591 { 1583 {
1592 emacs_close (fd); 1584 struct stat st;
1593 fd = -1; 1585 int err = (fstat (fd, &st) != 0 ? errno
1586 : S_ISDIR (st.st_mode) ? EISDIR : 0);
1587 if (err)
1588 {
1589 last_errno = err;
1590 emacs_close (fd);
1591 fd = -1;
1592 }
1594 } 1593 }
1595 } 1594 }
1596 1595
@@ -1609,6 +1608,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1609 } 1608 }
1610 1609
1611 UNGCPRO; 1610 UNGCPRO;
1611 errno = last_errno;
1612 return -1; 1612 return -1;
1613} 1613}
1614 1614
@@ -4349,9 +4349,6 @@ init_lread (void)
4349 4349
4350 load_in_progress = 0; 4350 load_in_progress = 0;
4351 Vload_file_name = Qnil; 4351 Vload_file_name = Qnil;
4352
4353 load_descriptor_list = Qnil;
4354
4355 Vstandard_input = Qt; 4352 Vstandard_input = Qt;
4356 Vloads_in_progress = Qnil; 4353 Vloads_in_progress = Qnil;
4357} 4354}
@@ -4624,9 +4621,6 @@ variables, this must be set in the first line of a file. */);
4624 4621
4625 /* Vsource_directory was initialized in init_lread. */ 4622 /* Vsource_directory was initialized in init_lread. */
4626 4623
4627 load_descriptor_list = Qnil;
4628 staticpro (&load_descriptor_list);
4629
4630 DEFSYM (Qcurrent_load_list, "current-load-list"); 4624 DEFSYM (Qcurrent_load_list, "current-load-list");
4631 DEFSYM (Qstandard_input, "standard-input"); 4625 DEFSYM (Qstandard_input, "standard-input");
4632 DEFSYM (Qread_char, "read-char"); 4626 DEFSYM (Qread_char, "read-char");
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index 272b053ed12..f4885580e1c 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -813,7 +813,6 @@ $(BLD)/emacs.$(O) : \
813 $(NT_INC)/sys/file.h \ 813 $(NT_INC)/sys/file.h \
814 $(NT_INC)/unistd.h \ 814 $(NT_INC)/unistd.h \
815 $(GNU_LIB)/close-stream.h \ 815 $(GNU_LIB)/close-stream.h \
816 $(GNU_LIB)/ignore-value.h \
817 $(ATIMER_H) \ 816 $(ATIMER_H) \
818 $(BUFFER_H) \ 817 $(BUFFER_H) \
819 $(CHARACTER_H) \ 818 $(CHARACTER_H) \
@@ -1407,7 +1406,6 @@ $(BLD)/sysdep.$(O) : \
1407 $(NT_INC)/sys/stat.h \ 1406 $(NT_INC)/sys/stat.h \
1408 $(NT_INC)/unistd.h \ 1407 $(NT_INC)/unistd.h \
1409 $(GNU_LIB)/execinfo.h \ 1408 $(GNU_LIB)/execinfo.h \
1410 $(GNU_LIB)/ignore-value.h \
1411 $(GNU_LIB)/utimens.h \ 1409 $(GNU_LIB)/utimens.h \
1412 $(CONFIG_H) \ 1410 $(CONFIG_H) \
1413 $(C_CTYPE_H) \ 1411 $(C_CTYPE_H) \
diff --git a/src/nsfns.m b/src/nsfns.m
index b8f46e461fa..6eebb4d2567 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -885,7 +885,7 @@ ns_appkit_version_str (void)
885 885
886#ifdef NS_IMPL_GNUSTEP 886#ifdef NS_IMPL_GNUSTEP
887 sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION)); 887 sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION));
888#elif defined(NS_IMPL_COCOA) 888#elif defined (NS_IMPL_COCOA)
889 sprintf(tmp, "apple-appkit-%.2f", NSAppKitVersionNumber); 889 sprintf(tmp, "apple-appkit-%.2f", NSAppKitVersionNumber);
890#else 890#else
891 tmp = "ns-unknown"; 891 tmp = "ns-unknown";
@@ -902,7 +902,7 @@ ns_appkit_version_int (void)
902{ 902{
903#ifdef NS_IMPL_GNUSTEP 903#ifdef NS_IMPL_GNUSTEP
904 return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION; 904 return GNUSTEP_GUI_MAJOR_VERSION * 100 + GNUSTEP_GUI_MINOR_VERSION;
905#elif defined(NS_IMPL_COCOA) 905#elif defined (NS_IMPL_COCOA)
906 return (int)NSAppKitVersionNumber; 906 return (int)NSAppKitVersionNumber;
907#endif 907#endif
908 return 0; 908 return 0;
@@ -2493,7 +2493,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
2493 vy = (short) (primary_display_height - 2493 vy = (short) (primary_display_height -
2494 vfr.size.height - vfr.origin.y); 2494 vfr.size.height - vfr.origin.y);
2495 } 2495 }
2496 2496
2497 m->geom.x = (short) fr.origin.x; 2497 m->geom.x = (short) fr.origin.x;
2498 m->geom.y = y; 2498 m->geom.y = y;
2499 m->geom.width = (unsigned short) fr.size.width; 2499 m->geom.width = (unsigned short) fr.size.width;
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 1d3d111e9a1..22635dca0a2 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -612,8 +612,8 @@ extern NSString *NSMenuDidBeginTrackingNotification;
612 if (trackingMenu == 0) 612 if (trackingMenu == 0)
613 return; 613 return;
614/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */ 614/*fprintf (stderr, "Updating menu '%s'\n", [[self title] UTF8String]); NSLog (@"%@\n", event); */
615#if ! defined(NS_IMPL_COCOA) || \ 615#if (! defined (NS_IMPL_COCOA) \
616 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 616 || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
617 /* Don't know how to do this for anything other than OSX >= 10.5 617 /* Don't know how to do this for anything other than OSX >= 10.5
618 This is wrong, as it might run Lisp code in the event loop. */ 618 This is wrong, as it might run Lisp code in the event loop. */
619 ns_update_menubar (frame, true, self); 619 ns_update_menubar (frame, true, self);
@@ -1240,7 +1240,7 @@ update_frame_tool_bar (FRAME_PTR f)
1240#ifdef NS_IMPL_GNUSTEP 1240#ifdef NS_IMPL_GNUSTEP
1241 [self insertItemWithItemIdentifier: identifier atIndex: idx]; 1241 [self insertItemWithItemIdentifier: identifier atIndex: idx];
1242#endif 1242#endif
1243 1243
1244 [item setTag: tag]; 1244 [item setTag: tag];
1245 [item setEnabled: enabled]; 1245 [item setEnabled: enabled];
1246 1246
diff --git a/src/nsterm.m b/src/nsterm.m
index 97a6313489d..d7cea5c189a 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -3603,7 +3603,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3603 3603
3604 /* Inform fd_handler that select should be called */ 3604 /* Inform fd_handler that select should be called */
3605 c = 'g'; 3605 c = 'g';
3606 emacs_write (selfds[1], &c, 1); 3606 emacs_write_sig (selfds[1], &c, 1);
3607 } 3607 }
3608 else if (nr == 0 && timeout) 3608 else if (nr == 0 && timeout)
3609 { 3609 {
@@ -3636,7 +3636,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3636 if (nr > 0 && readfds) 3636 if (nr > 0 && readfds)
3637 { 3637 {
3638 c = 's'; 3638 c = 's';
3639 emacs_write (selfds[1], &c, 1); 3639 emacs_write_sig (selfds[1], &c, 1);
3640 } 3640 }
3641 unblock_input (); 3641 unblock_input ();
3642 3642
@@ -4142,7 +4142,7 @@ ns_term_init (Lisp_Object display_name)
4142 4142
4143 if (selfds[0] == -1) 4143 if (selfds[0] == -1)
4144 { 4144 {
4145 if (pipe (selfds) == -1) 4145 if (pipe2 (selfds, O_CLOEXEC) != 0)
4146 { 4146 {
4147 fprintf (stderr, "Failed to create pipe: %s\n", 4147 fprintf (stderr, "Failed to create pipe: %s\n",
4148 emacs_strerror (errno)); 4148 emacs_strerror (errno));
@@ -4419,6 +4419,16 @@ ns_term_shutdown (int sig)
4419/* NSTRACE (sendEvent); */ 4419/* NSTRACE (sendEvent); */
4420/*fprintf (stderr, "received event of type %d\t%d\n", type);*/ 4420/*fprintf (stderr, "received event of type %d\t%d\n", type);*/
4421 4421
4422#ifdef NS_IMPL_GNUSTEP
4423 // Keyboard events aren't propagated to file dialogs for some reason.
4424 if ([NSApp modalWindow] != nil &&
4425 (type == NSKeyDown || type == NSKeyUp || type == NSFlagsChanged))
4426 {
4427 [[NSApp modalWindow] sendEvent: theEvent];
4428 return;
4429 }
4430#endif
4431
4422 if (type == NSApplicationDefined) 4432 if (type == NSApplicationDefined)
4423 { 4433 {
4424 switch ([theEvent data2]) 4434 switch ([theEvent data2])
diff --git a/src/print.c b/src/print.c
index 09519d93cfe..01e490dcbad 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1765,9 +1765,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1765 } 1765 }
1766 else if (WINDOWP (obj)) 1766 else if (WINDOWP (obj))
1767 { 1767 {
1768 int len; 1768 void *ptr = XWINDOW (obj);
1769 strout ("#<window ", -1, -1, printcharfun); 1769 int len = sprintf (buf, "#<window %p", ptr);
1770 len = sprintf (buf, "%p", XWINDOW (obj));
1771 strout (buf, len, len, printcharfun); 1770 strout (buf, len, len, printcharfun);
1772 if (BUFFERP (XWINDOW (obj)->contents)) 1771 if (BUFFERP (XWINDOW (obj)->contents))
1773 { 1772 {
@@ -1798,6 +1797,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1798 ptrdiff_t real_size, size; 1797 ptrdiff_t real_size, size;
1799 int len; 1798 int len;
1800#if 0 1799#if 0
1800 void *ptr = h;
1801 strout ("#<hash-table", -1, -1, printcharfun); 1801 strout ("#<hash-table", -1, -1, printcharfun);
1802 if (SYMBOLP (h->test)) 1802 if (SYMBOLP (h->test))
1803 { 1803 {
@@ -1810,9 +1810,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1810 len = sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next)); 1810 len = sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next));
1811 strout (buf, len, len, printcharfun); 1811 strout (buf, len, len, printcharfun);
1812 } 1812 }
1813 len = sprintf (buf, " %p", h); 1813 len = sprintf (buf, " %p>", ptr);
1814 strout (buf, len, len, printcharfun); 1814 strout (buf, len, len, printcharfun);
1815 PRINTCHAR ('>');
1816#endif 1815#endif
1817 /* Implement a readable output, e.g.: 1816 /* Implement a readable output, e.g.:
1818 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ 1817 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
@@ -1892,6 +1891,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1892 else if (FRAMEP (obj)) 1891 else if (FRAMEP (obj))
1893 { 1892 {
1894 int len; 1893 int len;
1894 void *ptr = XFRAME (obj);
1895 Lisp_Object frame_name = XFRAME (obj)->name; 1895 Lisp_Object frame_name = XFRAME (obj)->name;
1896 1896
1897 strout ((FRAME_LIVE_P (XFRAME (obj)) 1897 strout ((FRAME_LIVE_P (XFRAME (obj))
@@ -1907,9 +1907,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
1907 frame_name = build_string ("*INVALID*FRAME*NAME*"); 1907 frame_name = build_string ("*INVALID*FRAME*NAME*");
1908 } 1908 }
1909 print_string (frame_name, printcharfun); 1909 print_string (frame_name, printcharfun);
1910 len = sprintf (buf, " %p", XFRAME (obj)); 1910 len = sprintf (buf, " %p>", ptr);
1911 strout (buf, len, len, printcharfun); 1911 strout (buf, len, len, printcharfun);
1912 PRINTCHAR ('>');
1913 } 1912 }
1914 else if (FONTP (obj)) 1913 else if (FONTP (obj))
1915 { 1914 {
diff --git a/src/process.c b/src/process.c
index 2e2610ffde4..dc37bfe7067 100644
--- a/src/process.c
+++ b/src/process.c
@@ -135,6 +135,37 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
135 EMACS_TIME *, void *); 135 EMACS_TIME *, void *);
136#endif 136#endif
137 137
138#ifndef SOCK_CLOEXEC
139# define SOCK_CLOEXEC 0
140#endif
141
142#ifndef HAVE_ACCEPT4
143
144/* Emulate GNU/Linux accept4 and socket well enough for this module. */
145
146static int
147close_on_exec (int fd)
148{
149 if (0 <= fd)
150 fcntl (fd, F_SETFD, FD_CLOEXEC);
151 return fd;
152}
153
154static int
155accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
156{
157 return close_on_exec (accept (sockfd, addr, addrlen));
158}
159
160static int
161process_socket (int domain, int type, int protocol)
162{
163 return close_on_exec (socket (domain, type, protocol));
164}
165# undef socket
166# define socket(domain, type, protocol) process_socket (domain, type, protocol)
167#endif
168
138/* Work around GCC 4.7.0 bug with strict overflow checking; see 169/* Work around GCC 4.7.0 bug with strict overflow checking; see
139 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. 170 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
140 These lines can be removed once the GCC bug is fixed. */ 171 These lines can be removed once the GCC bug is fixed. */
@@ -1782,6 +1813,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1782{ 1813{
1783 int inchannel, outchannel; 1814 int inchannel, outchannel;
1784 pid_t pid; 1815 pid_t pid;
1816 int vfork_errno;
1785 int sv[2]; 1817 int sv[2];
1786#ifndef WINDOWSNT 1818#ifndef WINDOWSNT
1787 int wait_child_setup[2]; 1819 int wait_child_setup[2];
@@ -1816,47 +1848,30 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1816 else 1848 else
1817#endif /* HAVE_PTYS */ 1849#endif /* HAVE_PTYS */
1818 { 1850 {
1819 int tem; 1851 if (pipe2 (sv, O_CLOEXEC) != 0)
1820 tem = pipe (sv);
1821 if (tem < 0)
1822 report_file_error ("Creating pipe", Qnil); 1852 report_file_error ("Creating pipe", Qnil);
1823 inchannel = sv[0]; 1853 inchannel = sv[0];
1824 forkout = sv[1]; 1854 forkout = sv[1];
1825 tem = pipe (sv); 1855 if (pipe2 (sv, O_CLOEXEC) != 0)
1826 if (tem < 0)
1827 { 1856 {
1857 int pipe_errno = errno;
1828 emacs_close (inchannel); 1858 emacs_close (inchannel);
1829 emacs_close (forkout); 1859 emacs_close (forkout);
1830 report_file_error ("Creating pipe", Qnil); 1860 report_file_errno ("Creating pipe", Qnil, pipe_errno);
1831 } 1861 }
1832 outchannel = sv[1]; 1862 outchannel = sv[1];
1833 forkin = sv[0]; 1863 forkin = sv[0];
1834 } 1864 }
1835 1865
1836#ifndef WINDOWSNT 1866#ifndef WINDOWSNT
1837 { 1867 if (pipe2 (wait_child_setup, O_CLOEXEC) != 0)
1838 int tem; 1868 report_file_error ("Creating pipe", Qnil);
1839
1840 tem = pipe (wait_child_setup);
1841 if (tem < 0)
1842 report_file_error ("Creating pipe", Qnil);
1843 tem = fcntl (wait_child_setup[1], F_GETFD, 0);
1844 if (tem >= 0)
1845 tem = fcntl (wait_child_setup[1], F_SETFD, tem | FD_CLOEXEC);
1846 if (tem < 0)
1847 {
1848 emacs_close (wait_child_setup[0]);
1849 emacs_close (wait_child_setup[1]);
1850 report_file_error ("Setting file descriptor flags", Qnil);
1851 }
1852 }
1853#endif 1869#endif
1854 1870
1855 fcntl (inchannel, F_SETFL, O_NONBLOCK); 1871 fcntl (inchannel, F_SETFL, O_NONBLOCK);
1856 fcntl (outchannel, F_SETFL, O_NONBLOCK); 1872 fcntl (outchannel, F_SETFL, O_NONBLOCK);
1857 1873
1858 /* Record this as an active process, with its channels. 1874 /* Record this as an active process, with its channels. */
1859 As a result, child_setup will close Emacs's side of the pipes. */
1860 chan_process[inchannel] = process; 1875 chan_process[inchannel] = process;
1861 XPROCESS (process)->infd = inchannel; 1876 XPROCESS (process)->infd = inchannel;
1862 XPROCESS (process)->outfd = outchannel; 1877 XPROCESS (process)->outfd = outchannel;
@@ -1933,7 +1948,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1933 tcgetattr (xforkin, &t); 1948 tcgetattr (xforkin, &t);
1934 t.c_lflag = LDISC1; 1949 t.c_lflag = LDISC1;
1935 if (tcsetattr (xforkin, TCSANOW, &t) < 0) 1950 if (tcsetattr (xforkin, TCSANOW, &t) < 0)
1936 emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39); 1951 emacs_perror ("create_process/tcsetattr LDISC1");
1937 } 1952 }
1938#else 1953#else
1939#if defined (NTTYDISC) && defined (TIOCSETD) 1954#if defined (NTTYDISC) && defined (TIOCSETD)
@@ -1980,10 +1995,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1980 1995
1981 if (xforkin < 0) 1996 if (xforkin < 0)
1982 { 1997 {
1983 emacs_write (1, "Couldn't open the pty terminal ", 31); 1998 emacs_perror (pty_name);
1984 emacs_write (1, pty_name, strlen (pty_name)); 1999 _exit (EXIT_CANCELED);
1985 emacs_write (1, "\n", 1);
1986 _exit (1);
1987 } 2000 }
1988 2001
1989 } 2002 }
@@ -1995,12 +2008,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1995 SETUP_SLAVE_PTY; 2008 SETUP_SLAVE_PTY;
1996 } 2009 }
1997#endif /* SETUP_SLAVE_PTY */ 2010#endif /* SETUP_SLAVE_PTY */
1998#ifdef AIX
1999 /* On AIX, we've disabled SIGHUP above once we start a child on a pty.
2000 Now reenable it in the child, so it will die when we want it to. */
2001 if (pty_flag)
2002 signal (SIGHUP, SIG_DFL);
2003#endif
2004#endif /* HAVE_PTYS */ 2011#endif /* HAVE_PTYS */
2005 2012
2006 signal (SIGINT, SIG_DFL); 2013 signal (SIGINT, SIG_DFL);
@@ -2026,6 +2033,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2026 2033
2027 /* Back in the parent process. */ 2034 /* Back in the parent process. */
2028 2035
2036 vfork_errno = errno;
2029 XPROCESS (process)->pid = pid; 2037 XPROCESS (process)->pid = pid;
2030 if (pid >= 0) 2038 if (pid >= 0)
2031 XPROCESS (process)->alive = 1; 2039 XPROCESS (process)->alive = 1;
@@ -2040,6 +2048,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2040 emacs_close (forkin); 2048 emacs_close (forkin);
2041 if (forkin != forkout && forkout >= 0) 2049 if (forkin != forkout && forkout >= 0)
2042 emacs_close (forkout); 2050 emacs_close (forkout);
2051 report_file_errno ("Doing vfork", Qnil, vfork_errno);
2043 } 2052 }
2044 else 2053 else
2045 { 2054 {
@@ -2085,10 +2094,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
2085 } 2094 }
2086#endif 2095#endif
2087 } 2096 }
2088
2089 /* Now generate the error if vfork failed. */
2090 if (pid < 0)
2091 report_file_error ("Doing vfork", Qnil);
2092} 2097}
2093 2098
2094void 2099void
@@ -3323,7 +3328,8 @@ usage: (make-network-process &rest ARGS) */)
3323 retry_connect: 3328 retry_connect:
3324#endif 3329#endif
3325 3330
3326 s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); 3331 s = socket (lres->ai_family, lres->ai_socktype | SOCK_CLOEXEC,
3332 lres->ai_protocol);
3327 if (s < 0) 3333 if (s < 0)
3328 { 3334 {
3329 xerrno = errno; 3335 xerrno = errno;
@@ -3447,12 +3453,11 @@ usage: (make-network-process &rest ARGS) */)
3447 3453
3448 len = sizeof xerrno; 3454 len = sizeof xerrno;
3449 eassert (FD_ISSET (s, &fdset)); 3455 eassert (FD_ISSET (s, &fdset));
3450 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) 3456 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3451 report_file_error ("getsockopt failed", Qnil); 3457 report_file_error ("getsockopt failed", Qnil);
3452 if (xerrno) 3458 if (xerrno)
3453 errno = xerrno, report_file_error ("error during connect", Qnil); 3459 report_file_errno ("error during connect", Qnil, xerrno);
3454 else 3460 break;
3455 break;
3456 } 3461 }
3457#endif /* !WINDOWSNT */ 3462#endif /* !WINDOWSNT */
3458 3463
@@ -3536,11 +3541,10 @@ usage: (make-network-process &rest ARGS) */)
3536 if (is_non_blocking_client) 3541 if (is_non_blocking_client)
3537 return Qnil; 3542 return Qnil;
3538 3543
3539 errno = xerrno; 3544 report_file_errno ((is_server
3540 if (is_server) 3545 ? "make server process failed"
3541 report_file_error ("make server process failed", contact); 3546 : "make client process failed"),
3542 else 3547 contact, xerrno);
3543 report_file_error ("make client process failed", contact);
3544 } 3548 }
3545 3549
3546 inch = s; 3550 inch = s;
@@ -3713,7 +3717,7 @@ format; see the description of ADDRESS in `make-network-process'. */)
3713 int s; 3717 int s;
3714 Lisp_Object res; 3718 Lisp_Object res;
3715 3719
3716 s = socket (AF_INET, SOCK_STREAM, 0); 3720 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3717 if (s < 0) 3721 if (s < 0)
3718 return Qnil; 3722 return Qnil;
3719 3723
@@ -3724,14 +3728,14 @@ format; see the description of ADDRESS in `make-network-process'. */)
3724 ifconf.ifc_len = buf_size; 3728 ifconf.ifc_len = buf_size;
3725 if (ioctl (s, SIOCGIFCONF, &ifconf)) 3729 if (ioctl (s, SIOCGIFCONF, &ifconf))
3726 { 3730 {
3727 close (s); 3731 emacs_close (s);
3728 xfree (buf); 3732 xfree (buf);
3729 return Qnil; 3733 return Qnil;
3730 } 3734 }
3731 } 3735 }
3732 while (ifconf.ifc_len == buf_size); 3736 while (ifconf.ifc_len == buf_size);
3733 3737
3734 close (s); 3738 emacs_close (s);
3735 3739
3736 res = Qnil; 3740 res = Qnil;
3737 ifreq = ifconf.ifc_req; 3741 ifreq = ifconf.ifc_req;
@@ -3869,7 +3873,7 @@ FLAGS is the current flags of the interface. */)
3869 error ("interface name too long"); 3873 error ("interface name too long");
3870 strcpy (rq.ifr_name, SSDATA (ifname)); 3874 strcpy (rq.ifr_name, SSDATA (ifname));
3871 3875
3872 s = socket (AF_INET, SOCK_STREAM, 0); 3876 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
3873 if (s < 0) 3877 if (s < 0)
3874 return Qnil; 3878 return Qnil;
3875 3879
@@ -3988,7 +3992,7 @@ FLAGS is the current flags of the interface. */)
3988#endif 3992#endif
3989 res = Fcons (elt, res); 3993 res = Fcons (elt, res);
3990 3994
3991 close (s); 3995 emacs_close (s);
3992 3996
3993 return any ? res : Qnil; 3997 return any ? res : Qnil;
3994} 3998}
@@ -4161,7 +4165,7 @@ server_accept_connection (Lisp_Object server, int channel)
4161 } saddr; 4165 } saddr;
4162 socklen_t len = sizeof saddr; 4166 socklen_t len = sizeof saddr;
4163 4167
4164 s = accept (channel, &saddr.sa, &len); 4168 s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC);
4165 4169
4166 if (s < 0) 4170 if (s < 0)
4167 { 4171 {
@@ -4785,20 +4789,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4785 if (xerrno == EINTR) 4789 if (xerrno == EINTR)
4786 no_avail = 1; 4790 no_avail = 1;
4787 else if (xerrno == EBADF) 4791 else if (xerrno == EBADF)
4788 { 4792 emacs_abort ();
4789#ifdef AIX
4790 /* AIX doesn't handle PTY closure the same way BSD does. On AIX,
4791 the child's closure of the pts gives the parent a SIGHUP, and
4792 the ptc file descriptor is automatically closed,
4793 yielding EBADF here or at select() call above.
4794 So, SIGHUP is ignored (see def of PTY_TTY_NAME_SPRINTF
4795 in m/ibmrt-aix.h), and here we just ignore the select error.
4796 Cleanup occurs c/o status_notify after SIGCHLD. */
4797 no_avail = 1; /* Cannot depend on values returned */
4798#else
4799 emacs_abort ();
4800#endif
4801 }
4802 else 4793 else
4803 error ("select error: %s", emacs_strerror (xerrno)); 4794 error ("select error: %s", emacs_strerror (xerrno));
4804 } 4795 }
@@ -5648,7 +5639,7 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5648 written = emacs_gnutls_write (p, cur_buf, cur_len); 5639 written = emacs_gnutls_write (p, cur_buf, cur_len);
5649 else 5640 else
5650#endif 5641#endif
5651 written = emacs_write (outfd, cur_buf, cur_len); 5642 written = emacs_write_sig (outfd, cur_buf, cur_len);
5652 rv = (written ? 0 : -1); 5643 rv = (written ? 0 : -1);
5653#ifdef ADAPTIVE_READ_BUFFERING 5644#ifdef ADAPTIVE_READ_BUFFERING
5654 if (p->read_output_delay > 0 5645 if (p->read_output_delay > 0
@@ -7010,32 +7001,6 @@ setup_process_coding_systems (Lisp_Object process)
7010#endif 7001#endif
7011} 7002}
7012 7003
7013/* Close all descriptors currently in use for communication
7014 with subprocess. This is used in a newly-forked subprocess
7015 to get rid of irrelevant descriptors. */
7016
7017void
7018close_process_descs (void)
7019{
7020#ifndef DOS_NT
7021 int i;
7022 for (i = 0; i < MAXDESC; i++)
7023 {
7024 Lisp_Object process;
7025 process = chan_process[i];
7026 if (!NILP (process))
7027 {
7028 int in = XPROCESS (process)->infd;
7029 int out = XPROCESS (process)->outfd;
7030 if (in >= 0)
7031 emacs_close (in);
7032 if (out >= 0 && in != out)
7033 emacs_close (out);
7034 }
7035 }
7036#endif
7037}
7038
7039DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, 7004DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0,
7040 doc: /* Return the (or a) process associated with BUFFER. 7005 doc: /* Return the (or a) process associated with BUFFER.
7041BUFFER may be a buffer or the name of one. */) 7006BUFFER may be a buffer or the name of one. */)
diff --git a/src/process.h b/src/process.h
index 52142e55e94..89c7e8b1259 100644
--- a/src/process.h
+++ b/src/process.h
@@ -201,6 +201,14 @@ extern Lisp_Object QCspeed;
201extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven; 201extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
202extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary; 202extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
203 203
204/* Exit statuses for GNU programs that exec other programs. */
205enum
206{
207 EXIT_CANCELED = 125, /* Internal error prior to exec attempt. */
208 EXIT_CANNOT_INVOKE = 126, /* Program located, but not usable. */
209 EXIT_ENOENT = 127 /* Could not find program to exec. */
210};
211
204/* Defined in callproc.c. */ 212/* Defined in callproc.c. */
205 213
206extern void block_child_signal (void); 214extern void block_child_signal (void);
diff --git a/src/profiler.c b/src/profiler.c
index aba81344c68..c86fb47d21d 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -568,12 +568,12 @@ to make room for new entries. */);
568 profiler_log_size = 10000; 568 profiler_log_size = 10000;
569 569
570 DEFSYM (Qprofiler_backtrace_equal, "profiler-backtrace-equal"); 570 DEFSYM (Qprofiler_backtrace_equal, "profiler-backtrace-equal");
571 { 571
572 struct hash_table_test test 572 hashtest_profiler.name = Qprofiler_backtrace_equal;
573 = { Qprofiler_backtrace_equal, Qnil, Qnil, 573 hashtest_profiler.user_hash_function = Qnil;
574 cmpfn_profiler, hashfn_profiler }; 574 hashtest_profiler.user_cmp_function = Qnil;
575 hashtest_profiler = test; 575 hashtest_profiler.cmpfn = cmpfn_profiler;
576 } 576 hashtest_profiler.hashfn = hashfn_profiler;
577 577
578 defsubr (&Sfunction_equal); 578 defsubr (&Sfunction_equal);
579 579
diff --git a/src/regex.c b/src/regex.c
index 73a735cea65..5024f748884 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -531,8 +531,10 @@ init_syntax_once (void)
531/* Type of source-pattern and string chars. */ 531/* Type of source-pattern and string chars. */
532#ifdef _MSC_VER 532#ifdef _MSC_VER
533typedef unsigned char re_char; 533typedef unsigned char re_char;
534typedef const re_char const_re_char;
534#else 535#else
535typedef const unsigned char re_char; 536typedef const unsigned char re_char;
537typedef re_char const_re_char;
536#endif 538#endif
537 539
538typedef char boolean; 540typedef char boolean;
@@ -2019,7 +2021,7 @@ struct range_table_work_area
2019 2021
2020/* Map a string to the char class it names (if any). */ 2022/* Map a string to the char class it names (if any). */
2021re_wctype_t 2023re_wctype_t
2022re_wctype (const re_char *str) 2024re_wctype (const_re_char *str)
2023{ 2025{
2024 const char *string = (const char *) str; 2026 const char *string = (const char *) str;
2025 if (STREQ (string, "alnum")) return RECC_ALNUM; 2027 if (STREQ (string, "alnum")) return RECC_ALNUM;
@@ -2413,7 +2415,8 @@ do { \
2413 } while (0) 2415 } while (0)
2414 2416
2415static reg_errcode_t 2417static reg_errcode_t
2416regex_compile (const re_char *pattern, size_t size, reg_syntax_t syntax, struct re_pattern_buffer *bufp) 2418regex_compile (const_re_char *pattern, size_t size, reg_syntax_t syntax,
2419 struct re_pattern_buffer *bufp)
2417{ 2420{
2418 /* We fetch characters from PATTERN here. */ 2421 /* We fetch characters from PATTERN here. */
2419 register re_wchar_t c, c1; 2422 register re_wchar_t c, c1;
@@ -3769,7 +3772,7 @@ insert_op2 (re_opcode_t op, unsigned char *loc, int arg1, int arg2, unsigned cha
3769 least one character before the ^. */ 3772 least one character before the ^. */
3770 3773
3771static boolean 3774static boolean
3772at_begline_loc_p (const re_char *pattern, const re_char *p, reg_syntax_t syntax) 3775at_begline_loc_p (const_re_char *pattern, const_re_char *p, reg_syntax_t syntax)
3773{ 3776{
3774 re_char *prev = p - 2; 3777 re_char *prev = p - 2;
3775 boolean odd_backslashes; 3778 boolean odd_backslashes;
@@ -3810,7 +3813,7 @@ at_begline_loc_p (const re_char *pattern, const re_char *p, reg_syntax_t syntax)
3810 at least one character after the $, i.e., `P < PEND'. */ 3813 at least one character after the $, i.e., `P < PEND'. */
3811 3814
3812static boolean 3815static boolean
3813at_endline_loc_p (const re_char *p, const re_char *pend, reg_syntax_t syntax) 3816at_endline_loc_p (const_re_char *p, const_re_char *pend, reg_syntax_t syntax)
3814{ 3817{
3815 re_char *next = p; 3818 re_char *next = p;
3816 boolean next_backslash = *next == '\\'; 3819 boolean next_backslash = *next == '\\';
@@ -3854,7 +3857,8 @@ group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum)
3854 Return -1 if fastmap was not updated accurately. */ 3857 Return -1 if fastmap was not updated accurately. */
3855 3858
3856static int 3859static int
3857analyse_first (const re_char *p, const re_char *pend, char *fastmap, const int multibyte) 3860analyse_first (const_re_char *p, const_re_char *pend, char *fastmap,
3861 const int multibyte)
3858{ 3862{
3859 int j, k; 3863 int j, k;
3860 boolean not; 3864 boolean not;
@@ -4598,7 +4602,7 @@ static int bcmp_translate (re_char *s1, re_char *s2,
4598/* If the operation is a match against one or more chars, 4602/* If the operation is a match against one or more chars,
4599 return a pointer to the next operation, else return NULL. */ 4603 return a pointer to the next operation, else return NULL. */
4600static re_char * 4604static re_char *
4601skip_one_char (const re_char *p) 4605skip_one_char (const_re_char *p)
4602{ 4606{
4603 switch (*p++) 4607 switch (*p++)
4604 { 4608 {
@@ -4640,7 +4644,7 @@ skip_one_char (const re_char *p)
4640 4644
4641/* Jump over non-matching operations. */ 4645/* Jump over non-matching operations. */
4642static re_char * 4646static re_char *
4643skip_noops (const re_char *p, const re_char *pend) 4647skip_noops (const_re_char *p, const_re_char *pend)
4644{ 4648{
4645 int mcnt; 4649 int mcnt;
4646 while (p < pend) 4650 while (p < pend)
@@ -4667,7 +4671,8 @@ skip_noops (const re_char *p, const re_char *pend)
4667 4671
4668/* Non-zero if "p1 matches something" implies "p2 fails". */ 4672/* Non-zero if "p1 matches something" implies "p2 fails". */
4669static int 4673static int
4670mutually_exclusive_p (struct re_pattern_buffer *bufp, const re_char *p1, const re_char *p2) 4674mutually_exclusive_p (struct re_pattern_buffer *bufp, const_re_char *p1,
4675 const_re_char *p2)
4671{ 4676{
4672 re_opcode_t op2; 4677 re_opcode_t op2;
4673 const boolean multibyte = RE_MULTIBYTE_P (bufp); 4678 const boolean multibyte = RE_MULTIBYTE_P (bufp);
@@ -4920,8 +4925,8 @@ WEAK_ALIAS (__re_match_2, re_match_2)
4920/* This is a separate function so that we can force an alloca cleanup 4925/* This is a separate function so that we can force an alloca cleanup
4921 afterwards. */ 4926 afterwards. */
4922static regoff_t 4927static regoff_t
4923re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1, 4928re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
4924 size_t size1, const re_char *string2, size_t size2, 4929 size_t size1, const_re_char *string2, size_t size2,
4925 ssize_t pos, struct re_registers *regs, ssize_t stop) 4930 ssize_t pos, struct re_registers *regs, ssize_t stop)
4926{ 4931{
4927 /* General temporaries. */ 4932 /* General temporaries. */
@@ -6263,7 +6268,7 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const re_char *string1,
6263 bytes; nonzero otherwise. */ 6268 bytes; nonzero otherwise. */
6264 6269
6265static int 6270static int
6266bcmp_translate (const re_char *s1, const re_char *s2, register ssize_t len, 6271bcmp_translate (const_re_char *s1, const_re_char *s2, register ssize_t len,
6267 RE_TRANSLATE_TYPE translate, const int target_multibyte) 6272 RE_TRANSLATE_TYPE translate, const int target_multibyte)
6268{ 6273{
6269 register re_char *p1 = s1, *p2 = s2; 6274 register re_char *p1 = s1, *p2 = s2;
@@ -6432,7 +6437,7 @@ re_exec (const char *s)
6432 the return codes and their meanings.) */ 6437 the return codes and their meanings.) */
6433 6438
6434reg_errcode_t 6439reg_errcode_t
6435regcomp (regex_t *__restrict preg, const char *__restrict pattern, 6440regcomp (regex_t *_Restrict_ preg, const char *_Restrict_ pattern,
6436 int cflags) 6441 int cflags)
6437{ 6442{
6438 reg_errcode_t ret; 6443 reg_errcode_t ret;
@@ -6513,8 +6518,8 @@ WEAK_ALIAS (__regcomp, regcomp)
6513 We return 0 if we find a match and REG_NOMATCH if not. */ 6518 We return 0 if we find a match and REG_NOMATCH if not. */
6514 6519
6515reg_errcode_t 6520reg_errcode_t
6516regexec (const regex_t *__restrict preg, const char *__restrict string, 6521regexec (const regex_t *_Restrict_ preg, const char *_Restrict_ string,
6517 size_t nmatch, regmatch_t pmatch[__restrict_arr], int eflags) 6522 size_t nmatch, regmatch_t pmatch[_Restrict_arr_], int eflags)
6518{ 6523{
6519 regoff_t ret; 6524 regoff_t ret;
6520 struct re_registers regs; 6525 struct re_registers regs;
diff --git a/src/regex.h b/src/regex.h
index 175eed10177..31be0504c9e 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -528,31 +528,41 @@ extern int re_exec (const char *);
528#endif 528#endif
529 529
530/* GCC 2.95 and later have "__restrict"; C99 compilers have 530/* GCC 2.95 and later have "__restrict"; C99 compilers have
531 "restrict", and "configure" may have defined "restrict". */ 531 "restrict", and "configure" may have defined "restrict".
532#ifndef __restrict 532 Other compilers use __restrict, __restrict__, and _Restrict, and
533# if ! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)) 533 'configure' might #define 'restrict' to those words, so pick a
534# if defined restrict || 199901L <= __STDC_VERSION__ 534 different name. */
535# define __restrict restrict 535#ifndef _Restrict_
536# else 536# if 199901L <= __STDC_VERSION__
537# define __restrict 537# define _Restrict_ restrict
538# endif 538# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)
539# define _Restrict_ __restrict
540# else
541# define _Restrict_
539# endif 542# endif
540#endif 543#endif
541/* For now conditionally define __restrict_arr to expand to nothing. 544/* gcc 3.1 and up support the [restrict] syntax. Don't trust
542 Ideally we would have a test for the compiler which allows defining 545 sys/cdefs.h's definition of __restrict_arr, though, as it
543 it to restrict. */ 546 mishandles gcc -ansi -pedantic. */
544#ifndef __restrict_arr 547#ifndef _Restrict_arr_
545# define __restrict_arr 548# if ((199901L <= __STDC_VERSION__ \
549 || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \
550 && !defined __STRICT_ANSI__)) \
551 && !defined __GNUG__)
552# define _Restrict_arr_ _Restrict_
553# else
554# define _Restrict_arr_
555# endif
546#endif 556#endif
547 557
548/* POSIX compatibility. */ 558/* POSIX compatibility. */
549extern reg_errcode_t regcomp (regex_t *__restrict __preg, 559extern reg_errcode_t regcomp (regex_t *_Restrict_ __preg,
550 const char *__restrict __pattern, 560 const char *_Restrict_ __pattern,
551 int __cflags); 561 int __cflags);
552 562
553extern reg_errcode_t regexec (const regex_t *__restrict __preg, 563extern reg_errcode_t regexec (const regex_t *_Restrict_ __preg,
554 const char *__restrict __string, size_t __nmatch, 564 const char *_Restrict_ __string, size_t __nmatch,
555 regmatch_t __pmatch[__restrict_arr], 565 regmatch_t __pmatch[_Restrict_arr_],
556 int __eflags); 566 int __eflags);
557 567
558extern size_t regerror (int __errcode, const regex_t * __preg, 568extern size_t regerror (int __errcode, const regex_t * __preg,
diff --git a/src/search.c b/src/search.c
index b4e3cca8269..ff47bb2fecf 100644
--- a/src/search.c
+++ b/src/search.c
@@ -22,10 +22,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22#include <config.h> 22#include <config.h>
23 23
24#include "lisp.h" 24#include "lisp.h"
25#include "syntax.h"
26#include "category.h" 25#include "category.h"
27#include "character.h" 26#include "character.h"
28#include "buffer.h" 27#include "buffer.h"
28#include "syntax.h"
29#include "charset.h" 29#include "charset.h"
30#include "region-cache.h" 30#include "region-cache.h"
31#include "commands.h" 31#include "commands.h"
diff --git a/src/sheap.c b/src/sheap.c
index f8eec753268..54eef60c27d 100644
--- a/src/sheap.c
+++ b/src/sheap.c
@@ -25,7 +25,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 25
26#include <unistd.h> 26#include <unistd.h>
27 27
28#ifdef __x86_64__
29#define STATIC_HEAP_SIZE (18 * 1024 * 1024)
30#else
28#define STATIC_HEAP_SIZE (13 * 1024 * 1024) 31#define STATIC_HEAP_SIZE (13 * 1024 * 1024)
32#endif
29 33
30int debug_sheap = 0; 34int debug_sheap = 0;
31 35
diff --git a/src/sound.c b/src/sound.c
index 7f0ede5b398..5ce185ea60e 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -879,7 +879,7 @@ vox_init (struct sound_device *sd)
879static void 879static void
880vox_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes) 880vox_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes)
881{ 881{
882 if (emacs_write (sd->fd, buffer, nbytes) != nbytes) 882 if (emacs_write_sig (sd->fd, buffer, nbytes) != nbytes)
883 sound_perror ("Error writing to sound device"); 883 sound_perror ("Error writing to sound device");
884} 884}
885 885
diff --git a/src/syntax.c b/src/syntax.c
index ea15cf68c43..6d52d115889 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -20,6 +20,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#define SYNTAX_INLINE EXTERN_INLINE
24
23#include <sys/types.h> 25#include <sys/types.h>
24 26
25#include "lisp.h" 27#include "lisp.h"
@@ -58,54 +60,86 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
58 For style c (like the nested flag), the flag can be placed on any of 60 For style c (like the nested flag), the flag can be placed on any of
59 the chars. */ 61 the chars. */
60 62
61/* These macros extract specific flags from an integer 63/* These functions extract specific flags from an integer
62 that holds the syntax code and the flags. */ 64 that holds the syntax code and the flags. */
63 65
64#define SYNTAX_FLAGS_COMSTART_FIRST(flags) (((flags) >> 16) & 1) 66static bool
65 67SYNTAX_FLAGS_COMSTART_FIRST (int flags)
66#define SYNTAX_FLAGS_COMSTART_SECOND(flags) (((flags) >> 17) & 1) 68{
67 69 return (flags >> 16) & 1;
68#define SYNTAX_FLAGS_COMEND_FIRST(flags) (((flags) >> 18) & 1) 70}
69 71static bool
70#define SYNTAX_FLAGS_COMEND_SECOND(flags) (((flags) >> 19) & 1) 72SYNTAX_FLAGS_COMSTART_SECOND (int flags)
71 73{
72#define SYNTAX_FLAGS_PREFIX(flags) (((flags) >> 20) & 1) 74 return (flags >> 17) & 1;
75}
76static bool
77SYNTAX_FLAGS_COMEND_FIRST (int flags)
78{
79 return (flags >> 18) & 1;
80}
81static bool
82SYNTAX_FLAGS_COMEND_SECOND (int flags)
83{
84 return (flags >> 19) & 1;
85}
86static bool
87SYNTAX_FLAGS_PREFIX (int flags)
88{
89 return (flags >> 20) & 1;
90}
91static bool
92SYNTAX_FLAGS_COMMENT_STYLEB (int flags)
93{
94 return (flags >> 21) & 1;
95}
96static bool
97SYNTAX_FLAGS_COMMENT_STYLEC (int flags)
98{
99 return (flags >> 23) & 1;
100}
101static int
102SYNTAX_FLAGS_COMMENT_STYLEC2 (int flags)
103{
104 return (flags >> 22) & 2; /* SYNTAX_FLAGS_COMMENT_STYLEC (flags) * 2 */
105}
106static bool
107SYNTAX_FLAGS_COMMENT_NESTED (int flags)
108{
109 return (flags >> 22) & 1;
110}
73 111
74#define SYNTAX_FLAGS_COMMENT_STYLEB(flags) (((flags) >> 21) & 1)
75#define SYNTAX_FLAGS_COMMENT_STYLEC(flags) (((flags) >> 23) & 1)
76#define SYNTAX_FLAGS_COMMENT_STYLEC2(flags) (((flags) >> 22) & 2) /* C * 2 */
77/* FLAGS should be the flags of the main char of the comment marker, e.g. 112/* FLAGS should be the flags of the main char of the comment marker, e.g.
78 the second for comstart and the first for comend. */ 113 the second for comstart and the first for comend. */
79#define SYNTAX_FLAGS_COMMENT_STYLE(flags, other_flags) \ 114static int
80 (SYNTAX_FLAGS_COMMENT_STYLEB (flags) \ 115SYNTAX_FLAGS_COMMENT_STYLE (int flags, int other_flags)
81 | SYNTAX_FLAGS_COMMENT_STYLEC2 (flags) \ 116{
82 | SYNTAX_FLAGS_COMMENT_STYLEC2 (other_flags)) 117 return (SYNTAX_FLAGS_COMMENT_STYLEB (flags)
83 118 | SYNTAX_FLAGS_COMMENT_STYLEC2 (flags)
84#define SYNTAX_FLAGS_COMMENT_NESTED(flags) (((flags) >> 22) & 1) 119 | SYNTAX_FLAGS_COMMENT_STYLEC2 (other_flags));
120}
85 121
86/* These macros extract a particular flag for a given character. */ 122/* Extract a particular flag for a given character. */
87 123
88#define SYNTAX_COMEND_FIRST(c) \ 124static bool
89 (SYNTAX_FLAGS_COMEND_FIRST (SYNTAX_WITH_FLAGS (c))) 125SYNTAX_COMEND_FIRST (int c)
90#define SYNTAX_PREFIX(c) (SYNTAX_FLAGS_PREFIX (SYNTAX_WITH_FLAGS (c))) 126{
127 return SYNTAX_FLAGS_COMEND_FIRST (SYNTAX_WITH_FLAGS (c));
128}
91 129
92/* We use these constants in place for comment-style and 130/* We use these constants in place for comment-style and
93 string-ender-char to distinguish comments/strings started by 131 string-ender-char to distinguish comments/strings started by
94 comment_fence and string_fence codes. */ 132 comment_fence and string_fence codes. */
95 133
96#define ST_COMMENT_STYLE (256 + 1) 134enum
97#define ST_STRING_STYLE (256 + 2) 135 {
136 ST_COMMENT_STYLE = 256 + 1,
137 ST_STRING_STYLE = 256 + 2
138 };
98 139
99static Lisp_Object Qsyntax_table_p; 140static Lisp_Object Qsyntax_table_p;
100static Lisp_Object Qsyntax_table, Qscan_error; 141static Lisp_Object Qsyntax_table, Qscan_error;
101 142
102#ifndef __GNUC__
103/* Used as a temporary in SYNTAX_ENTRY and other macros in syntax.h,
104 if not compiled with GCC. No need to mark it, since it is used
105 only very temporarily. */
106Lisp_Object syntax_temp;
107#endif
108
109/* This is the internal form of the parse state used in parse-partial-sexp. */ 143/* This is the internal form of the parse state used in parse-partial-sexp. */
110 144
111struct lisp_parse_state 145struct lisp_parse_state
@@ -162,14 +196,107 @@ bset_syntax_table (struct buffer *b, Lisp_Object val)
162bool 196bool
163syntax_prefix_flag_p (int c) 197syntax_prefix_flag_p (int c)
164{ 198{
165 return SYNTAX_PREFIX (c); 199 return SYNTAX_FLAGS_PREFIX (SYNTAX_WITH_FLAGS (c));
166} 200}
167 201
168struct gl_state_s gl_state; /* Global state of syntax parser. */ 202struct gl_state_s gl_state; /* Global state of syntax parser. */
169 203
170#define INTERVALS_AT_ONCE 10 /* 1 + max-number of intervals 204enum { INTERVALS_AT_ONCE = 10 }; /* 1 + max-number of intervals
171 to scan to property-change. */ 205 to scan to property-change. */
172 206
207/* Set the syntax entry VAL for char C in table TABLE. */
208
209static void
210SET_RAW_SYNTAX_ENTRY (Lisp_Object table, int c, Lisp_Object val)
211{
212 CHAR_TABLE_SET (table, c, val);
213}
214
215/* Set the syntax entry VAL for char-range RANGE in table TABLE.
216 RANGE is a cons (FROM . TO) specifying the range of characters. */
217
218static void
219SET_RAW_SYNTAX_ENTRY_RANGE (Lisp_Object table, Lisp_Object range,
220 Lisp_Object val)
221{
222 Fset_char_table_range (table, range, val);
223}
224
225/* Extract the information from the entry for character C
226 in the current syntax table. */
227
228static Lisp_Object
229SYNTAX_MATCH (int c)
230{
231 Lisp_Object ent = SYNTAX_ENTRY (c);
232 return CONSP (ent) ? XCDR (ent) : Qnil;
233}
234
235/* This should be called with FROM at the start of forward
236 search, or after the last position of the backward search. It
237 makes sure that the first char is picked up with correct table, so
238 one does not need to call UPDATE_SYNTAX_TABLE immediately after the
239 call.
240 Sign of COUNT gives the direction of the search.
241 */
242
243static void
244SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count)
245{
246 SETUP_BUFFER_SYNTAX_TABLE ();
247 gl_state.b_property = BEGV;
248 gl_state.e_property = ZV + 1;
249 gl_state.object = Qnil;
250 gl_state.offset = 0;
251 if (parse_sexp_lookup_properties)
252 if (count > 0 || from > BEGV)
253 update_syntax_table (count > 0 ? from : from - 1, count, 1, Qnil);
254}
255
256/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer.
257 If it is t (which is only used in fast_c_string_match_ignore_case),
258 ignore properties altogether.
259
260 This is meant for regex.c to use. For buffers, regex.c passes arguments
261 to the UPDATE_SYNTAX_TABLE functions which are relative to BEGV.
262 So if it is a buffer, we set the offset field to BEGV. */
263
264void
265SETUP_SYNTAX_TABLE_FOR_OBJECT (Lisp_Object object,
266 ptrdiff_t from, ptrdiff_t count)
267{
268 SETUP_BUFFER_SYNTAX_TABLE ();
269 gl_state.object = object;
270 if (BUFFERP (gl_state.object))
271 {
272 struct buffer *buf = XBUFFER (gl_state.object);
273 gl_state.b_property = 1;
274 gl_state.e_property = BUF_ZV (buf) - BUF_BEGV (buf) + 1;
275 gl_state.offset = BUF_BEGV (buf) - 1;
276 }
277 else if (NILP (gl_state.object))
278 {
279 gl_state.b_property = 1;
280 gl_state.e_property = ZV - BEGV + 1;
281 gl_state.offset = BEGV - 1;
282 }
283 else if (EQ (gl_state.object, Qt))
284 {
285 gl_state.b_property = 0;
286 gl_state.e_property = PTRDIFF_MAX;
287 gl_state.offset = 0;
288 }
289 else
290 {
291 gl_state.b_property = 0;
292 gl_state.e_property = 1 + SCHARS (gl_state.object);
293 gl_state.offset = 0;
294 }
295 if (parse_sexp_lookup_properties)
296 update_syntax_table (from + gl_state.offset - (count <= 0),
297 count, 1, gl_state.object);
298}
299
173/* Update gl_state to an appropriate interval which contains CHARPOS. The 300/* Update gl_state to an appropriate interval which contains CHARPOS. The
174 sign of COUNT give the relative position of CHARPOS wrt the previously 301 sign of COUNT give the relative position of CHARPOS wrt the previously
175 valid interval. If INIT, only [be]_property fields of gl_state are 302 valid interval. If INIT, only [be]_property fields of gl_state are
@@ -1751,7 +1878,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
1751 } 1878 }
1752 1879
1753 immediate_quit = 1; 1880 immediate_quit = 1;
1754 /* This code may look up syntax tables using macros that rely on the 1881 /* This code may look up syntax tables using functions that rely on the
1755 gl_state object. To make sure this object is not out of date, 1882 gl_state object. To make sure this object is not out of date,
1756 let's initialize it manually. 1883 let's initialize it manually.
1757 We ignore syntax-table text-properties for now, since that's 1884 We ignore syntax-table text-properties for now, since that's
@@ -2426,11 +2553,13 @@ between them, return t; otherwise return nil. */)
2426} 2553}
2427 2554
2428/* Return syntax code of character C if C is an ASCII character 2555/* Return syntax code of character C if C is an ASCII character
2429 or `multibyte_symbol_p' is zero. Otherwise, return Ssymbol. */ 2556 or if MULTIBYTE_SYMBOL_P is false. Otherwise, return Ssymbol. */
2430 2557
2431#define SYNTAX_WITH_MULTIBYTE_CHECK(c) \ 2558static enum syntaxcode
2432 ((ASCII_CHAR_P (c) || !multibyte_symbol_p) \ 2559syntax_multibyte (int c, bool multibyte_symbol_p)
2433 ? SYNTAX (c) : Ssymbol) 2560{
2561 return ASCII_CHAR_P (c) || !multibyte_symbol_p ? SYNTAX (c) : Ssymbol;
2562}
2434 2563
2435static Lisp_Object 2564static Lisp_Object
2436scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) 2565scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
@@ -2441,7 +2570,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2441 int stringterm; 2570 int stringterm;
2442 bool quoted; 2571 bool quoted;
2443 bool mathexit = 0; 2572 bool mathexit = 0;
2444 enum syntaxcode code, temp_code, c_code; 2573 enum syntaxcode code;
2445 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */ 2574 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */
2446 int comstyle = 0; /* style of comment encountered */ 2575 int comstyle = 0; /* style of comment encountered */
2447 bool comnested = 0; /* whether the comment is nestable or not */ 2576 bool comnested = 0; /* whether the comment is nestable or not */
@@ -2473,7 +2602,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2473 UPDATE_SYNTAX_TABLE_FORWARD (from); 2602 UPDATE_SYNTAX_TABLE_FORWARD (from);
2474 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2603 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2475 syntax = SYNTAX_WITH_FLAGS (c); 2604 syntax = SYNTAX_WITH_FLAGS (c);
2476 code = SYNTAX_WITH_MULTIBYTE_CHECK (c); 2605 code = syntax_multibyte (c, multibyte_symbol_p);
2477 comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax); 2606 comstart_first = SYNTAX_FLAGS_COMSTART_FIRST (syntax);
2478 comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax); 2607 comnested = SYNTAX_FLAGS_COMMENT_NESTED (syntax);
2479 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0); 2608 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0);
@@ -2519,10 +2648,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2519 { 2648 {
2520 UPDATE_SYNTAX_TABLE_FORWARD (from); 2649 UPDATE_SYNTAX_TABLE_FORWARD (from);
2521 2650
2522 /* Some compilers can't handle this inside the switch. */
2523 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2651 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2524 c_code = SYNTAX_WITH_MULTIBYTE_CHECK (c); 2652 switch (syntax_multibyte (c, multibyte_symbol_p))
2525 switch (c_code)
2526 { 2653 {
2527 case Scharquote: 2654 case Scharquote:
2528 case Sescape: 2655 case Sescape:
@@ -2594,18 +2721,17 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2594 stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2721 stringterm = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2595 while (1) 2722 while (1)
2596 { 2723 {
2724 enum syntaxcode c_code;
2597 if (from >= stop) 2725 if (from >= stop)
2598 goto lose; 2726 goto lose;
2599 UPDATE_SYNTAX_TABLE_FORWARD (from); 2727 UPDATE_SYNTAX_TABLE_FORWARD (from);
2600 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2728 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2729 c_code = syntax_multibyte (c, multibyte_symbol_p);
2601 if (code == Sstring 2730 if (code == Sstring
2602 ? (c == stringterm 2731 ? c == stringterm && c_code == Sstring
2603 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) 2732 : c_code == Sstring_fence)
2604 : SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring_fence)
2605 break; 2733 break;
2606 2734
2607 /* Some compilers can't handle this inside the switch. */
2608 c_code = SYNTAX_WITH_MULTIBYTE_CHECK (c);
2609 switch (c_code) 2735 switch (c_code)
2610 { 2736 {
2611 case Scharquote: 2737 case Scharquote:
@@ -2644,7 +2770,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2644 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2770 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2645 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 2771 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2646 syntax= SYNTAX_WITH_FLAGS (c); 2772 syntax= SYNTAX_WITH_FLAGS (c);
2647 code = SYNTAX_WITH_MULTIBYTE_CHECK (c); 2773 code = syntax_multibyte (c, multibyte_symbol_p);
2648 if (depth == min_depth) 2774 if (depth == min_depth)
2649 last_good = from; 2775 last_good = from;
2650 comstyle = 0; 2776 comstyle = 0;
@@ -2697,9 +2823,8 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2697 temp_pos--; 2823 temp_pos--;
2698 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2824 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2699 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2825 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2700 temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1);
2701 /* Don't allow comment-end to be quoted. */ 2826 /* Don't allow comment-end to be quoted. */
2702 if (temp_code == Sendcomment) 2827 if (syntax_multibyte (c1, multibyte_symbol_p) == Sendcomment)
2703 goto done2; 2828 goto done2;
2704 quoted = char_quoted (from - 1, temp_pos); 2829 quoted = char_quoted (from - 1, temp_pos);
2705 if (quoted) 2830 if (quoted)
@@ -2709,11 +2834,12 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2709 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1); 2834 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
2710 } 2835 }
2711 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos); 2836 c1 = FETCH_CHAR_AS_MULTIBYTE (temp_pos);
2712 temp_code = SYNTAX_WITH_MULTIBYTE_CHECK (c1); 2837 if (! quoted)
2713 if (! (quoted || temp_code == Sword 2838 switch (syntax_multibyte (c1, multibyte_symbol_p))
2714 || temp_code == Ssymbol 2839 {
2715 || temp_code == Squote)) 2840 case Sword: case Ssymbol: case Squote: break;
2716 goto done2; 2841 default: goto done2;
2842 }
2717 DEC_BOTH (from, from_byte); 2843 DEC_BOTH (from, from_byte);
2718 } 2844 }
2719 goto done2; 2845 goto done2;
@@ -2768,10 +2894,12 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2768 goto lose; 2894 goto lose;
2769 DEC_BOTH (from, from_byte); 2895 DEC_BOTH (from, from_byte);
2770 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2896 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2771 if (!char_quoted (from, from_byte) 2897 if (!char_quoted (from, from_byte))
2772 && (c = FETCH_CHAR_AS_MULTIBYTE (from_byte), 2898 {
2773 SYNTAX_WITH_MULTIBYTE_CHECK (c) == code)) 2899 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2774 break; 2900 if (syntax_multibyte (c, multibyte_symbol_p) == code)
2901 break;
2902 }
2775 } 2903 }
2776 if (code == Sstring_fence && !depth && sexpflag) goto done2; 2904 if (code == Sstring_fence && !depth && sexpflag) goto done2;
2777 break; 2905 break;
@@ -2784,11 +2912,14 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2784 goto lose; 2912 goto lose;
2785 DEC_BOTH (from, from_byte); 2913 DEC_BOTH (from, from_byte);
2786 UPDATE_SYNTAX_TABLE_BACKWARD (from); 2914 UPDATE_SYNTAX_TABLE_BACKWARD (from);
2787 if (!char_quoted (from, from_byte) 2915 if (!char_quoted (from, from_byte))
2788 && (stringterm 2916 {
2789 == (c = FETCH_CHAR_AS_MULTIBYTE (from_byte))) 2917 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
2790 && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring) 2918 if (c == stringterm
2791 break; 2919 && (syntax_multibyte (c, multibyte_symbol_p)
2920 == Sstring))
2921 break;
2922 }
2792 } 2923 }
2793 if (!depth && sexpflag) goto done2; 2924 if (!depth && sexpflag) goto done2;
2794 break; 2925 break;
@@ -2894,7 +3025,7 @@ This includes chars with "quote" or "prefix" syntax (' or p). */)
2894 while (!char_quoted (pos, pos_byte) 3025 while (!char_quoted (pos, pos_byte)
2895 /* Previous statement updates syntax table. */ 3026 /* Previous statement updates syntax table. */
2896 && ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote) 3027 && ((c = FETCH_CHAR_AS_MULTIBYTE (pos_byte), SYNTAX (c) == Squote)
2897 || SYNTAX_PREFIX (c))) 3028 || syntax_prefix_flag_p (c)))
2898 { 3029 {
2899 opoint = pos; 3030 opoint = pos;
2900 opoint_byte = pos_byte; 3031 opoint_byte = pos_byte;
@@ -3117,10 +3248,8 @@ do { prev_from = from; \
3117 symstarted: 3248 symstarted:
3118 while (from < end) 3249 while (from < end)
3119 { 3250 {
3120 /* Some compilers can't handle this inside the switch. */
3121 int symchar = FETCH_CHAR_AS_MULTIBYTE (from_byte); 3251 int symchar = FETCH_CHAR_AS_MULTIBYTE (from_byte);
3122 enum syntaxcode symcharcode = SYNTAX (symchar); 3252 switch (SYNTAX (symchar))
3123 switch (symcharcode)
3124 { 3253 {
3125 case Scharquote: 3254 case Scharquote:
3126 case Sescape: 3255 case Sescape:
@@ -3206,7 +3335,6 @@ do { prev_from = from; \
3206 3335
3207 if (from >= end) goto done; 3336 if (from >= end) goto done;
3208 c = FETCH_CHAR_AS_MULTIBYTE (from_byte); 3337 c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
3209 /* Some compilers can't handle this inside the switch. */
3210 c_code = SYNTAX (c); 3338 c_code = SYNTAX (c);
3211 3339
3212 /* Check C_CODE here so that if the char has 3340 /* Check C_CODE here so that if the char has
diff --git a/src/syntax.h b/src/syntax.h
index 58d39b9059c..1b96284af42 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -18,6 +18,10 @@ GNU General Public License for more details.
18You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21INLINE_HEADER_BEGIN
22#ifndef SYNTAX_INLINE
23# define SYNTAX_INLINE INLINE
24#endif
21 25
22extern void update_syntax_table (ptrdiff_t, EMACS_INT, bool, Lisp_Object); 26extern void update_syntax_table (ptrdiff_t, EMACS_INT, bool, Lisp_Object);
23 27
@@ -54,79 +58,64 @@ enum syntaxcode
54 Smax /* Upper bound on codes that are meaningful */ 58 Smax /* Upper bound on codes that are meaningful */
55 }; 59 };
56 60
57/* Set the syntax entry VAL for char C in table TABLE. */
58
59#define SET_RAW_SYNTAX_ENTRY(table, c, val) \
60 CHAR_TABLE_SET ((table), c, (val))
61 61
62/* Set the syntax entry VAL for char-range RANGE in table TABLE. 62struct gl_state_s
63 RANGE is a cons (FROM . TO) specifying the range of characters. */ 63{
64 Lisp_Object object; /* The object we are scanning. */
65 ptrdiff_t start; /* Where to stop. */
66 ptrdiff_t stop; /* Where to stop. */
67 bool use_global; /* Whether to use global_code
68 or c_s_t. */
69 Lisp_Object global_code; /* Syntax code of current char. */
70 Lisp_Object current_syntax_table; /* Syntax table for current pos. */
71 Lisp_Object old_prop; /* Syntax-table prop at prev pos. */
72 ptrdiff_t b_property; /* First index where c_s_t is valid. */
73 ptrdiff_t e_property; /* First index where c_s_t is
74 not valid. */
75 INTERVAL forward_i; /* Where to start lookup on forward */
76 INTERVAL backward_i; /* or backward movement. The
77 data in c_s_t is valid
78 between these intervals,
79 and possibly at the
80 intervals too, depending
81 on: */
82 /* Offset for positions specified to UPDATE_SYNTAX_TABLE. */
83 ptrdiff_t offset;
84};
64 85
65#define SET_RAW_SYNTAX_ENTRY_RANGE(table, range, val) \ 86extern struct gl_state_s gl_state;
66 Fset_char_table_range ((table), (range), (val))
67 87
68/* SYNTAX_ENTRY fetches the information from the entry for character C 88/* Fetch the information from the entry for character C
69 in syntax table TABLE, or from globally kept data (gl_state). 89 in syntax table TABLE, or from globally kept data (gl_state).
70 Does inheritance. */ 90 Does inheritance. */
71/* CURRENT_SYNTAX_TABLE gives the syntax table valid for current
72 position, it is either the buffer's syntax table, or syntax table
73 found in text properties. */
74 91
92SYNTAX_INLINE Lisp_Object
93SYNTAX_ENTRY (int c)
94{
75#ifdef SYNTAX_ENTRY_VIA_PROPERTY 95#ifdef SYNTAX_ENTRY_VIA_PROPERTY
76# define SYNTAX_ENTRY(c) \ 96 return (gl_state.use_global
77 (gl_state.use_global ? gl_state.global_code : SYNTAX_ENTRY_INT (c)) 97 ? gl_state.global_code
78# define CURRENT_SYNTAX_TABLE gl_state.current_syntax_table 98 : CHAR_TABLE_REF (gl_state.current_syntax_table, c));
79#else 99#else
80# define SYNTAX_ENTRY SYNTAX_ENTRY_INT 100 return CHAR_TABLE_REF (BVAR (current_buffer, syntax_table), c);
81# define CURRENT_SYNTAX_TABLE BVAR (current_buffer, syntax_table)
82#endif 101#endif
83 102}
84#define SYNTAX_ENTRY_INT(c) CHAR_TABLE_REF (CURRENT_SYNTAX_TABLE, (c))
85 103
86/* Extract the information from the entry for character C 104/* Extract the information from the entry for character C
87 in the current syntax table. */ 105 in the current syntax table. */
88 106
89#ifdef __GNUC__ 107SYNTAX_INLINE int
90#define SYNTAX(c) \ 108SYNTAX_WITH_FLAGS (int c)
91 ({ Lisp_Object _syntax_temp; \ 109{
92 _syntax_temp = SYNTAX_ENTRY (c); \ 110 Lisp_Object ent = SYNTAX_ENTRY (c);
93 (CONSP (_syntax_temp) \ 111 return CONSP (ent) ? XINT (XCAR (ent)) : Swhitespace;
94 ? (enum syntaxcode) (XINT (XCAR (_syntax_temp)) & 0xff) \ 112}
95 : Swhitespace); }) 113
96 114SYNTAX_INLINE enum syntaxcode
97#define SYNTAX_WITH_FLAGS(c) \ 115SYNTAX (int c)
98 ({ Lisp_Object _syntax_temp; \ 116{
99 _syntax_temp = SYNTAX_ENTRY (c); \ 117 return SYNTAX_WITH_FLAGS (c) & 0xff;
100 (CONSP (_syntax_temp) \ 118}
101 ? XINT (XCAR (_syntax_temp)) \
102 : Swhitespace); })
103
104#define SYNTAX_MATCH(c) \
105 ({ Lisp_Object _syntax_temp; \
106 _syntax_temp = SYNTAX_ENTRY (c); \
107 (CONSP (_syntax_temp) \
108 ? XCDR (_syntax_temp) \
109 : Qnil); })
110#else
111extern Lisp_Object syntax_temp;
112#define SYNTAX(c) \
113 (syntax_temp = SYNTAX_ENTRY ((c)), \
114 (CONSP (syntax_temp) \
115 ? (enum syntaxcode) (XINT (XCAR (syntax_temp)) & 0xff) \
116 : Swhitespace))
117
118#define SYNTAX_WITH_FLAGS(c) \
119 (syntax_temp = SYNTAX_ENTRY ((c)), \
120 (CONSP (syntax_temp) \
121 ? XINT (XCAR (syntax_temp)) \
122 : Swhitespace))
123
124#define SYNTAX_MATCH(c) \
125 (syntax_temp = SYNTAX_ENTRY ((c)), \
126 (CONSP (syntax_temp) \
127 ? XCDR (syntax_temp) \
128 : Qnil))
129#endif
130 119
131 120
132/* Whether the syntax of the character C has the prefix flag set. */ 121/* Whether the syntax of the character C has the prefix flag set. */
@@ -145,158 +134,65 @@ extern char const syntax_code_spec[16];
145/* Convert the byte offset BYTEPOS into a character position, 134/* Convert the byte offset BYTEPOS into a character position,
146 for the object recorded in gl_state with SETUP_SYNTAX_TABLE_FOR_OBJECT. 135 for the object recorded in gl_state with SETUP_SYNTAX_TABLE_FOR_OBJECT.
147 136
148 The value is meant for use in the UPDATE_SYNTAX_TABLE... macros. 137 The value is meant for use in code that does nothing when
149 These macros do nothing when parse_sexp_lookup_properties is 0, 138 parse_sexp_lookup_properties is 0, so return 0 in that case, for speed. */
150 so we return 0 in that case, for speed. */ 139
151 140SYNTAX_INLINE ptrdiff_t
152#define SYNTAX_TABLE_BYTE_TO_CHAR(bytepos) \ 141SYNTAX_TABLE_BYTE_TO_CHAR (ptrdiff_t bytepos)
153 (! parse_sexp_lookup_properties \ 142{
154 ? 0 \ 143 return (! parse_sexp_lookup_properties
155 : STRINGP (gl_state.object) \ 144 ? 0
156 ? string_byte_to_char (gl_state.object, (bytepos)) \ 145 : STRINGP (gl_state.object)
157 : BUFFERP (gl_state.object) \ 146 ? string_byte_to_char (gl_state.object, bytepos)
158 ? buf_bytepos_to_charpos (XBUFFER (gl_state.object), \ 147 : BUFFERP (gl_state.object)
159 (bytepos) + BUF_BEGV_BYTE (XBUFFER (gl_state.object)) - 1) - BUF_BEGV (XBUFFER (gl_state.object)) + 1 \ 148 ? ((buf_bytepos_to_charpos
160 : NILP (gl_state.object) \ 149 (XBUFFER (gl_state.object),
161 ? BYTE_TO_CHAR ((bytepos) + BEGV_BYTE - 1) - BEGV + 1 \ 150 (bytepos + BUF_BEGV_BYTE (XBUFFER (gl_state.object)) - 1)))
162 : (bytepos)) 151 - BUF_BEGV (XBUFFER (gl_state.object)) + 1)
152 : NILP (gl_state.object)
153 ? BYTE_TO_CHAR (bytepos + BEGV_BYTE - 1) - BEGV + 1
154 : bytepos);
155}
163 156
164/* Make syntax table state (gl_state) good for CHARPOS, assuming it is 157/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
165 currently good for a position before CHARPOS. */ 158 currently good for a position before CHARPOS. */
166 159
167#define UPDATE_SYNTAX_TABLE_FORWARD(charpos) \ 160SYNTAX_INLINE void
168 (parse_sexp_lookup_properties \ 161UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos)
169 && (charpos) >= gl_state.e_property \ 162{
170 ? (update_syntax_table ((charpos) + gl_state.offset, 1, 0, \ 163 if (parse_sexp_lookup_properties && charpos >= gl_state.e_property)
171 gl_state.object), \ 164 update_syntax_table (charpos + gl_state.offset, 1, 0, gl_state.object);
172 1) \ 165}
173 : 0)
174 166
175/* Make syntax table state (gl_state) good for CHARPOS, assuming it is 167/* Make syntax table state (gl_state) good for CHARPOS, assuming it is
176 currently good for a position after CHARPOS. */ 168 currently good for a position after CHARPOS. */
177 169
178#define UPDATE_SYNTAX_TABLE_BACKWARD(charpos) \ 170SYNTAX_INLINE void
179 (parse_sexp_lookup_properties \ 171UPDATE_SYNTAX_TABLE_BACKWARD (ptrdiff_t charpos)
180 && (charpos) < gl_state.b_property \ 172{
181 ? (update_syntax_table ((charpos) + gl_state.offset, -1, 0, \ 173 if (parse_sexp_lookup_properties && charpos < gl_state.b_property)
182 gl_state.object), \ 174 update_syntax_table (charpos + gl_state.offset, -1, 0, gl_state.object);
183 1) \ 175}
184 : 0)
185 176
186/* Make syntax table good for CHARPOS. */ 177/* Make syntax table good for CHARPOS. */
187 178
188#define UPDATE_SYNTAX_TABLE(charpos) \ 179SYNTAX_INLINE void
189 (parse_sexp_lookup_properties \ 180UPDATE_SYNTAX_TABLE (ptrdiff_t charpos)
190 && (charpos) < gl_state.b_property \ 181{
191 ? (update_syntax_table ((charpos) + gl_state.offset, -1, 0, \ 182 UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
192 gl_state.object), \ 183 UPDATE_SYNTAX_TABLE_FORWARD (charpos);
193 1) \ 184}
194 : (parse_sexp_lookup_properties \ 185
195 && (charpos) >= gl_state.e_property \ 186/* Set up the buffer-global syntax table. */
196 ? (update_syntax_table ((charpos) + gl_state.offset, 1, 0,\
197 gl_state.object), \
198 1) \
199 : 0))
200
201/* This macro sets up the buffer-global syntax table. */
202#define SETUP_BUFFER_SYNTAX_TABLE() \
203do \
204 { \
205 gl_state.use_global = 0; \
206 gl_state.current_syntax_table = BVAR (current_buffer, syntax_table);\
207 } while (0)
208
209/* This macro should be called with FROM at the start of forward
210 search, or after the last position of the backward search. It
211 makes sure that the first char is picked up with correct table, so
212 one does not need to call UPDATE_SYNTAX_TABLE immediately after the
213 call.
214 Sign of COUNT gives the direction of the search.
215 */
216
217#define SETUP_SYNTAX_TABLE(FROM, COUNT) \
218do \
219 { \
220 SETUP_BUFFER_SYNTAX_TABLE (); \
221 gl_state.b_property = BEGV; \
222 gl_state.e_property = ZV + 1; \
223 gl_state.object = Qnil; \
224 gl_state.offset = 0; \
225 if (parse_sexp_lookup_properties) \
226 if ((COUNT) > 0 || (FROM) > BEGV) \
227 update_syntax_table ((COUNT) > 0 ? (FROM) : (FROM) - 1, (COUNT),\
228 1, Qnil); \
229 } \
230while (0)
231
232/* Same as above, but in OBJECT. If OBJECT is nil, use current buffer.
233 If it is t (which is only used in fast_c_string_match_ignore_case),
234 ignore properties altogether.
235
236 This is meant for regex.c to use. For buffers, regex.c passes arguments
237 to the UPDATE_SYNTAX_TABLE macros which are relative to BEGV.
238 So if it is a buffer, we set the offset field to BEGV. */
239
240#define SETUP_SYNTAX_TABLE_FOR_OBJECT(OBJECT, FROM, COUNT) \
241do \
242 { \
243 SETUP_BUFFER_SYNTAX_TABLE (); \
244 gl_state.object = (OBJECT); \
245 if (BUFFERP (gl_state.object)) \
246 { \
247 struct buffer *buf = XBUFFER (gl_state.object); \
248 gl_state.b_property = 1; \
249 gl_state.e_property = BUF_ZV (buf) - BUF_BEGV (buf) + 1; \
250 gl_state.offset = BUF_BEGV (buf) - 1; \
251 } \
252 else if (NILP (gl_state.object)) \
253 { \
254 gl_state.b_property = 1; \
255 gl_state.e_property = ZV - BEGV + 1; \
256 gl_state.offset = BEGV - 1; \
257 } \
258 else if (EQ (gl_state.object, Qt)) \
259 { \
260 gl_state.b_property = 0; \
261 gl_state.e_property = PTRDIFF_MAX; \
262 gl_state.offset = 0; \
263 } \
264 else \
265 { \
266 gl_state.b_property = 0; \
267 gl_state.e_property = 1 + SCHARS (gl_state.object); \
268 gl_state.offset = 0; \
269 } \
270 if (parse_sexp_lookup_properties) \
271 update_syntax_table (((FROM) + gl_state.offset \
272 + (COUNT > 0 ? 0 : -1)), \
273 COUNT, 1, gl_state.object); \
274 } \
275while (0)
276 187
277struct gl_state_s 188SYNTAX_INLINE void
189SETUP_BUFFER_SYNTAX_TABLE (void)
278{ 190{
279 Lisp_Object object; /* The object we are scanning. */ 191 gl_state.use_global = 0;
280 ptrdiff_t start; /* Where to stop. */ 192 gl_state.current_syntax_table = BVAR (current_buffer, syntax_table);
281 ptrdiff_t stop; /* Where to stop. */ 193}
282 int use_global; /* Whether to use global_code
283 or c_s_t. */
284 Lisp_Object global_code; /* Syntax code of current char. */
285 Lisp_Object current_syntax_table; /* Syntax table for current pos. */
286 Lisp_Object old_prop; /* Syntax-table prop at prev pos. */
287 ptrdiff_t b_property; /* First index where c_s_t is valid. */
288 ptrdiff_t e_property; /* First index where c_s_t is
289 not valid. */
290 INTERVAL forward_i; /* Where to start lookup on forward */
291 INTERVAL backward_i; /* or backward movement. The
292 data in c_s_t is valid
293 between these intervals,
294 and possibly at the
295 intervals too, depending
296 on: */
297 /* Offset for positions specified to UPDATE_SYNTAX_TABLE. */
298 ptrdiff_t offset;
299};
300 194
301extern struct gl_state_s gl_state;
302extern ptrdiff_t scan_words (ptrdiff_t, EMACS_INT); 195extern ptrdiff_t scan_words (ptrdiff_t, EMACS_INT);
196extern void SETUP_SYNTAX_TABLE_FOR_OBJECT (Lisp_Object, ptrdiff_t, ptrdiff_t);
197
198INLINE_HEADER_END
diff --git a/src/sysdep.c b/src/sysdep.c
index 91e941a2050..f614d8bc557 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -31,7 +31,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
31#include <unistd.h> 31#include <unistd.h>
32 32
33#include <c-ctype.h> 33#include <c-ctype.h>
34#include <ignore-value.h>
35#include <utimens.h> 34#include <utimens.h>
36 35
37#include "lisp.h" 36#include "lisp.h"
@@ -103,8 +102,8 @@ int _cdecl _getpid (void);
103#include "syssignal.h" 102#include "syssignal.h"
104#include "systime.h" 103#include "systime.h"
105 104
106static int emacs_get_tty (int, struct emacs_tty *); 105static void emacs_get_tty (int, struct emacs_tty *);
107static int emacs_set_tty (int, struct emacs_tty *, int); 106static int emacs_set_tty (int, struct emacs_tty *, bool);
108 107
109/* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */ 108/* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */
110#ifndef ULLONG_MAX 109#ifndef ULLONG_MAX
@@ -538,13 +537,11 @@ sys_subshell (void)
538 if (str && chdir ((char *) str) != 0) 537 if (str && chdir ((char *) str) != 0)
539 { 538 {
540#ifndef DOS_NT 539#ifndef DOS_NT
541 ignore_value (write (1, "Can't chdir\n", 12)); 540 emacs_perror ((char *) str);
542 _exit (1); 541 _exit (EXIT_CANCELED);
543#endif 542#endif
544 } 543 }
545 544
546 close_process_descs (); /* Close Emacs's pipes/ptys */
547
548#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */ 545#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
549 { 546 {
550 char *epwd = getenv ("PWD"); 547 char *epwd = getenv ("PWD");
@@ -572,8 +569,8 @@ sys_subshell (void)
572 write (1, "Can't execute subshell", 22); 569 write (1, "Can't execute subshell", 22);
573#else /* not WINDOWSNT */ 570#else /* not WINDOWSNT */
574 execlp (sh, sh, (char *) 0); 571 execlp (sh, sh, (char *) 0);
575 ignore_value (write (1, "Can't execute subshell", 22)); 572 emacs_perror (sh);
576 _exit (1); 573 _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
577#endif /* not WINDOWSNT */ 574#endif /* not WINDOWSNT */
578#endif /* not MSDOS */ 575#endif /* not MSDOS */
579 } 576 }
@@ -772,31 +769,26 @@ widen_foreground_group (int fd)
772 769
773/* Getting and setting emacs_tty structures. */ 770/* Getting and setting emacs_tty structures. */
774 771
775/* Set *TC to the parameters associated with the terminal FD. 772/* Set *TC to the parameters associated with the terminal FD,
776 Return zero if all's well, or -1 if we ran into an error we 773 or clear it if the parameters are not available. */
777 couldn't deal with. */ 774static void
778int
779emacs_get_tty (int fd, struct emacs_tty *settings) 775emacs_get_tty (int fd, struct emacs_tty *settings)
780{ 776{
781 /* Retrieve the primary parameters - baud rate, character size, etcetera. */ 777 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
782#ifndef DOS_NT 778#ifndef DOS_NT
783 /* We have those nifty POSIX tcmumbleattr functions. */ 779 /* We have those nifty POSIX tcmumbleattr functions. */
784 memset (&settings->main, 0, sizeof (settings->main)); 780 memset (&settings->main, 0, sizeof (settings->main));
785 if (tcgetattr (fd, &settings->main) < 0) 781 tcgetattr (fd, &settings->main);
786 return -1;
787#endif 782#endif
788
789 /* We have survived the tempest. */
790 return 0;
791} 783}
792 784
793 785
794/* Set the parameters of the tty on FD according to the contents of 786/* Set the parameters of the tty on FD according to the contents of
795 *SETTINGS. If FLUSHP is non-zero, we discard input. 787 *SETTINGS. If FLUSHP, discard input.
796 Return 0 if all went well, and -1 if anything failed. */ 788 Return 0 if all went well, and -1 (setting errno) if anything failed. */
797 789
798int 790static int
799emacs_set_tty (int fd, struct emacs_tty *settings, int flushp) 791emacs_set_tty (int fd, struct emacs_tty *settings, bool flushp)
800{ 792{
801 /* Set the primary parameters - baud rate, character size, etcetera. */ 793 /* Set the primary parameters - baud rate, character size, etcetera. */
802#ifndef DOS_NT 794#ifndef DOS_NT
@@ -1121,10 +1113,10 @@ init_sys_modes (struct tty_display_info *tty_out)
1121 tty_out->term_initted = 1; 1113 tty_out->term_initted = 1;
1122} 1114}
1123 1115
1124/* Return nonzero if safe to use tabs in output. 1116/* Return true if safe to use tabs in output.
1125 At the time this is called, init_sys_modes has not been done yet. */ 1117 At the time this is called, init_sys_modes has not been done yet. */
1126 1118
1127int 1119bool
1128tabs_safe_p (int fd) 1120tabs_safe_p (int fd)
1129{ 1121{
1130 struct emacs_tty etty; 1122 struct emacs_tty etty;
@@ -1378,8 +1370,10 @@ init_system_name (void)
1378 uname (&uts); 1370 uname (&uts);
1379 Vsystem_name = build_string (uts.nodename); 1371 Vsystem_name = build_string (uts.nodename);
1380#else /* HAVE_GETHOSTNAME */ 1372#else /* HAVE_GETHOSTNAME */
1381 unsigned int hostname_size = 256; 1373 char *hostname_alloc = NULL;
1382 char *hostname = alloca (hostname_size); 1374 char hostname_buf[256];
1375 ptrdiff_t hostname_size = sizeof hostname_buf;
1376 char *hostname = hostname_buf;
1383 1377
1384 /* Try to get the host name; if the buffer is too short, try 1378 /* Try to get the host name; if the buffer is too short, try
1385 again. Apparently, the only indication gethostname gives of 1379 again. Apparently, the only indication gethostname gives of
@@ -1394,8 +1388,8 @@ init_system_name (void)
1394 if (strlen (hostname) < hostname_size - 1) 1388 if (strlen (hostname) < hostname_size - 1)
1395 break; 1389 break;
1396 1390
1397 hostname_size <<= 1; 1391 hostname = hostname_alloc = xpalloc (hostname_alloc, &hostname_size, 1,
1398 hostname = alloca (hostname_size); 1392 min (PTRDIFF_MAX, SIZE_MAX), 1);
1399 } 1393 }
1400#ifdef HAVE_SOCKETS 1394#ifdef HAVE_SOCKETS
1401 /* Turn the hostname into the official, fully-qualified hostname. 1395 /* Turn the hostname into the official, fully-qualified hostname.
@@ -1440,7 +1434,13 @@ init_system_name (void)
1440 } 1434 }
1441 if (it) 1435 if (it)
1442 { 1436 {
1443 hostname = alloca (strlen (it->ai_canonname) + 1); 1437 ptrdiff_t len = strlen (it->ai_canonname);
1438 if (hostname_size <= len)
1439 {
1440 hostname_size = len + 1;
1441 hostname = hostname_alloc = xrealloc (hostname_alloc,
1442 hostname_size);
1443 }
1444 strcpy (hostname, it->ai_canonname); 1444 strcpy (hostname, it->ai_canonname);
1445 } 1445 }
1446 freeaddrinfo (res); 1446 freeaddrinfo (res);
@@ -1487,10 +1487,11 @@ init_system_name (void)
1487 } 1487 }
1488#endif /* HAVE_SOCKETS */ 1488#endif /* HAVE_SOCKETS */
1489 Vsystem_name = build_string (hostname); 1489 Vsystem_name = build_string (hostname);
1490 xfree (hostname_alloc);
1490#endif /* HAVE_GETHOSTNAME */ 1491#endif /* HAVE_GETHOSTNAME */
1491 { 1492 {
1492 unsigned char *p; 1493 char *p;
1493 for (p = SDATA (Vsystem_name); *p; p++) 1494 for (p = SSDATA (Vsystem_name); *p; p++)
1494 if (*p == ' ' || *p == '\t') 1495 if (*p == ' ' || *p == '\t')
1495 *p = '-'; 1496 *p = '-';
1496 } 1497 }
@@ -2136,10 +2137,10 @@ emacs_backtrace (int backtrace_limit)
2136 2137
2137 if (npointers) 2138 if (npointers)
2138 { 2139 {
2139 ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12)); 2140 emacs_write (STDERR_FILENO, "\nBacktrace:\n", 12);
2140 backtrace_symbols_fd (buffer, npointers, STDERR_FILENO); 2141 backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
2141 if (bounded_limit < npointers) 2142 if (bounded_limit < npointers)
2142 ignore_value (write (STDERR_FILENO, "...\n", 4)); 2143 emacs_write (STDERR_FILENO, "...\n", 4);
2143 } 2144 }
2144} 2145}
2145 2146
@@ -2152,6 +2153,8 @@ emacs_abort (void)
2152#endif 2153#endif
2153 2154
2154/* Open FILE for Emacs use, using open flags OFLAG and mode MODE. 2155/* Open FILE for Emacs use, using open flags OFLAG and mode MODE.
2156 Arrange for subprograms to not inherit the file descriptor.
2157 Prefer a method that is multithread-safe, if available.
2155 Do not fail merely because the open was interrupted by a signal. 2158 Do not fail merely because the open was interrupted by a signal.
2156 Allow the user to quit. */ 2159 Allow the user to quit. */
2157 2160
@@ -2159,8 +2162,11 @@ int
2159emacs_open (const char *file, int oflags, int mode) 2162emacs_open (const char *file, int oflags, int mode)
2160{ 2163{
2161 int fd; 2164 int fd;
2165 oflags |= O_CLOEXEC;
2162 while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR) 2166 while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR)
2163 QUIT; 2167 QUIT;
2168 if (! O_CLOEXEC && 0 <= fd)
2169 fcntl (fd, F_SETFD, FD_CLOEXEC);
2164 return fd; 2170 return fd;
2165} 2171}
2166 2172
@@ -2170,29 +2176,84 @@ emacs_open (const char *file, int oflags, int mode)
2170FILE * 2176FILE *
2171emacs_fopen (char const *file, char const *mode) 2177emacs_fopen (char const *file, char const *mode)
2172{ 2178{
2173 FILE *fp; 2179 int fd, omode, oflags;
2174 while (! (fp = fopen (file, mode)) && errno == EINTR) 2180 int bflag = 0;
2175 QUIT; 2181 char const *m = mode;
2176 return fp; 2182
2183 switch (*m++)
2184 {
2185 case 'r': omode = O_RDONLY; oflags = 0; break;
2186 case 'w': omode = O_WRONLY; oflags = O_CREAT | O_TRUNC; break;
2187 case 'a': omode = O_WRONLY; oflags = O_CREAT | O_APPEND; break;
2188 default: emacs_abort ();
2189 }
2190
2191 while (*m)
2192 switch (*m++)
2193 {
2194 case '+': omode = O_RDWR; break;
2195 case 'b': bflag = O_BINARY; break;
2196 case 't': bflag = O_TEXT; break;
2197 default: /* Ignore. */ break;
2198 }
2199
2200 fd = emacs_open (file, omode | oflags | bflag, 0666);
2201 return fd < 0 ? 0 : fdopen (fd, mode);
2177} 2202}
2178 2203
2179int 2204/* Approximate posix_close and POSIX_CLOSE_RESTART well enough for Emacs.
2180emacs_close (int fd) 2205 For the background behind this mess, please see Austin Group defect 529
2206 <http://austingroupbugs.net/view.php?id=529>. */
2207
2208#ifndef POSIX_CLOSE_RESTART
2209# define POSIX_CLOSE_RESTART 1
2210static int
2211posix_close (int fd, int flag)
2181{ 2212{
2182 int did_retry = 0; 2213 /* Only the POSIX_CLOSE_RESTART case is emulated. */
2183 register int rtnval; 2214 eassert (flag == POSIX_CLOSE_RESTART);
2184 2215
2185 while ((rtnval = close (fd)) == -1 2216 /* Things are tricky if close (fd) returns -1 with errno == EINTR
2186 && (errno == EINTR)) 2217 on a system that does not define POSIX_CLOSE_RESTART.
2187 did_retry = 1;
2188 2218
2189 /* If close is interrupted SunOS 4.1 may or may not have closed the 2219 In this case, in some systems (e.g., GNU/Linux, AIX) FD is
2190 file descriptor. If it did the second close will fail with 2220 closed, and retrying the close could inadvertently close a file
2191 errno = EBADF. That means we have succeeded. */ 2221 descriptor allocated by some other thread. In other systems
2192 if (rtnval == -1 && did_retry && errno == EBADF) 2222 (e.g., HP/UX) FD is not closed. And in still other systems
2193 return 0; 2223 (e.g., OS X, Solaris), maybe FD is closed, maybe not, and in a
2224 multithreaded program there can be no way to tell.
2194 2225
2195 return rtnval; 2226 So, in this case, pretend that the close succeeded. This works
2227 well on systems like GNU/Linux that close FD. Although it may
2228 leak a file descriptor on other systems, the leak is unlikely and
2229 it's better to leak than to close a random victim. */
2230 return close (fd) == 0 || errno == EINTR ? 0 : -1;
2231}
2232#endif
2233
2234/* Close FD, retrying if interrupted. If successful, return 0;
2235 otherwise, return -1 and set errno to a non-EINTR value. Consider
2236 an EINPROGRESS error to be successful, as that's merely a signal
2237 arriving. FD is always closed when this function returns, even
2238 when it returns -1.
2239
2240 Do not call this function if FD is nonnegative and might already be closed,
2241 as that might close an innocent victim opened by some other thread. */
2242
2243int
2244emacs_close (int fd)
2245{
2246 while (1)
2247 {
2248 int r = posix_close (fd, POSIX_CLOSE_RESTART);
2249 if (r == 0)
2250 return r;
2251 if (!POSIX_CLOSE_RESTART || errno != EINTR)
2252 {
2253 eassert (errno != EBADF || fd < 0);
2254 return errno == EINPROGRESS ? 0 : r;
2255 }
2256 }
2196} 2257}
2197 2258
2198/* Maximum number of bytes to read or write in a single system call. 2259/* Maximum number of bytes to read or write in a single system call.
@@ -2224,27 +2285,26 @@ emacs_read (int fildes, char *buf, ptrdiff_t nbyte)
2224} 2285}
2225 2286
2226/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted 2287/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted
2227 or if a partial write occurs. Return the number of bytes written, setting 2288 or if a partial write occurs. If interrupted, process pending
2289 signals if PROCESS SIGNALS. Return the number of bytes written, setting
2228 errno if this is less than NBYTE. */ 2290 errno if this is less than NBYTE. */
2229ptrdiff_t 2291static ptrdiff_t
2230emacs_write (int fildes, const char *buf, ptrdiff_t nbyte) 2292emacs_full_write (int fildes, char const *buf, ptrdiff_t nbyte,
2293 bool process_signals)
2231{ 2294{
2232 ssize_t rtnval; 2295 ptrdiff_t bytes_written = 0;
2233 ptrdiff_t bytes_written;
2234
2235 bytes_written = 0;
2236 2296
2237 while (nbyte > 0) 2297 while (nbyte > 0)
2238 { 2298 {
2239 rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT)); 2299 ssize_t n = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
2240 2300
2241 if (rtnval < 0) 2301 if (n < 0)
2242 { 2302 {
2243 if (errno == EINTR) 2303 if (errno == EINTR)
2244 { 2304 {
2245 /* I originally used `QUIT' but that might causes files to 2305 /* I originally used `QUIT' but that might causes files to
2246 be truncated if you hit C-g in the middle of it. --Stef */ 2306 be truncated if you hit C-g in the middle of it. --Stef */
2247 if (pending_signals) 2307 if (process_signals && pending_signals)
2248 process_pending_signals (); 2308 process_pending_signals ();
2249 continue; 2309 continue;
2250 } 2310 }
@@ -2252,12 +2312,57 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
2252 break; 2312 break;
2253 } 2313 }
2254 2314
2255 buf += rtnval; 2315 buf += n;
2256 nbyte -= rtnval; 2316 nbyte -= n;
2257 bytes_written += rtnval; 2317 bytes_written += n;
2258 } 2318 }
2259 2319
2260 return (bytes_written); 2320 return bytes_written;
2321}
2322
2323/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if
2324 interrupted or if a partial write occurs. Return the number of
2325 bytes written, setting errno if this is less than NBYTE. */
2326ptrdiff_t
2327emacs_write (int fildes, char const *buf, ptrdiff_t nbyte)
2328{
2329 return emacs_full_write (fildes, buf, nbyte, 0);
2330}
2331
2332/* Like emacs_write, but also process pending signals if interrupted. */
2333ptrdiff_t
2334emacs_write_sig (int fildes, char const *buf, ptrdiff_t nbyte)
2335{
2336 return emacs_full_write (fildes, buf, nbyte, 1);
2337}
2338
2339/* Write a diagnostic to standard error that contains MESSAGE and a
2340 string derived from errno. Preserve errno. Do not buffer stderr.
2341 Do not process pending signals if interrupted. */
2342void
2343emacs_perror (char const *message)
2344{
2345 int err = errno;
2346 char const *error_string = strerror (err);
2347 char const *command = (initial_argv && initial_argv[0]
2348 ? initial_argv[0] : "emacs");
2349 /* Write it out all at once, if it's short; this is less likely to
2350 be interleaved with other output. */
2351 char buf[BUFSIZ];
2352 int nbytes = snprintf (buf, sizeof buf, "%s: %s: %s\n",
2353 command, message, error_string);
2354 if (0 <= nbytes && nbytes < BUFSIZ)
2355 emacs_write (STDERR_FILENO, buf, nbytes);
2356 else
2357 {
2358 emacs_write (STDERR_FILENO, command, strlen (command));
2359 emacs_write (STDERR_FILENO, ": ", 2);
2360 emacs_write (STDERR_FILENO, message, strlen (message));
2361 emacs_write (STDERR_FILENO, ": ", 2);
2362 emacs_write (STDERR_FILENO, error_string, strlen (error_string));
2363 emacs_write (STDERR_FILENO, "\n", 1);
2364 }
2365 errno = err;
2261} 2366}
2262 2367
2263/* Return a struct timeval that is roughly equivalent to T. 2368/* Return a struct timeval that is roughly equivalent to T.
@@ -2611,7 +2716,7 @@ list_system_processes (void)
2611 2716
2612#endif /* !defined (WINDOWSNT) */ 2717#endif /* !defined (WINDOWSNT) */
2613 2718
2614#ifdef GNU_LINUX 2719#if defined GNU_LINUX && defined HAVE_LONG_LONG_INT
2615static EMACS_TIME 2720static EMACS_TIME
2616time_from_jiffies (unsigned long long tval, long hz) 2721time_from_jiffies (unsigned long long tval, long hz)
2617{ 2722{
diff --git a/src/systime.h b/src/systime.h
index 0e611a3f5e3..657f2cca11f 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -67,7 +67,9 @@ SYSTIME_INLINE time_t *emacs_secs_addr (EMACS_TIME *t) { return &t->tv_sec; }
67SYSTIME_INLINE EMACS_TIME 67SYSTIME_INLINE EMACS_TIME
68make_emacs_time (time_t s, int ns) 68make_emacs_time (time_t s, int ns)
69{ 69{
70 EMACS_TIME r = { s, ns }; 70 EMACS_TIME r;
71 r.tv_sec = s;
72 r.tv_nsec = ns;
71 return r; 73 return r;
72} 74}
73 75
@@ -75,7 +77,9 @@ make_emacs_time (time_t s, int ns)
75SYSTIME_INLINE EMACS_TIME 77SYSTIME_INLINE EMACS_TIME
76invalid_emacs_time (void) 78invalid_emacs_time (void)
77{ 79{
78 EMACS_TIME r = { 0, -1 }; 80 EMACS_TIME r;
81 r.tv_sec = 0;
82 r.tv_nsec = -1;
79 return r; 83 return r;
80} 84}
81 85
@@ -166,21 +170,6 @@ EMACS_TIME_EQ (EMACS_TIME t1, EMACS_TIME t2)
166 return timespec_cmp (t1, t2) == 0; 170 return timespec_cmp (t1, t2) == 0;
167} 171}
168SYSTIME_INLINE int 172SYSTIME_INLINE int
169EMACS_TIME_NE (EMACS_TIME t1, EMACS_TIME t2)
170{
171 return timespec_cmp (t1, t2) != 0;
172}
173SYSTIME_INLINE int
174EMACS_TIME_GT (EMACS_TIME t1, EMACS_TIME t2)
175{
176 return timespec_cmp (t1, t2) > 0;
177}
178SYSTIME_INLINE int
179EMACS_TIME_GE (EMACS_TIME t1, EMACS_TIME t2)
180{
181 return timespec_cmp (t1, t2) >= 0;
182}
183SYSTIME_INLINE int
184EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2) 173EMACS_TIME_LT (EMACS_TIME t1, EMACS_TIME t2)
185{ 174{
186 return timespec_cmp (t1, t2) < 0; 175 return timespec_cmp (t1, t2) < 0;
diff --git a/src/term.c b/src/term.c
index 39d143564c6..b6878a0abd1 100644
--- a/src/term.c
+++ b/src/term.c
@@ -71,13 +71,13 @@ static void tty_turn_off_highlight (struct tty_display_info *);
71static void tty_show_cursor (struct tty_display_info *); 71static void tty_show_cursor (struct tty_display_info *);
72static void tty_hide_cursor (struct tty_display_info *); 72static void tty_hide_cursor (struct tty_display_info *);
73static void tty_background_highlight (struct tty_display_info *tty); 73static void tty_background_highlight (struct tty_display_info *tty);
74static struct terminal *get_tty_terminal (Lisp_Object, int); 74static struct terminal *get_tty_terminal (Lisp_Object, bool);
75static void clear_tty_hooks (struct terminal *terminal); 75static void clear_tty_hooks (struct terminal *terminal);
76static void set_tty_hooks (struct terminal *terminal); 76static void set_tty_hooks (struct terminal *terminal);
77static void dissociate_if_controlling_tty (int fd); 77static void dissociate_if_controlling_tty (int fd);
78static void delete_tty (struct terminal *); 78static void delete_tty (struct terminal *);
79static _Noreturn void maybe_fatal (int must_succeed, struct terminal *terminal, 79static _Noreturn void maybe_fatal (bool, struct terminal *,
80 const char *str1, const char *str2, ...) 80 const char *, const char *, ...)
81 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5); 81 ATTRIBUTE_FORMAT_PRINTF (3, 5) ATTRIBUTE_FORMAT_PRINTF (4, 5);
82static _Noreturn void vfatal (const char *str, va_list ap) 82static _Noreturn void vfatal (const char *str, va_list ap)
83 ATTRIBUTE_FORMAT_PRINTF (1, 0); 83 ATTRIBUTE_FORMAT_PRINTF (1, 0);
@@ -85,8 +85,7 @@ static _Noreturn void vfatal (const char *str, va_list ap)
85 85
86#define OUTPUT(tty, a) \ 86#define OUTPUT(tty, a) \
87 emacs_tputs ((tty), a, \ 87 emacs_tputs ((tty), a, \
88 (int) (FRAME_LINES (XFRAME (selected_frame)) \ 88 FRAME_LINES (XFRAME (selected_frame)) - curY (tty), \
89 - curY (tty)), \
90 cmputc) 89 cmputc)
91 90
92#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc) 91#define OUTPUT1(tty, a) emacs_tputs ((tty), a, 1, cmputc)
@@ -695,7 +694,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
695{ 694{
696 unsigned char *conversion_buffer; 695 unsigned char *conversion_buffer;
697 struct coding_system *coding; 696 struct coding_system *coding;
698 size_t n, stringlen; 697 int n, stringlen;
699 698
700 struct tty_display_info *tty = FRAME_TTY (f); 699 struct tty_display_info *tty = FRAME_TTY (f);
701 700
@@ -1431,7 +1430,7 @@ static void append_glyph (struct it *);
1431static void append_composite_glyph (struct it *); 1430static void append_composite_glyph (struct it *);
1432static void produce_composite_glyph (struct it *); 1431static void produce_composite_glyph (struct it *);
1433static void append_glyphless_glyph (struct it *, int, const char *); 1432static void append_glyphless_glyph (struct it *, int, const char *);
1434static void produce_glyphless_glyph (struct it *, int, Lisp_Object); 1433static void produce_glyphless_glyph (struct it *, Lisp_Object);
1435 1434
1436/* Append glyphs to IT's glyph_row. Called from produce_glyphs for 1435/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1437 terminal frames if IT->glyph_row != NULL. IT->char_to_display is 1436 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
@@ -1551,7 +1550,7 @@ produce_glyphs (struct it *it)
1551 1550
1552 if (it->what == IT_GLYPHLESS) 1551 if (it->what == IT_GLYPHLESS)
1553 { 1552 {
1554 produce_glyphless_glyph (it, 0, Qnil); 1553 produce_glyphless_glyph (it, Qnil);
1555 goto done; 1554 goto done;
1556 } 1555 }
1557 1556
@@ -1620,7 +1619,7 @@ produce_glyphs (struct it *it)
1620 Lisp_Object acronym = lookup_glyphless_char_display (-1, it); 1619 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
1621 1620
1622 eassert (it->what == IT_GLYPHLESS); 1621 eassert (it->what == IT_GLYPHLESS);
1623 produce_glyphless_glyph (it, 1, acronym); 1622 produce_glyphless_glyph (it, acronym);
1624 } 1623 }
1625 } 1624 }
1626 1625
@@ -1794,14 +1793,12 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1794 the character. See the description of enum 1793 the character. See the description of enum
1795 glyphless_display_method in dispextern.h for the details. 1794 glyphless_display_method in dispextern.h for the details.
1796 1795
1797 FOR_NO_FONT is nonzero if and only if this is for a character that 1796 ACRONYM, if non-nil, is an acronym string for the character.
1798 is not supported by the coding system of the terminal. ACRONYM, if
1799 non-nil, is an acronym string for the character.
1800 1797
1801 The glyphs actually produced are of type CHAR_GLYPH. */ 1798 The glyphs actually produced are of type CHAR_GLYPH. */
1802 1799
1803static void 1800static void
1804produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) 1801produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
1805{ 1802{
1806 int face_id; 1803 int face_id;
1807 int len; 1804 int len;
@@ -1968,7 +1965,7 @@ turn_on_face (struct frame *f, int face_id)
1968 ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground; 1965 ts = tty->standout_mode ? tty->TS_set_background : tty->TS_set_foreground;
1969 if (fg >= 0 && ts) 1966 if (fg >= 0 && ts)
1970 { 1967 {
1971 p = tparam (ts, NULL, 0, (int) fg, 0, 0, 0); 1968 p = tparam (ts, NULL, 0, fg, 0, 0, 0);
1972 OUTPUT (tty, p); 1969 OUTPUT (tty, p);
1973 xfree (p); 1970 xfree (p);
1974 } 1971 }
@@ -1976,7 +1973,7 @@ turn_on_face (struct frame *f, int face_id)
1976 ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background; 1973 ts = tty->standout_mode ? tty->TS_set_foreground : tty->TS_set_background;
1977 if (bg >= 0 && ts) 1974 if (bg >= 0 && ts)
1978 { 1975 {
1979 p = tparam (ts, NULL, 0, (int) bg, 0, 0, 0); 1976 p = tparam (ts, NULL, 0, bg, 0, 0, 0);
1980 OUTPUT (tty, p); 1977 OUTPUT (tty, p);
1981 xfree (p); 1978 xfree (p);
1982 } 1979 }
@@ -2027,11 +2024,11 @@ turn_off_face (struct frame *f, int face_id)
2027} 2024}
2028 2025
2029 2026
2030/* Return non-zero if the terminal on frame F supports all of the 2027/* Return true if the terminal on frame F supports all of the
2031 capabilities in CAPS simultaneously, with foreground and background 2028 capabilities in CAPS simultaneously, with foreground and background
2032 colors FG and BG. */ 2029 colors FG and BG. */
2033 2030
2034int 2031bool
2035tty_capable_p (struct tty_display_info *tty, unsigned int caps, 2032tty_capable_p (struct tty_display_info *tty, unsigned int caps,
2036 unsigned long fg, unsigned long bg) 2033 unsigned long fg, unsigned long bg)
2037{ 2034{
@@ -2099,7 +2096,7 @@ static char *default_set_background;
2099/* Save or restore the default color-related capabilities of this 2096/* Save or restore the default color-related capabilities of this
2100 terminal. */ 2097 terminal. */
2101static void 2098static void
2102tty_default_color_capabilities (struct tty_display_info *tty, int save) 2099tty_default_color_capabilities (struct tty_display_info *tty, bool save)
2103{ 2100{
2104 2101
2105 if (save) 2102 if (save)
@@ -2209,7 +2206,7 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f)
2209/* Return the tty display object specified by TERMINAL. */ 2206/* Return the tty display object specified by TERMINAL. */
2210 2207
2211static struct terminal * 2208static struct terminal *
2212get_tty_terminal (Lisp_Object terminal, int throw) 2209get_tty_terminal (Lisp_Object terminal, bool throw)
2213{ 2210{
2214 struct terminal *t = get_terminal (terminal, throw); 2211 struct terminal *t = get_terminal (terminal, throw);
2215 2212
@@ -2481,7 +2478,7 @@ term_mouse_moveto (int x, int y)
2481 name = (const char *) ttyname (0); 2478 name = (const char *) ttyname (0);
2482 fd = emacs_open (name, O_WRONLY, 0); 2479 fd = emacs_open (name, O_WRONLY, 0);
2483 SOME_FUNCTION (x, y, fd); 2480 SOME_FUNCTION (x, y, fd);
2484 close (fd); 2481 emacs_close (fd);
2485 last_mouse_x = x; 2482 last_mouse_x = x;
2486 last_mouse_y = y; */ 2483 last_mouse_y = y; */
2487} 2484}
@@ -2519,7 +2516,7 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2519 cursor_to (f, save_y, save_x); 2516 cursor_to (f, save_y, save_x);
2520} 2517}
2521 2518
2522static int 2519static bool
2523term_mouse_movement (FRAME_PTR frame, Gpm_Event *event) 2520term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2524{ 2521{
2525 /* Has the mouse moved off the glyph it was on at the last sighting? */ 2522 /* Has the mouse moved off the glyph it was on at the last sighting? */
@@ -2649,7 +2646,7 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct in
2649{ 2646{
2650 struct frame *f = XFRAME (tty->top_frame); 2647 struct frame *f = XFRAME (tty->top_frame);
2651 struct input_event ie; 2648 struct input_event ie;
2652 int do_help = 0; 2649 bool do_help = 0;
2653 int count = 0; 2650 int count = 0;
2654 2651
2655 EVENT_INIT (ie); 2652 EVENT_INIT (ie);
@@ -2934,7 +2931,7 @@ dissociate_if_controlling_tty (int fd)
2934 If MUST_SUCCEED is true, then all errors are fatal. */ 2931 If MUST_SUCCEED is true, then all errors are fatal. */
2935 2932
2936struct terminal * 2933struct terminal *
2937init_tty (const char *name, const char *terminal_type, int must_succeed) 2934init_tty (const char *name, const char *terminal_type, bool must_succeed)
2938{ 2935{
2939 char *area = NULL; 2936 char *area = NULL;
2940 char **address = &area; 2937 char **address = &area;
@@ -2942,7 +2939,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
2942 int status; 2939 int status;
2943 struct tty_display_info *tty = NULL; 2940 struct tty_display_info *tty = NULL;
2944 struct terminal *terminal = NULL; 2941 struct terminal *terminal = NULL;
2945 int ctty = 0; /* 1 if asked to open controlling tty. */ 2942 bool ctty = 0; /* True if asked to open controlling tty. */
2946 2943
2947 if (!terminal_type) 2944 if (!terminal_type)
2948 maybe_fatal (must_succeed, 0, 2945 maybe_fatal (must_succeed, 0,
@@ -3015,7 +3012,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3015 name); 3012 name);
3016 if (!isatty (fd)) 3013 if (!isatty (fd))
3017 { 3014 {
3018 close (fd); 3015 emacs_close (fd);
3019 maybe_fatal (must_succeed, terminal, 3016 maybe_fatal (must_succeed, terminal,
3020 "Not a tty device: %s", 3017 "Not a tty device: %s",
3021 "Not a tty device: %s", 3018 "Not a tty device: %s",
@@ -3412,10 +3409,10 @@ vfatal (const char *str, va_list ap)
3412 3409
3413/* Auxiliary error-handling function for init_tty. 3410/* Auxiliary error-handling function for init_tty.
3414 Delete TERMINAL, then call error or fatal with str1 or str2, 3411 Delete TERMINAL, then call error or fatal with str1 or str2,
3415 respectively, according to whether MUST_SUCCEED is zero or not. */ 3412 respectively, according to whether MUST_SUCCEED is true. */
3416 3413
3417static void 3414static void
3418maybe_fatal (int must_succeed, struct terminal *terminal, 3415maybe_fatal (bool must_succeed, struct terminal *terminal,
3419 const char *str1, const char *str2, ...) 3416 const char *str1, const char *str2, ...)
3420{ 3417{
3421 va_list ap; 3418 va_list ap;
diff --git a/src/termcap.c b/src/termcap.c
index 7256eef9e81..be05828eea6 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -213,8 +213,8 @@ tgetst1 (char *ptr, char **area)
213 abbreviation expansion makes that effort a little more hairy than 213 abbreviation expansion makes that effort a little more hairy than
214 its worth; this is cleaner. */ 214 its worth; this is cleaner. */
215 { 215 {
216 register int last_p_param = 0; 216 int last_p_param = 0;
217 int remove_p_params = 1; 217 bool remove_p_params = 1;
218 struct { char *beg; int len; } cut[11]; 218 struct { char *beg; int len; } cut[11];
219 219
220 for (cut[0].beg = p = ret; p < r - 3; p++) 220 for (cut[0].beg = p = ret; p < r - 3; p++)
@@ -318,26 +318,26 @@ struct termcap_buffer
318 char *beg; 318 char *beg;
319 ptrdiff_t size; 319 ptrdiff_t size;
320 char *ptr; 320 char *ptr;
321 int ateof; 321 bool ateof;
322 ptrdiff_t full; 322 ptrdiff_t full;
323 }; 323 };
324 324
325/* Forward declarations of static functions. */ 325/* Forward declarations of static functions. */
326 326
327static int scan_file (char *str, int fd, register struct termcap_buffer *bufp); 327static bool scan_file (char *, int, struct termcap_buffer *);
328static char *gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end); 328static char *gobble_line (int, struct termcap_buffer *, char *);
329static int compare_contin (register char *str1, register char *str2); 329static bool compare_contin (char *, char *);
330static int name_match (char *line, char *name); 330static bool name_match (char *, char *);
331 331
332#ifdef MSDOS /* MW, May 1993 */ 332static bool
333static int
334valid_filename_p (char *fn) 333valid_filename_p (char *fn)
335{ 334{
335#ifdef MSDOS
336 return *fn == '/' || fn[1] == ':'; 336 return *fn == '/' || fn[1] == ':';
337}
338#else 337#else
339#define valid_filename_p(fn) (*(fn) == '/') 338 return *fn == '/';
340#endif 339#endif
340}
341 341
342/* Find the termcap entry data for terminal type NAME 342/* Find the termcap entry data for terminal type NAME
343 and store it in the block that BP points to. 343 and store it in the block that BP points to.
@@ -360,10 +360,10 @@ tgetent (char *bp, const char *name)
360 char *tc_search_point; 360 char *tc_search_point;
361 char *term; 361 char *term;
362 ptrdiff_t malloc_size = 0; 362 ptrdiff_t malloc_size = 0;
363 register int c; 363 int c;
364 char *tcenv = NULL; /* TERMCAP value, if it contains :tc=. */ 364 char *tcenv = NULL; /* TERMCAP value, if it contains :tc=. */
365 char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ 365 char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */
366 int filep; 366 bool filep;
367 367
368#ifdef INTERNAL_TERMINAL 368#ifdef INTERNAL_TERMINAL
369 /* For the internal terminal we don't want to read any termcap file, 369 /* For the internal terminal we don't want to read any termcap file,
@@ -455,7 +455,7 @@ tgetent (char *bp, const char *name)
455 /* Scan the file, reading it via buf, till find start of main entry. */ 455 /* Scan the file, reading it via buf, till find start of main entry. */
456 if (scan_file (term, fd, &buf) == 0) 456 if (scan_file (term, fd, &buf) == 0)
457 { 457 {
458 close (fd); 458 emacs_close (fd);
459 xfree (buf.beg); 459 xfree (buf.beg);
460 if (malloc_size) 460 if (malloc_size)
461 xfree (bp); 461 xfree (bp);
@@ -493,7 +493,7 @@ tgetent (char *bp, const char *name)
493 term = tgetst1 (tc_search_point, (char **) 0); 493 term = tgetst1 (tc_search_point, (char **) 0);
494 } 494 }
495 495
496 close (fd); 496 emacs_close (fd);
497 xfree (buf.beg); 497 xfree (buf.beg);
498 498
499 if (malloc_size) 499 if (malloc_size)
@@ -510,10 +510,10 @@ tgetent (char *bp, const char *name)
510 Return 1 if successful, with that line in BUFP, 510 Return 1 if successful, with that line in BUFP,
511 or 0 if no entry is found in the file. */ 511 or 0 if no entry is found in the file. */
512 512
513static int 513static bool
514scan_file (char *str, int fd, register struct termcap_buffer *bufp) 514scan_file (char *str, int fd, struct termcap_buffer *bufp)
515{ 515{
516 register char *end; 516 char *end;
517 517
518 bufp->ptr = bufp->beg; 518 bufp->ptr = bufp->beg;
519 bufp->full = 0; 519 bufp->full = 0;
@@ -544,13 +544,13 @@ scan_file (char *str, int fd, register struct termcap_buffer *bufp)
544 return 0; 544 return 0;
545} 545}
546 546
547/* Return nonzero if NAME is one of the names specified 547/* Return true if NAME is one of the names specified
548 by termcap entry LINE. */ 548 by termcap entry LINE. */
549 549
550static int 550static bool
551name_match (char *line, char *name) 551name_match (char *line, char *name)
552{ 552{
553 register char *tem; 553 char *tem;
554 554
555 if (!compare_contin (line, name)) 555 if (!compare_contin (line, name))
556 return 1; 556 return 1;
@@ -562,18 +562,18 @@ name_match (char *line, char *name)
562 return 0; 562 return 0;
563} 563}
564 564
565static int 565static bool
566compare_contin (register char *str1, register char *str2) 566compare_contin (char *str1, char *str2)
567{ 567{
568 register int c1, c2;
569 while (1) 568 while (1)
570 { 569 {
571 c1 = *str1++; 570 int c1 = *str1++;
572 c2 = *str2++; 571 int c2 = *str2++;
573 while (c1 == '\\' && *str1 == '\n') 572 while (c1 == '\\' && *str1 == '\n')
574 { 573 {
575 str1++; 574 str1++;
576 while ((c1 = *str1++) == ' ' || c1 == '\t'); 575 while ((c1 = *str1++) == ' ' || c1 == '\t')
576 continue;
577 } 577 }
578 if (c2 == '\0') 578 if (c2 == '\0')
579 { 579 {
@@ -647,57 +647,3 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
647 } 647 }
648 return end + 1; 648 return end + 1;
649} 649}
650
651#ifdef TEST
652
653#include <stdio.h>
654
655static void
656tprint (char *cap)
657{
658 char *x = tgetstr (cap, 0);
659 register char *y;
660
661 printf ("%s: ", cap);
662 if (x)
663 {
664 for (y = x; *y; y++)
665 if (*y <= ' ' || *y == 0177)
666 printf ("\\%0o", *y);
667 else
668 putchar (*y);
669 free (x);
670 }
671 else
672 printf ("none");
673 putchar ('\n');
674}
675
676int
677main (int argc, char **argv)
678{
679 char *term;
680 char *buf;
681
682 term = argv[1];
683 printf ("TERM: %s\n", term);
684
685 buf = (char *) tgetent (0, term);
686 if ((int) buf <= 0)
687 {
688 printf ("No entry.\n");
689 return 0;
690 }
691
692 printf ("Entry: %s\n", buf);
693
694 tprint ("cm");
695 tprint ("AL");
696
697 printf ("co: %d\n", tgetnum ("co"));
698 printf ("am: %d\n", tgetflag ("am"));
699
700 return 0;
701}
702
703#endif /* TEST */
diff --git a/src/termhooks.h b/src/termhooks.h
index 4f3fa9cb47f..0190478c254 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -643,7 +643,7 @@ extern struct terminal *terminal_list;
643 (((d)->type != output_termcap && (d)->type != output_msdos_raw) \ 643 (((d)->type != output_termcap && (d)->type != output_msdos_raw) \
644 || (d)->display_info.tty->input) 644 || (d)->display_info.tty->input)
645 645
646extern struct terminal *get_terminal (Lisp_Object terminal, int); 646extern struct terminal *get_terminal (Lisp_Object terminal, bool);
647extern struct terminal *create_terminal (void); 647extern struct terminal *create_terminal (void);
648extern void delete_terminal (struct terminal *); 648extern void delete_terminal (struct terminal *);
649 649
diff --git a/src/terminal.c b/src/terminal.c
index c99c39c64ae..c55fd4eb077 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -199,11 +199,11 @@ ins_del_lines (struct frame *f, int vpos, int n)
199 199
200/* Return the terminal object specified by TERMINAL. TERMINAL may be 200/* Return the terminal object specified by TERMINAL. TERMINAL may be
201 a terminal object, a frame, or nil for the terminal device of the 201 a terminal object, a frame, or nil for the terminal device of the
202 current frame. If THROW is zero, return NULL for failure, 202 current frame. If THROW is false, return NULL for failure,
203 otherwise throw an error. */ 203 otherwise throw an error. */
204 204
205struct terminal * 205struct terminal *
206get_terminal (Lisp_Object terminal, int throw) 206get_terminal (Lisp_Object terminal, bool throw)
207{ 207{
208 struct terminal *result = NULL; 208 struct terminal *result = NULL;
209 209
diff --git a/src/undo.c b/src/undo.c
index d8711882fbf..234b8510f0a 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -229,10 +229,9 @@ record_first_change (void)
229 if (base_buffer->base_buffer) 229 if (base_buffer->base_buffer)
230 base_buffer = base_buffer->base_buffer; 230 base_buffer = base_buffer->base_buffer;
231 231
232 bset_undo_list 232 bset_undo_list (current_buffer,
233 (current_buffer, 233 Fcons (Fcons (Qt, Fvisited_file_modtime ()),
234 Fcons (Fcons (Qt, make_lisp_time (base_buffer->modtime)), 234 BVAR (current_buffer, undo_list)));
235 BVAR (current_buffer, undo_list)));
236} 235}
237 236
238/* Record a change in property PROP (whose old value was VAL) 237/* Record a change in property PROP (whose old value was VAL)
diff --git a/src/unexaix.c b/src/unexaix.c
index 204f6cf4ad3..757ba6f51b3 100644
--- a/src/unexaix.c
+++ b/src/unexaix.c
@@ -94,13 +94,10 @@ static int pagemask;
94static _Noreturn void 94static _Noreturn void
95report_error (const char *file, int fd) 95report_error (const char *file, int fd)
96{ 96{
97 int err = errno;
97 if (fd) 98 if (fd)
98 { 99 emacs_close (fd);
99 int failed_errno = errno; 100 report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err);
100 close (fd);
101 errno = failed_errno;
102 }
103 report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil));
104} 101}
105 102
106#define ERROR0(msg) report_error_1 (new, msg) 103#define ERROR0(msg) report_error_1 (new, msg)
@@ -111,7 +108,7 @@ static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (2, 3)
111report_error_1 (int fd, const char *msg, ...) 108report_error_1 (int fd, const char *msg, ...)
112{ 109{
113 va_list ap; 110 va_list ap;
114 close (fd); 111 emacs_close (fd);
115 va_start (ap, msg); 112 va_start (ap, msg);
116 verror (msg, ap); 113 verror (msg, ap);
117 va_end (ap); 114 va_end (ap);
@@ -148,13 +145,13 @@ unexec (const char *new_name, const char *a_name)
148 || adjust_lnnoptrs (new, a_out, new_name) < 0 145 || adjust_lnnoptrs (new, a_out, new_name) < 0
149 || unrelocate_symbols (new, a_out, a_name, new_name) < 0) 146 || unrelocate_symbols (new, a_out, a_name, new_name) < 0)
150 { 147 {
151 close (new); 148 emacs_close (new);
152 return; 149 return;
153 } 150 }
154 151
155 close (new); 152 emacs_close (new);
156 if (a_out >= 0) 153 if (a_out >= 0)
157 close (a_out); 154 emacs_close (a_out);
158 mark_x (new_name); 155 mark_x (new_name);
159} 156}
160 157
@@ -534,7 +531,7 @@ adjust_lnnoptrs (int writedesc, int readdesc, const char *new_name)
534 } 531 }
535 } 532 }
536 } 533 }
537 close (new); 534 emacs_close (new);
538 535
539 return 0; 536 return 0;
540} 537}
diff --git a/src/unexcoff.c b/src/unexcoff.c
index e79821251ba..c467e59a665 100644
--- a/src/unexcoff.c
+++ b/src/unexcoff.c
@@ -127,9 +127,10 @@ static int pagemask;
127static void 127static void
128report_error (const char *file, int fd) 128report_error (const char *file, int fd)
129{ 129{
130 int err = errno;
130 if (fd) 131 if (fd)
131 close (fd); 132 emacs_close (fd);
132 report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil)); 133 report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err);
133} 134}
134 135
135#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1 136#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
@@ -139,7 +140,7 @@ report_error (const char *file, int fd)
139static void 140static void
140report_error_1 (int fd, const char *msg, int a1, int a2) 141report_error_1 (int fd, const char *msg, int a1, int a2)
141{ 142{
142 close (fd); 143 emacs_close (fd);
143 error (msg, a1, a2); 144 error (msg, a1, a2);
144} 145}
145 146
@@ -511,7 +512,7 @@ adjust_lnnoptrs (int writedesc, int readdesc, const char *new_name)
511 } 512 }
512 } 513 }
513#ifndef MSDOS 514#ifndef MSDOS
514 close (new); 515 emacs_close (new);
515#endif 516#endif
516 return 0; 517 return 0;
517} 518}
@@ -541,13 +542,13 @@ unexec (const char *new_name, const char *a_name)
541 || adjust_lnnoptrs (new, a_out, new_name) < 0 542 || adjust_lnnoptrs (new, a_out, new_name) < 0
542 ) 543 )
543 { 544 {
544 close (new); 545 emacs_close (new);
545 return; 546 return;
546 } 547 }
547 548
548 close (new); 549 emacs_close (new);
549 if (a_out >= 0) 550 if (a_out >= 0)
550 close (a_out); 551 emacs_close (a_out);
551 mark_x (new_name); 552 mark_x (new_name);
552} 553}
553 554
diff --git a/src/unexcw.c b/src/unexcw.c
index 0312a7328fb..12435a85051 100644
--- a/src/unexcw.c
+++ b/src/unexcw.c
@@ -316,13 +316,13 @@ unexec (const char *outfile, const char *infile)
316 ret2 = write (fd_out, buffer, ret); 316 ret2 = write (fd_out, buffer, ret);
317 assert (ret2 == ret); 317 assert (ret2 == ret);
318 } 318 }
319 ret = close (fd_in); 319 ret = emacs_close (fd_in);
320 assert (ret == 0); 320 assert (ret == 0);
321 321
322 bss_sbrk_did_unexec = 1; 322 bss_sbrk_did_unexec = 1;
323 fixup_executable (fd_out); 323 fixup_executable (fd_out);
324 bss_sbrk_did_unexec = 0; 324 bss_sbrk_did_unexec = 0;
325 325
326 ret = close (fd_out); 326 ret = emacs_close (fd_out);
327 assert (ret == 0); 327 assert (ret == 0);
328} 328}
diff --git a/src/unexelf.c b/src/unexelf.c
index 28847157e40..e2412393286 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -1312,13 +1312,13 @@ temacs:
1312 /* Close the files and make the new file executable. */ 1312 /* Close the files and make the new file executable. */
1313 1313
1314#if MAP_ANON == 0 1314#if MAP_ANON == 0
1315 close (mmap_fd); 1315 emacs_close (mmap_fd);
1316#endif 1316#endif
1317 1317
1318 if (close (old_file) != 0) 1318 if (emacs_close (old_file) != 0)
1319 fatal ("Can't close (%s): %s", old_name, strerror (errno)); 1319 fatal ("Can't close (%s): %s", old_name, strerror (errno));
1320 1320
1321 if (close (new_file) != 0) 1321 if (emacs_close (new_file) != 0)
1322 fatal ("Can't close (%s): %s", new_name, strerror (errno)); 1322 fatal ("Can't close (%s): %s", new_name, strerror (errno));
1323 1323
1324 if (stat (new_name, &stat_buf) != 0) 1324 if (stat (new_name, &stat_buf) != 0)
diff --git a/src/unexhp9k800.c b/src/unexhp9k800.c
index 0f6eb87ee01..bee2517307a 100644
--- a/src/unexhp9k800.c
+++ b/src/unexhp9k800.c
@@ -306,6 +306,6 @@ unexec (const char *new_name, /* name of the new a.out file to be created *
306 write_header (new, &hdr, &auxhdr); 306 write_header (new, &hdr, &auxhdr);
307 307
308 /* Close the binary file */ 308 /* Close the binary file */
309 close (old); 309 emacs_close (old);
310 close (new); 310 emacs_close (new);
311} 311}
diff --git a/src/unexmacosx.c b/src/unexmacosx.c
index 2bc6de177eb..87848b012ba 100644
--- a/src/unexmacosx.c
+++ b/src/unexmacosx.c
@@ -1332,7 +1332,7 @@ unexec (const char *outfile, const char *infile)
1332 outfd = emacs_open (outfile, O_WRONLY | O_TRUNC | O_CREAT, 0755); 1332 outfd = emacs_open (outfile, O_WRONLY | O_TRUNC | O_CREAT, 0755);
1333 if (outfd < 0) 1333 if (outfd < 0)
1334 { 1334 {
1335 close (infd); 1335 emacs_close (infd);
1336 unexec_error ("cannot open output file `%s'", outfile); 1336 unexec_error ("cannot open output file `%s'", outfile);
1337 } 1337 }
1338 1338
@@ -1346,7 +1346,7 @@ unexec (const char *outfile, const char *infile)
1346 1346
1347 dump_it (); 1347 dump_it ();
1348 1348
1349 close (outfd); 1349 emacs_close (outfd);
1350} 1350}
1351 1351
1352 1352
diff --git a/src/w32.c b/src/w32.c
index 230479cd61a..1a3d81bbffc 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -234,6 +234,8 @@ extern int sys_access (const char *, int);
234extern void *e_malloc (size_t); 234extern void *e_malloc (size_t);
235extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *, 235extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
236 EMACS_TIME *, void *); 236 EMACS_TIME *, void *);
237extern int sys_dup (int);
238
237 239
238 240
239 241
@@ -6719,10 +6721,16 @@ sys_sendto (int s, const char * buf, int len, int flags,
6719} 6721}
6720 6722
6721/* Windows does not have an fcntl function. Provide an implementation 6723/* Windows does not have an fcntl function. Provide an implementation
6722 solely for making sockets non-blocking. */ 6724 good enough for Emacs. */
6723int 6725int
6724fcntl (int s, int cmd, int options) 6726fcntl (int s, int cmd, int options)
6725{ 6727{
6728 /* In the w32 Emacs port, fcntl (fd, F_DUPFD_CLOEXEC, fd1) is always
6729 invoked in a context where fd1 is closed and all descriptors less
6730 than fd1 are open, so sys_dup is an adequate implementation. */
6731 if (cmd == F_DUPFD_CLOEXEC)
6732 return sys_dup (s);
6733
6726 if (winsock_lib == NULL) 6734 if (winsock_lib == NULL)
6727 { 6735 {
6728 errno = ENETDOWN; 6736 errno = ENETDOWN;
@@ -6864,13 +6872,14 @@ sys_dup2 (int src, int dst)
6864 return rc; 6872 return rc;
6865} 6873}
6866 6874
6867/* Unix pipe() has only one arg */
6868int 6875int
6869sys_pipe (int * phandles) 6876pipe2 (int * phandles, int pipe2_flags)
6870{ 6877{
6871 int rc; 6878 int rc;
6872 unsigned flags; 6879 unsigned flags;
6873 6880
6881 eassert (pipe2_flags == O_CLOEXEC);
6882
6874 /* make pipe handles non-inheritable; when we spawn a child, we 6883 /* make pipe handles non-inheritable; when we spawn a child, we
6875 replace the relevant handle with an inheritable one. Also put 6884 replace the relevant handle with an inheritable one. Also put
6876 pipes into binary mode; we will do text mode translation ourselves 6885 pipes into binary mode; we will do text mode translation ourselves
diff --git a/src/w32.h b/src/w32.h
index 17da0778db1..9c1f1efa699 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -188,7 +188,7 @@ extern int random (void);
188 188
189extern int fchmod (int, mode_t); 189extern int fchmod (int, mode_t);
190extern int sys_rename_replace (char const *, char const *, BOOL); 190extern int sys_rename_replace (char const *, char const *, BOOL);
191extern int sys_pipe (int *); 191extern int pipe2 (int *, int);
192 192
193extern void set_process_dir (char *); 193extern void set_process_dir (char *);
194extern int sys_spawnve (int, char *, char **, char **); 194extern int sys_spawnve (int, char *, char **, char **);
diff --git a/src/xdisp.c b/src/xdisp.c
index 5869ce5fdfa..12b294e6800 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12589,6 +12589,7 @@ static void debug_method_add (struct window *, char const *, ...)
12589static void 12589static void
12590debug_method_add (struct window *w, char const *fmt, ...) 12590debug_method_add (struct window *w, char const *fmt, ...)
12591{ 12591{
12592 void *ptr = w;
12592 char *method = w->desired_matrix->method; 12593 char *method = w->desired_matrix->method;
12593 int len = strlen (method); 12594 int len = strlen (method);
12594 int size = sizeof w->desired_matrix->method; 12595 int size = sizeof w->desired_matrix->method;
@@ -12607,7 +12608,7 @@ debug_method_add (struct window *w, char const *fmt, ...)
12607 12608
12608 if (trace_redisplay_p) 12609 if (trace_redisplay_p)
12609 fprintf (stderr, "%p (%s): %s\n", 12610 fprintf (stderr, "%p (%s): %s\n",
12610 w, 12611 ptr,
12611 ((BUFFERP (w->contents) 12612 ((BUFFERP (w->contents)
12612 && STRINGP (BVAR (XBUFFER (w->contents), name))) 12613 && STRINGP (BVAR (XBUFFER (w->contents), name)))
12613 ? SSDATA (BVAR (XBUFFER (w->contents), name)) 12614 ? SSDATA (BVAR (XBUFFER (w->contents), name))
diff --git a/src/xrdb.c b/src/xrdb.c
index c25c25d6f33..7c9cd53fa8c 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -634,10 +634,7 @@ member (char *elt, List list)
634static void 634static void
635fatal (char *msg, char *prog) 635fatal (char *msg, char *prog)
636{ 636{
637 if (errno) 637 fprintf (stderr, msg, prog);
638 perror (prog);
639
640 (void) fprintf (stderr, msg, prog);
641 exit (1); 638 exit (1);
642} 639}
643 640
diff --git a/src/xsettings.c b/src/xsettings.c
index f48c49dbafe..45f8435d9f4 100644
--- a/src/xsettings.c
+++ b/src/xsettings.c
@@ -170,7 +170,7 @@ enum {
170 SEEN_HINTSTYLE = 0x10, 170 SEEN_HINTSTYLE = 0x10,
171 SEEN_DPI = 0x20, 171 SEEN_DPI = 0x20,
172 SEEN_FONT = 0x40, 172 SEEN_FONT = 0x40,
173 SEEN_TB_STYLE = 0x80, 173 SEEN_TB_STYLE = 0x80
174}; 174};
175struct xsettings 175struct xsettings
176{ 176{
@@ -687,7 +687,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
687 { 687 {
688 static char const format[] = 688 static char const format[] =
689 "Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, " 689 "Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, "
690 "Hintstyle: %d, DPI: %lf"; 690 "Hintstyle: %d, DPI: %f";
691 enum 691 enum
692 { 692 {
693 d_formats = 5, 693 d_formats = 5,
@@ -696,7 +696,7 @@ apply_xft_settings (struct x_display_info *dpyinfo,
696 max_f_integer_digits = DBL_MAX_10_EXP + 1, 696 max_f_integer_digits = DBL_MAX_10_EXP + 1,
697 f_precision = 6, 697 f_precision = 6,
698 lf_growth = (sizeof "-." + max_f_integer_digits + f_precision 698 lf_growth = (sizeof "-." + max_f_integer_digits + f_precision
699 - sizeof "%lf") 699 - sizeof "%f")
700 }; 700 };
701 char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth]; 701 char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth];
702 702
diff --git a/src/xterm.c b/src/xterm.c
index f0b95d585e3..818b69cc41d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2647,7 +2647,10 @@ x_draw_underwave (struct glyph_string *s)
2647 2647
2648 /* Find and set clipping rectangle */ 2648 /* Find and set clipping rectangle */
2649 2649
2650 wave_clip = (XRectangle){ x0, y0, width, wave_height }; 2650 wave_clip.x = x0;
2651 wave_clip.y = y0;
2652 wave_clip.width = width;
2653 wave_clip.height = wave_height;
2651 get_glyph_string_clip_rect (s, &string_clip); 2654 get_glyph_string_clip_rect (s, &string_clip);
2652 2655
2653 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip)) 2656 if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
@@ -10191,71 +10194,73 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10191 } 10194 }
10192 10195
10193 { 10196 {
10194 const struct 10197 static const struct
10195 { 10198 {
10196 const char *name; 10199 const char *name;
10197 Atom *atom; 10200 int offset;
10198 } atom_refs[] = { 10201 } atom_refs[] = {
10199 { "WM_PROTOCOLS", &dpyinfo->Xatom_wm_protocols }, 10202#define ATOM_REFS_INIT(string, member) \
10200 { "WM_TAKE_FOCUS", &dpyinfo->Xatom_wm_take_focus }, 10203 { string, offsetof (struct x_display_info, member) },
10201 { "WM_SAVE_YOURSELF", &dpyinfo->Xatom_wm_save_yourself }, 10204 ATOM_REFS_INIT ("WM_PROTOCOLS", Xatom_wm_protocols)
10202 { "WM_DELETE_WINDOW", &dpyinfo->Xatom_wm_delete_window }, 10205 ATOM_REFS_INIT ("WM_TAKE_FOCUS", Xatom_wm_take_focus)
10203 { "WM_CHANGE_STATE", &dpyinfo->Xatom_wm_change_state }, 10206 ATOM_REFS_INIT ("WM_SAVE_YOURSELF", Xatom_wm_save_yourself)
10204 { "WM_CONFIGURE_DENIED", &dpyinfo->Xatom_wm_configure_denied }, 10207 ATOM_REFS_INIT ("WM_DELETE_WINDOW", Xatom_wm_delete_window)
10205 { "WM_MOVED", &dpyinfo->Xatom_wm_window_moved }, 10208 ATOM_REFS_INIT ("WM_CHANGE_STATE", Xatom_wm_change_state)
10206 { "WM_CLIENT_LEADER", &dpyinfo->Xatom_wm_client_leader }, 10209 ATOM_REFS_INIT ("WM_CONFIGURE_DENIED", Xatom_wm_configure_denied)
10207 { "Editres", &dpyinfo->Xatom_editres }, 10210 ATOM_REFS_INIT ("WM_MOVED", Xatom_wm_window_moved)
10208 { "CLIPBOARD", &dpyinfo->Xatom_CLIPBOARD }, 10211 ATOM_REFS_INIT ("WM_CLIENT_LEADER", Xatom_wm_client_leader)
10209 { "TIMESTAMP", &dpyinfo->Xatom_TIMESTAMP }, 10212 ATOM_REFS_INIT ("Editres", Xatom_editres)
10210 { "TEXT", &dpyinfo->Xatom_TEXT }, 10213 ATOM_REFS_INIT ("CLIPBOARD", Xatom_CLIPBOARD)
10211 { "COMPOUND_TEXT", &dpyinfo->Xatom_COMPOUND_TEXT }, 10214 ATOM_REFS_INIT ("TIMESTAMP", Xatom_TIMESTAMP)
10212 { "UTF8_STRING", &dpyinfo->Xatom_UTF8_STRING }, 10215 ATOM_REFS_INIT ("TEXT", Xatom_TEXT)
10213 { "DELETE", &dpyinfo->Xatom_DELETE }, 10216 ATOM_REFS_INIT ("COMPOUND_TEXT", Xatom_COMPOUND_TEXT)
10214 { "MULTIPLE", &dpyinfo->Xatom_MULTIPLE }, 10217 ATOM_REFS_INIT ("UTF8_STRING", Xatom_UTF8_STRING)
10215 { "INCR", &dpyinfo->Xatom_INCR }, 10218 ATOM_REFS_INIT ("DELETE", Xatom_DELETE)
10216 { "_EMACS_TMP_", &dpyinfo->Xatom_EMACS_TMP }, 10219 ATOM_REFS_INIT ("MULTIPLE", Xatom_MULTIPLE)
10217 { "TARGETS", &dpyinfo->Xatom_TARGETS }, 10220 ATOM_REFS_INIT ("INCR", Xatom_INCR)
10218 { "NULL", &dpyinfo->Xatom_NULL }, 10221 ATOM_REFS_INIT ("_EMACS_TMP_", Xatom_EMACS_TMP)
10219 { "ATOM", &dpyinfo->Xatom_ATOM }, 10222 ATOM_REFS_INIT ("TARGETS", Xatom_TARGETS)
10220 { "ATOM_PAIR", &dpyinfo->Xatom_ATOM_PAIR }, 10223 ATOM_REFS_INIT ("NULL", Xatom_NULL)
10221 { "CLIPBOARD_MANAGER", &dpyinfo->Xatom_CLIPBOARD_MANAGER }, 10224 ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
10222 { "_XEMBED_INFO", &dpyinfo->Xatom_XEMBED_INFO }, 10225 ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
10226 ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
10227 ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
10223 /* For properties of font. */ 10228 /* For properties of font. */
10224 { "PIXEL_SIZE", &dpyinfo->Xatom_PIXEL_SIZE }, 10229 ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
10225 { "AVERAGE_WIDTH", &dpyinfo->Xatom_AVERAGE_WIDTH }, 10230 ATOM_REFS_INIT ("AVERAGE_WIDTH", Xatom_AVERAGE_WIDTH)
10226 { "_MULE_BASELINE_OFFSET", &dpyinfo->Xatom_MULE_BASELINE_OFFSET }, 10231 ATOM_REFS_INIT ("_MULE_BASELINE_OFFSET", Xatom_MULE_BASELINE_OFFSET)
10227 { "_MULE_RELATIVE_COMPOSE", &dpyinfo->Xatom_MULE_RELATIVE_COMPOSE }, 10232 ATOM_REFS_INIT ("_MULE_RELATIVE_COMPOSE", Xatom_MULE_RELATIVE_COMPOSE)
10228 { "_MULE_DEFAULT_ASCENT", &dpyinfo->Xatom_MULE_DEFAULT_ASCENT }, 10233 ATOM_REFS_INIT ("_MULE_DEFAULT_ASCENT", Xatom_MULE_DEFAULT_ASCENT)
10229 /* Ghostscript support. */ 10234 /* Ghostscript support. */
10230 { "DONE", &dpyinfo->Xatom_DONE }, 10235 ATOM_REFS_INIT ("DONE", Xatom_DONE)
10231 { "PAGE", &dpyinfo->Xatom_PAGE }, 10236 ATOM_REFS_INIT ("PAGE", Xatom_PAGE)
10232 { "SCROLLBAR", &dpyinfo->Xatom_Scrollbar }, 10237 ATOM_REFS_INIT ("SCROLLBAR", Xatom_Scrollbar)
10233 { "_XEMBED", &dpyinfo->Xatom_XEMBED }, 10238 ATOM_REFS_INIT ("_XEMBED", Xatom_XEMBED)
10234 /* EWMH */ 10239 /* EWMH */
10235 { "_NET_WM_STATE", &dpyinfo->Xatom_net_wm_state }, 10240 ATOM_REFS_INIT ("_NET_WM_STATE", Xatom_net_wm_state)
10236 { "_NET_WM_STATE_FULLSCREEN", &dpyinfo->Xatom_net_wm_state_fullscreen }, 10241 ATOM_REFS_INIT ("_NET_WM_STATE_FULLSCREEN", Xatom_net_wm_state_fullscreen)
10237 { "_NET_WM_STATE_MAXIMIZED_HORZ", 10242 ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_HORZ",
10238 &dpyinfo->Xatom_net_wm_state_maximized_horz }, 10243 Xatom_net_wm_state_maximized_horz)
10239 { "_NET_WM_STATE_MAXIMIZED_VERT", 10244 ATOM_REFS_INIT ("_NET_WM_STATE_MAXIMIZED_VERT",
10240 &dpyinfo->Xatom_net_wm_state_maximized_vert }, 10245 Xatom_net_wm_state_maximized_vert)
10241 { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky }, 10246 ATOM_REFS_INIT ("_NET_WM_STATE_STICKY", Xatom_net_wm_state_sticky)
10242 { "_NET_WM_STATE_HIDDEN", &dpyinfo->Xatom_net_wm_state_hidden }, 10247 ATOM_REFS_INIT ("_NET_WM_STATE_HIDDEN", Xatom_net_wm_state_hidden)
10243 { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type }, 10248 ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE", Xatom_net_window_type)
10244 { "_NET_WM_WINDOW_TYPE_TOOLTIP", 10249 ATOM_REFS_INIT ("_NET_WM_WINDOW_TYPE_TOOLTIP",
10245 &dpyinfo->Xatom_net_window_type_tooltip }, 10250 Xatom_net_window_type_tooltip)
10246 { "_NET_WM_ICON_NAME", &dpyinfo->Xatom_net_wm_icon_name }, 10251 ATOM_REFS_INIT ("_NET_WM_ICON_NAME", Xatom_net_wm_icon_name)
10247 { "_NET_WM_NAME", &dpyinfo->Xatom_net_wm_name }, 10252 ATOM_REFS_INIT ("_NET_WM_NAME", Xatom_net_wm_name)
10248 { "_NET_SUPPORTED", &dpyinfo->Xatom_net_supported }, 10253 ATOM_REFS_INIT ("_NET_SUPPORTED", Xatom_net_supported)
10249 { "_NET_SUPPORTING_WM_CHECK", &dpyinfo->Xatom_net_supporting_wm_check }, 10254 ATOM_REFS_INIT ("_NET_SUPPORTING_WM_CHECK", Xatom_net_supporting_wm_check)
10250 { "_NET_WM_WINDOW_OPACITY", &dpyinfo->Xatom_net_wm_window_opacity }, 10255 ATOM_REFS_INIT ("_NET_WM_WINDOW_OPACITY", Xatom_net_wm_window_opacity)
10251 { "_NET_ACTIVE_WINDOW", &dpyinfo->Xatom_net_active_window }, 10256 ATOM_REFS_INIT ("_NET_ACTIVE_WINDOW", Xatom_net_active_window)
10252 { "_NET_FRAME_EXTENTS", &dpyinfo->Xatom_net_frame_extents }, 10257 ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
10253 { "_NET_CURRENT_DESKTOP", &dpyinfo->Xatom_net_current_desktop }, 10258 ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
10254 { "_NET_WORKAREA", &dpyinfo->Xatom_net_workarea }, 10259 ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
10255 /* Session management */ 10260 /* Session management */
10256 { "SM_CLIENT_ID", &dpyinfo->Xatom_SM_CLIENT_ID }, 10261 ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
10257 { "_XSETTINGS_SETTINGS", &dpyinfo->Xatom_xsettings_prop }, 10262 ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
10258 { "MANAGER", &dpyinfo->Xatom_xsettings_mgr }, 10263 ATOM_REFS_INIT ("MANAGER", Xatom_xsettings_mgr)
10259 }; 10264 };
10260 10265
10261 int i; 10266 int i;
@@ -10280,7 +10285,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
10280 False, atoms_return); 10285 False, atoms_return);
10281 10286
10282 for (i = 0; i < atom_count; i++) 10287 for (i = 0; i < atom_count; i++)
10283 *atom_refs[i].atom = atoms_return[i]; 10288 *(Atom *) ((char *) dpyinfo + atom_refs[i].offset) = atoms_return[i];
10284 10289
10285 /* Manual copy of last atom */ 10290 /* Manual copy of last atom */
10286 dpyinfo->Xatom_xsettings_sel = atoms_return[i]; 10291 dpyinfo->Xatom_xsettings_sel = atoms_return[i];