aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog230
-rw-r--r--src/Makefile.in3
-rw-r--r--src/callproc.c23
-rw-r--r--src/charset.c2
-rw-r--r--src/conf_post.h4
-rw-r--r--src/dispnew.c82
-rw-r--r--src/editfns.c4
-rw-r--r--src/emacs.c4
-rw-r--r--src/eval.c4
-rw-r--r--src/fileio.c184
-rw-r--r--src/keyboard.c4
-rw-r--r--src/lisp.h2
-rw-r--r--src/lread.c92
-rw-r--r--src/makefile.w32-in12
-rw-r--r--src/nsterm.m38
-rw-r--r--src/process.c116
-rw-r--r--src/sysdep.c33
-rw-r--r--src/term.c39
-rw-r--r--src/unexelf.c2
-rw-r--r--src/w32.c39
-rw-r--r--src/w32proc.c166
-rw-r--r--src/w32select.c2
-rw-r--r--src/w32term.h15
-rw-r--r--src/xdisp.c14
-rw-r--r--src/xfaces.c8
-rw-r--r--src/xrdb.c101
26 files changed, 675 insertions, 548 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 88352c201b6..2a0c0e6822d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,233 @@
12012-11-18 Paul Eggert <eggert@cs.ucla.edu>
2
3 * nsterm.m (ns_select): Send SIGIO only to self, not to process group.
4
52012-11-18 Eli Zaretskii <eliz@gnu.org>
6
7 * w32select.c: Include w32common.h before w32term.h, so that
8 windows.h gets included before w32term.h uses some of its
9 features, see below.
10
11 * w32term.h (LOCALE_ENUMPROCA, LOCALE_ENUMPROCW) [_MSC_VER]: New
12 typedefs.
13 (EnumSystemLocalesA, EnumSystemLocalesW) [_MSC_VER]: New
14 prototypes.
15 (EnumSystemLocales) [_MSC_VER]: Define if undefined. (Bug#12878)
16
172012-11-18 Jan Djärv <jan.h.d@swipnet.se>
18
19 * nsterm.m (hold_event): Set send_appdefined to YES (Bug#12834).
20 (ns_select): Return at once if events are held (Bug#12834).
21
222012-11-18 enami tsugutomo <tsugutomo.enami@jp.sony.com>
23
24 * unexelf.c (ELFSIZE) [__NetBSD__ && _LP64]: Set to 64.
25 Needed following 2012-10-20 change. (Bug#12902)
26
272012-11-18 Juanma Barranquero <lekktu@gmail.com>
28
29 * w32proc.c (waitpid): Remove unused label get_result.
30
312012-11-17 Juanma Barranquero <lekktu@gmail.com>
32
33 * makefile.w32-in (SYSWAIT_H): New macro.
34 ($(BLD)/callproc.$(O), $(BLD)/w32proc.$(O), $(BLD)/process.$(O))
35 ($(BLD)/sysdep.$(O)): Update dependencies.
36
372012-11-17 Paul Eggert <eggert@cs.ucla.edu>
38
39 Assume POSIX 1003.1-1988 or later for fcntl.h (Bug#12881).
40 * callproc.c (relocate_fd): Assume F_DUPFD.
41 * emacs.c, term.c (O_RDWR): Remove.
42 * keyboard.c (tty_read_avail_input): Use O_NONBLOCK rather than
43 O_NDELAY, since O_NONBLOCK is the standard name for this flag.
44 * nsterm.m: Assume <fcntl.h> exists.
45 * process.c (NON_BLOCKING_CONNECT, allocate_pty, create_process)
46 (create_pty, Fmake_network_process, server_accept_connection)
47 (wait_reading_process_output, init_process_emacs):
48 Assume O_NONBLOCK.
49 (wait_reading_process_output): Put in a special case for WINDOWSNT
50 to mimick the older behavior where it had O_NDELAY but not O_NONBLOCK.
51 It's not clear this is needed, but it's a more-conservative change.
52 (create_process): Assume FD_CLOEXEC.
53 (create_process, create_pty): Assume O_NOCTTY.
54 * sysdep.c (init_sys_modes, reset_sys_modes): Assume F_SETFL.
55 (reset_sys_modes): Use O_NONBLOCK rather than O_NDELAY.
56 Omit if not DOS_NT, since F_GETFL is not defined there.
57 (serial_open): Assume O_NONBLOCK and O_NOCTTY.
58 * term.c: Include <fcntl.h>, for flags like O_NOCTTY.
59 (O_NOCTTY): Remove.
60 (init_tty): Assume O_IGNORE_CTTY is defined to 0 on platforms that
61 lack it, since gnulib guarantees this.
62 * w32.c (fcntl): Test for O_NONBLOCK rather than O_NDELAY.
63
642012-11-17 Eli Zaretskii <eliz@gnu.org>
65
66 * w32.c (faccessat): Pretend that directories have the execute bit
67 set. Emacs expects that, e.g., in files.el:cd-absolute.
68
69 * w32proc.c (create_child): Don't clip the PID of the child
70 process to fit into an Emacs integer, as this is no longer a
71 restriction.
72 (waitpid): Rename from sys_wait. Emulate a Posix 'waitpid' by
73 reaping only the process specified by PID argument, if that is
74 positive. Use PID instead of dead_child to know which process to
75 reap. Wait for the child to die only if WNOHANG is not in
76 OPTIONS.
77 (sys_select): Don't set dead_child.
78
79 * sysdep.c (wait_for_termination_1): Remove the WINDOWSNT portion,
80 as it is no longer needed.
81
82 * process.c (waitpid, WUNTRACED) [!WNOHANG]: Remove definitions,
83 no longer needed.
84 (record_child_status_change): Remove the setting of
85 record_at_most_one_child for the !WNOHANG case.
86
872012-11-17 Paul Eggert <eggert@cs.ucla.edu>
88
89 Fix problems in ns port found by static checking.
90 * nsterm.m: Include <pthread.h>, for pthread_mutex_lock etc.
91 (hold_event, setPosition:portion:whole:): Send SIGIO only to self,
92 not to process group.
93 (ns_select): Use emacs_write, not write, as that's more robust
94 in the presence of signals.
95 (fd_handler:): Check for read errors.
96
972012-11-16 Glenn Morris <rgm@gnu.org>
98
99 * editfns.c (Fmessage): Mention message-log-max. (Bug#12849)
100
1012012-11-16 Stefan Monnier <monnier@iro.umontreal.ca>
102
103 * eval.c (Finteractive_p): Revert lexbind-merge mishap.
104
1052012-11-16 Eli Zaretskii <eliz@gnu.org>
106
107 * w32proc.c (timer_loop): Make sure SuspendThread and ResumeThread
108 use the same value of thread handle.
109 (start_timer_thread): If the timer thread exited (due to error),
110 clean up by closing the two handles it used. Duplicate the caller
111 thread's handle here, so it gets duplicated only once, when
112 launching the timer thread. Set priority of the timer thread, not
113 the caller thread.
114 (getitimer): Don't duplicate the caller thread's handle here.
115 (Bug#12832)
116
1172012-11-16 Jan Djärv <jan.h.d@swipnet.se>
118
119 * nsterm.m (hold_event): Send SIGIO to make sure ns_read_socket is
120 called (Bug#12834).
121
1222012-11-16 Paul Eggert <eggert@cs.ucla.edu>
123
124 Remove no-longer-used pty_max_bytes variable.
125 * process.c (pty_max_bytes): Remove; unused.
126 (send_process): Do not set it.
127
1282012-11-15 Juanma Barranquero <lekktu@gmail.com>
129
130 * makefile.w32-in ($(BLD)/dispnew.$(O), $(BLD)/emacs.$(O)):
131 Update dependencies.
132
1332012-11-15 Paul Eggert <eggert@cs.ucla.edu>
134
135 * eval.c (mark_backtrace) [BYTE_MARK_STACK]: Remove stray '*'.
136 This follows up on the 2012-09-29 patch that removed indirection
137 for the 'function' field. Reported by Sergey Vinokurov in
138 <http://lists.gnu.org/archive/html/emacs-devel/2012-11/msg00263.html>.
139
1402012-11-14 Eli Zaretskii <eliz@gnu.org>
141
142 * w32.c (faccessat): Rename from sys_faccessat. (No need to use a
143 different name, as the MS runtime does not have such a function,
144 and probably never will.) All callers changed. Ignore DIRFD
145 value if PATH is an absolute file name, to match Posix spec
146 better. If AT_SYMLINK_NOFOLLOW is set in FLAGS, don't resolve
147 symlinks.
148
1492012-11-14 Dmitry Antipov <dmantipov@yandex.ru>
150
151 * xdisp.c (echo_area_display, redisplay_internal):
152 Omit redundant check whether frame_garbaged is set.
153
1542012-11-14 Paul Eggert <eggert@cs.ucla.edu>
155
156 Use faccessat, not access, when checking file permissions (Bug#12632).
157 This fixes a bug that has been present in Emacs since its creation.
158 It was reported by Chris Torek in 1983 even before GNU Emacs existed,
159 which must set some sort of record. (Torek's bug report was against
160 a predecessor of GNU Emacs, but GNU Emacs happened to have the
161 same common flaw.) See Torek's Usenet posting
162 "setuid/setgid programs & Emacs" Article-I.D.: sri-arpa.858
163 Posted: Fri Apr 8 14:18:56 1983.
164 * Makefile.in (LIB_EACCESS): New macro.
165 (LIBES): Use it.
166 * callproc.c (init_callproc):
167 * charset.c (init_charset):
168 * fileio.c (check_existing, check_executable, check_writable)
169 (Ffile_readable_p):
170 * lread.c (openp, load_path_check):
171 * process.c (allocate_pty):
172 * xrdb.c (file_p):
173 Use effective UID when checking permissions, not real UID.
174 * callproc.c (init_callproc):
175 * charset.c (init_charset):
176 * lread.c (load_path_check, init_lread):
177 Test whether directories are accessible, not merely whether they exist.
178 * conf_post.h (GNULIB_SUPPORT_ONLY_AT_FDCWD): New macro.
179 * fileio.c (check_existing, check_executable, check_writable)
180 (Ffile_readable_p):
181 Use symbolic names instead of integers for the flags, as they're
182 portable now.
183 (check_writable): New arg AMODE. All uses changed.
184 Set errno on failure.
185 (Ffile_readable_p): Use faccessat, not stat + open + close.
186 (Ffile_writable_p): No need to call check_existing + check_writable.
187 Just call check_writable and then look at errno. This saves a syscall.
188 dir should never be nil; replace an unnecessary runtime check
189 with an eassert. When checking the parent directory of a nonexistent
190 file, check that the directory is searchable as well as writable, as
191 we can't create files in unsearchable directories.
192 (file_directory_p): New function, which uses 'stat' on most platforms
193 but faccessat with D_OK (for efficiency) if WINDOWSNT.
194 (Ffile_directory_p, Fset_file_times): Use it.
195 (file_accessible_directory_p): New function, which uses a single
196 syscall for efficiency.
197 (Ffile_accessible_directory_p): Use it.
198 * xrdb.c (file_p): Use file_directory_p.
199 * lisp.h (file_directory_p, file_accessible_directory_p): New decls.
200 * lread.c (openp): When opening a file, use fstat rather than
201 stat, as that avoids a permissions race. When not opening a file,
202 use file_directory_p rather than stat.
203 (dir_warning): First arg is now a usage string, not a format.
204 Use errno. All uses changed.
205 * nsterm.m (ns_term_init): Remove unnecessary call to file-readable
206 that merely introduced a race.
207 * process.c, sysdep.c, term.c: All uses of '#ifdef O_NONBLOCK'
208 changed to '#if O_NONBLOCK', to accommodate gnulib O_* style,
209 and similarly for the other O_* flags.
210 * w32.c (sys_faccessat): Rename from sys_access and switch to
211 faccessat's API. All uses changed.
212 * xrdb.c: Do not include <sys/stat.h>; no longer needed.
213 (magic_db): Rename from magic_file_p.
214 (magic_db, search_magic_path): Return an XrmDatabase rather than a
215 char *, so that we don't have to test for file existence
216 separately from opening the file for reading. This removes a race
217 fixes a permission-checking problem, and simplifies the code.
218 All uses changed.
219 (file_p): Remove; no longer needed.
220
2212012-11-13 Dmitry Antipov <dmantipov@yandex.ru>
222
223 Omit glyphs initialization at startup.
224 * dispnew.c (glyphs_initialized_initially_p): Remove.
225 (adjust_frame_glyphs_initially): Likewise. Adjust users.
226 (Fredraw_frame): Move actual code from here...
227 (redraw_frame): ...to here. Add eassert. Adjust comment.
228 (Fredraw_display): Use redraw_frame.
229 * xdisp.c (clear_garbaged_frames): Likewise.
230
12012-11-13 Eli Zaretskii <eliz@gnu.org> 2312012-11-13 Eli Zaretskii <eliz@gnu.org>
2 232
3 * xdisp.c (decode_mode_spec): Limit the value of WIDTH argument 233 * xdisp.c (decode_mode_spec): Limit the value of WIDTH argument
diff --git a/src/Makefile.in b/src/Makefile.in
index 20e9366592d..88e1fc544d0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -150,6 +150,7 @@ M17N_FLT_CFLAGS = @M17N_FLT_CFLAGS@
150M17N_FLT_LIBS = @M17N_FLT_LIBS@ 150M17N_FLT_LIBS = @M17N_FLT_LIBS@
151 151
152LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@ 152LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@
153LIB_EACCESS=@LIB_EACCESS@
153LIB_TIMER_TIME=@LIB_TIMER_TIME@ 154LIB_TIMER_TIME=@LIB_TIMER_TIME@
154 155
155DBUS_CFLAGS = @DBUS_CFLAGS@ 156DBUS_CFLAGS = @DBUS_CFLAGS@
@@ -405,7 +406,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBX_BASE) $(LIBIMAGE) \
405 $(LIBX_OTHER) $(LIBSOUND) \ 406 $(LIBX_OTHER) $(LIBSOUND) \
406 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \ 407 $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_CLOCK_GETTIME) \
407 $(WEBKIT_LIBS) $(CLUTTER_LIBS) $(GIR_LIBS) \ 408 $(WEBKIT_LIBS) $(CLUTTER_LIBS) $(GIR_LIBS) \
408 $(LIB_TIMER_TIME) $(DBUS_LIBS) \ 409 $(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
409 $(LIB_EXECINFO) \ 410 $(LIB_EXECINFO) \
410 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ 411 $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \
411 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ 412 $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
diff --git a/src/callproc.c b/src/callproc.c
index c7bbe36e605..c9a504746b3 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1317,16 +1317,7 @@ relocate_fd (int fd, int minfd)
1317 return fd; 1317 return fd;
1318 else 1318 else
1319 { 1319 {
1320 int new; 1320 int new = fcntl (fd, F_DUPFD, minfd);
1321#ifdef F_DUPFD
1322 new = fcntl (fd, F_DUPFD, minfd);
1323#else
1324 new = dup (fd);
1325 if (new != -1)
1326 /* Note that we hold the original FD open while we recurse,
1327 to guarantee we'll get a new FD if we need it. */
1328 new = relocate_fd (new, minfd);
1329#endif
1330 if (new == -1) 1321 if (new == -1)
1331 { 1322 {
1332 const char *message_1 = "Error while setting up child: "; 1323 const char *message_1 = "Error while setting up child: ";
@@ -1576,15 +1567,13 @@ init_callproc (void)
1576#endif 1567#endif
1577 { 1568 {
1578 tempdir = Fdirectory_file_name (Vexec_directory); 1569 tempdir = Fdirectory_file_name (Vexec_directory);
1579 if (access (SSDATA (tempdir), 0) < 0) 1570 if (! file_accessible_directory_p (SSDATA (tempdir)))
1580 dir_warning ("Warning: arch-dependent data dir (%s) does not exist.\n", 1571 dir_warning ("arch-dependent data dir", Vexec_directory);
1581 Vexec_directory);
1582 } 1572 }
1583 1573
1584 tempdir = Fdirectory_file_name (Vdata_directory); 1574 tempdir = Fdirectory_file_name (Vdata_directory);
1585 if (access (SSDATA (tempdir), 0) < 0) 1575 if (! file_accessible_directory_p (SSDATA (tempdir)))
1586 dir_warning ("Warning: arch-independent data dir (%s) does not exist.\n", 1576 dir_warning ("arch-independent data dir", Vdata_directory);
1587 Vdata_directory);
1588 1577
1589 sh = (char *) getenv ("SHELL"); 1578 sh = (char *) getenv ("SHELL");
1590 Vshell_file_name = build_string (sh ? sh : "/bin/sh"); 1579 Vshell_file_name = build_string (sh ? sh : "/bin/sh");
@@ -1593,7 +1582,7 @@ init_callproc (void)
1593 Vshared_game_score_directory = Qnil; 1582 Vshared_game_score_directory = Qnil;
1594#else 1583#else
1595 Vshared_game_score_directory = build_string (PATH_GAME); 1584 Vshared_game_score_directory = build_string (PATH_GAME);
1596 if (NILP (Ffile_directory_p (Vshared_game_score_directory))) 1585 if (NILP (Ffile_accessible_directory_p (Vshared_game_score_directory)))
1597 Vshared_game_score_directory = Qnil; 1586 Vshared_game_score_directory = Qnil;
1598#endif 1587#endif
1599} 1588}
diff --git a/src/charset.c b/src/charset.c
index 6b999824dab..c9133c780e8 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2293,7 +2293,7 @@ init_charset (void)
2293{ 2293{
2294 Lisp_Object tempdir; 2294 Lisp_Object tempdir;
2295 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); 2295 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
2296 if (access (SSDATA (tempdir), 0) < 0) 2296 if (! file_accessible_directory_p (SSDATA (tempdir)))
2297 { 2297 {
2298 /* This used to be non-fatal (dir_warning), but it should not 2298 /* This used to be non-fatal (dir_warning), but it should not
2299 happen, and if it does sooner or later it will cause some 2299 happen, and if it does sooner or later it will cause some
diff --git a/src/conf_post.h b/src/conf_post.h
index 66390ddf103..b1997e79081 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -178,6 +178,10 @@ extern void _DebPrint (const char *fmt, ...);
178#endif 178#endif
179#endif 179#endif
180 180
181/* Tell gnulib to omit support for openat-related functions having a
182 first argument other than AT_FDCWD. */
183#define GNULIB_SUPPORT_ONLY_AT_FDCWD
184
181#include <string.h> 185#include <string.h>
182#include <stdlib.h> 186#include <stdlib.h>
183 187
diff --git a/src/dispnew.c b/src/dispnew.c
index 7a0901aafd6..5c162cdfadf 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -144,10 +144,6 @@ struct frame *last_nonminibuf_frame;
144 144
145static bool delayed_size_change; 145static bool delayed_size_change;
146 146
147/* 1 means glyph initialization has been completed at startup. */
148
149static bool glyphs_initialized_initially_p;
150
151/* Updated window if != 0. Set by update_window. */ 147/* Updated window if != 0. Set by update_window. */
152 148
153struct window *updated_window; 149struct window *updated_window;
@@ -1852,43 +1848,6 @@ adjust_glyphs (struct frame *f)
1852 unblock_input (); 1848 unblock_input ();
1853} 1849}
1854 1850
1855
1856/* Adjust frame glyphs when Emacs is initialized.
1857
1858 To be called from init_display.
1859
1860 We need a glyph matrix because redraw will happen soon.
1861 Unfortunately, window sizes on selected_frame are not yet set to
1862 meaningful values. I believe we can assume that there are only two
1863 windows on the frame---the mini-buffer and the root window. Frame
1864 height and width seem to be correct so far. So, set the sizes of
1865 windows to estimated values. */
1866
1867static void
1868adjust_frame_glyphs_initially (void)
1869{
1870 struct frame *sf = SELECTED_FRAME ();
1871 struct window *root = XWINDOW (sf->root_window);
1872 struct window *mini = XWINDOW (root->next);
1873 int frame_lines = FRAME_LINES (sf);
1874 int frame_cols = FRAME_COLS (sf);
1875 int top_margin = FRAME_TOP_MARGIN (sf);
1876
1877 /* Do it for the root window. */
1878 wset_top_line (root, make_number (top_margin));
1879 wset_total_lines (root, make_number (frame_lines - 1 - top_margin));
1880 wset_total_cols (root, make_number (frame_cols));
1881
1882 /* Do it for the mini-buffer window. */
1883 wset_top_line (mini, make_number (frame_lines - 1));
1884 wset_total_lines (mini, make_number (1));
1885 wset_total_cols (mini, make_number (frame_cols));
1886
1887 adjust_frame_glyphs (sf);
1888 glyphs_initialized_initially_p = 1;
1889}
1890
1891
1892/* Allocate/reallocate glyph matrices of a single frame F. */ 1851/* Allocate/reallocate glyph matrices of a single frame F. */
1893 1852
1894static void 1853static void
@@ -3073,19 +3032,13 @@ window_to_frame_hpos (struct window *w, int hpos)
3073 Redrawing Frames 3032 Redrawing Frames
3074 **********************************************************************/ 3033 **********************************************************************/
3075 3034
3076DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0, 3035/* Redraw frame F. */
3077 doc: /* Clear frame FRAME and output again what is supposed to appear on it.
3078If FRAME is omitted or nil, the selected frame is used. */)
3079 (Lisp_Object frame)
3080{
3081 struct frame *f = decode_live_frame (frame);
3082
3083 /* Ignore redraw requests, if frame has no glyphs yet.
3084 (Implementation note: It still has to be checked why we are
3085 called so early here). */
3086 if (!glyphs_initialized_initially_p)
3087 return Qnil;
3088 3036
3037void
3038redraw_frame (struct frame *f)
3039{
3040 /* Error if F has no glyphs. */
3041 eassert (f->glyphs_initialized_p);
3089 update_begin (f); 3042 update_begin (f);
3090#ifdef MSDOS 3043#ifdef MSDOS
3091 if (FRAME_MSDOS_P (f)) 3044 if (FRAME_MSDOS_P (f))
@@ -3102,22 +3055,17 @@ If FRAME is omitted or nil, the selected frame is used. */)
3102 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0); 3055 mark_window_display_accurate (FRAME_ROOT_WINDOW (f), 0);
3103 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1); 3056 set_window_update_flags (XWINDOW (FRAME_ROOT_WINDOW (f)), 1);
3104 f->garbaged = 0; 3057 f->garbaged = 0;
3105 return Qnil;
3106} 3058}
3107 3059
3108 3060DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 0, 1, 0,
3109/* Redraw frame F. This is nothing more than a call to the Lisp 3061 doc: /* Clear frame FRAME and output again what is supposed to appear on it.
3110 function redraw-frame. */ 3062If FRAME is omitted or nil, the selected frame is used. */)
3111 3063 (Lisp_Object frame)
3112void
3113redraw_frame (struct frame *f)
3114{ 3064{
3115 Lisp_Object frame; 3065 redraw_frame (decode_live_frame (frame));
3116 XSETFRAME (frame, f); 3066 return Qnil;
3117 Fredraw_frame (frame);
3118} 3067}
3119 3068
3120
3121DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "", 3069DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3122 doc: /* Clear and redisplay all visible frames. */) 3070 doc: /* Clear and redisplay all visible frames. */)
3123 (void) 3071 (void)
@@ -3126,7 +3074,7 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3126 3074
3127 FOR_EACH_FRAME (tail, frame) 3075 FOR_EACH_FRAME (tail, frame)
3128 if (FRAME_VISIBLE_P (XFRAME (frame))) 3076 if (FRAME_VISIBLE_P (XFRAME (frame)))
3129 Fredraw_frame (frame); 3077 redraw_frame (XFRAME (frame));
3130 3078
3131 return Qnil; 3079 return Qnil;
3132} 3080}
@@ -6219,7 +6167,6 @@ init_display (void)
6219 So call tgetent. */ 6167 So call tgetent. */
6220 { char b[2044]; tgetent (b, "xterm");} 6168 { char b[2044]; tgetent (b, "xterm");}
6221#endif 6169#endif
6222 adjust_frame_glyphs_initially ();
6223 return; 6170 return;
6224 } 6171 }
6225#endif /* HAVE_X_WINDOWS */ 6172#endif /* HAVE_X_WINDOWS */
@@ -6229,7 +6176,6 @@ init_display (void)
6229 { 6176 {
6230 Vinitial_window_system = Qw32; 6177 Vinitial_window_system = Qw32;
6231 Vwindow_system_version = make_number (1); 6178 Vwindow_system_version = make_number (1);
6232 adjust_frame_glyphs_initially ();
6233 return; 6179 return;
6234 } 6180 }
6235#endif /* HAVE_NTGUI */ 6181#endif /* HAVE_NTGUI */
@@ -6243,7 +6189,6 @@ init_display (void)
6243 { 6189 {
6244 Vinitial_window_system = Qns; 6190 Vinitial_window_system = Qns;
6245 Vwindow_system_version = make_number (10); 6191 Vwindow_system_version = make_number (10);
6246 adjust_frame_glyphs_initially ();
6247 return; 6192 return;
6248 } 6193 }
6249#endif 6194#endif
@@ -6333,7 +6278,6 @@ init_display (void)
6333 fatal ("screen size %dx%d too big", width, height); 6278 fatal ("screen size %dx%d too big", width, height);
6334 } 6279 }
6335 6280
6336 adjust_frame_glyphs_initially ();
6337 calculate_costs (XFRAME (selected_frame)); 6281 calculate_costs (XFRAME (selected_frame));
6338 6282
6339 /* Set up faces of the initial terminal frame of a dumped Emacs. */ 6283 /* Set up faces of the initial terminal frame of a dumped Emacs. */
diff --git a/src/editfns.c b/src/editfns.c
index c5d4ed295ab..8122ffdd0d4 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3434,8 +3434,8 @@ static ptrdiff_t message_length;
3434 3434
3435DEFUN ("message", Fmessage, Smessage, 1, MANY, 0, 3435DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
3436 doc: /* Display a message at the bottom of the screen. 3436 doc: /* Display a message at the bottom of the screen.
3437The message also goes into the `*Messages*' buffer. 3437The message also goes into the `*Messages*' buffer, if `message-log-max'
3438\(In keyboard macros, that's all it does.) 3438is non-nil. (In keyboard macros, that's all it does.)
3439Return the message. 3439Return the message.
3440 3440
3441The first argument is a format control string, and the rest are data 3441The first argument is a format control string, and the rest are data
diff --git a/src/emacs.c b/src/emacs.c
index aece6069230..079304b6c8e 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -98,10 +98,6 @@ extern void moncontrol (int mode);
98#include <sys/personality.h> 98#include <sys/personality.h>
99#endif 99#endif
100 100
101#ifndef O_RDWR
102#define O_RDWR 2
103#endif
104
105static const char emacs_version[] = VERSION; 101static const char emacs_version[] = VERSION;
106static const char emacs_copyright[] = COPYRIGHT; 102static const char emacs_copyright[] = COPYRIGHT;
107 103
diff --git a/src/eval.c b/src/eval.c
index dcd48cb7250..f8a76646352 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -508,7 +508,7 @@ spec that specifies non-nil unconditionally (such as \"p\"); or (ii)
508use `called-interactively-p'. */) 508use `called-interactively-p'. */)
509 (void) 509 (void)
510{ 510{
511 return interactive_p () ? Qt : Qnil; 511 return (INTERACTIVE && interactive_p ()) ? Qt : Qnil;
512} 512}
513 513
514 514
@@ -3369,7 +3369,7 @@ mark_backtrace (void)
3369 3369
3370 for (backlist = backtrace_list; backlist; backlist = backlist->next) 3370 for (backlist = backtrace_list; backlist; backlist = backlist->next)
3371 { 3371 {
3372 mark_object (*backlist->function); 3372 mark_object (backlist->function);
3373 3373
3374 if (backlist->nargs == UNEVALLED 3374 if (backlist->nargs == UNEVALLED
3375 || backlist->nargs == MANY) /* FIXME: Can this happen? */ 3375 || backlist->nargs == MANY) /* FIXME: Can this happen? */
diff --git a/src/fileio.c b/src/fileio.c
index b9541e78838..572f6d8ef83 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2425,15 +2425,7 @@ On Unix, this is a name starting with a `/' or a `~'. */)
2425bool 2425bool
2426check_existing (const char *filename) 2426check_existing (const char *filename)
2427{ 2427{
2428#ifdef DOS_NT 2428 return faccessat (AT_FDCWD, filename, F_OK, AT_EACCESS) == 0;
2429 /* The full emulation of Posix 'stat' is too expensive on
2430 DOS/Windows, when all we want to know is whether the file exists.
2431 So we use 'access' instead, which is much more lightweight. */
2432 return (access (filename, F_OK) >= 0);
2433#else
2434 struct stat st;
2435 return (stat (filename, &st) >= 0);
2436#endif
2437} 2429}
2438 2430
2439/* Return true if file FILENAME exists and can be executed. */ 2431/* Return true if file FILENAME exists and can be executed. */
@@ -2441,56 +2433,40 @@ check_existing (const char *filename)
2441static bool 2433static bool
2442check_executable (char *filename) 2434check_executable (char *filename)
2443{ 2435{
2444#ifdef DOS_NT 2436 return faccessat (AT_FDCWD, filename, X_OK, AT_EACCESS) == 0;
2445 struct stat st;
2446 if (stat (filename, &st) < 0)
2447 return 0;
2448 return ((st.st_mode & S_IEXEC) != 0);
2449#else /* not DOS_NT */
2450#ifdef HAVE_EUIDACCESS
2451 return (euidaccess (filename, 1) >= 0);
2452#else
2453 /* Access isn't quite right because it uses the real uid
2454 and we really want to test with the effective uid.
2455 But Unix doesn't give us a right way to do it. */
2456 return (access (filename, 1) >= 0);
2457#endif
2458#endif /* not DOS_NT */
2459} 2437}
2460 2438
2461/* Return true if file FILENAME exists and can be written. */ 2439/* Return true if file FILENAME exists and can be accessed
2440 according to AMODE, which should include W_OK.
2441 On failure, return false and set errno. */
2462 2442
2463static bool 2443static bool
2464check_writable (const char *filename) 2444check_writable (const char *filename, int amode)
2465{ 2445{
2466#ifdef MSDOS 2446#ifdef MSDOS
2447 /* FIXME: an faccessat implementation should be added to the
2448 DOS/Windows ports and this #ifdef branch should be removed. */
2467 struct stat st; 2449 struct stat st;
2468 if (stat (filename, &st) < 0) 2450 if (stat (filename, &st) < 0)
2469 return 0; 2451 return 0;
2452 errno = EPERM;
2470 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode)); 2453 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode));
2471#else /* not MSDOS */ 2454#else /* not MSDOS */
2472#ifdef HAVE_EUIDACCESS 2455 bool res = faccessat (AT_FDCWD, filename, amode, AT_EACCESS) == 0;
2473 bool res = (euidaccess (filename, 2) >= 0);
2474#ifdef CYGWIN 2456#ifdef CYGWIN
2475 /* euidaccess may have returned failure because Cygwin couldn't 2457 /* faccessat may have returned failure because Cygwin couldn't
2476 determine the file's UID or GID; if so, we return success. */ 2458 determine the file's UID or GID; if so, we return success. */
2477 if (!res) 2459 if (!res)
2478 { 2460 {
2461 int faccessat_errno = errno;
2479 struct stat st; 2462 struct stat st;
2480 if (stat (filename, &st) < 0) 2463 if (stat (filename, &st) < 0)
2481 return 0; 2464 return 0;
2482 res = (st.st_uid == -1 || st.st_gid == -1); 2465 res = (st.st_uid == -1 || st.st_gid == -1);
2466 errno = faccessat_errno;
2483 } 2467 }
2484#endif /* CYGWIN */ 2468#endif /* CYGWIN */
2485 return res; 2469 return res;
2486#else /* not HAVE_EUIDACCESS */
2487 /* Access isn't quite right because it uses the real uid
2488 and we really want to test with the effective uid.
2489 But Unix doesn't give us a right way to do it.
2490 Opening with O_WRONLY could work for an ordinary file,
2491 but would lose for directories. */
2492 return (access (filename, 2) >= 0);
2493#endif /* not HAVE_EUIDACCESS */
2494#endif /* not MSDOS */ 2470#endif /* not MSDOS */
2495} 2471}
2496 2472
@@ -2547,9 +2523,6 @@ See also `file-exists-p' and `file-attributes'. */)
2547{ 2523{
2548 Lisp_Object absname; 2524 Lisp_Object absname;
2549 Lisp_Object handler; 2525 Lisp_Object handler;
2550 int desc;
2551 int flags;
2552 struct stat statbuf;
2553 2526
2554 CHECK_STRING (filename); 2527 CHECK_STRING (filename);
2555 absname = Fexpand_file_name (filename, Qnil); 2528 absname = Fexpand_file_name (filename, Qnil);
@@ -2561,35 +2534,10 @@ See also `file-exists-p' and `file-attributes'. */)
2561 return call2 (handler, Qfile_readable_p, absname); 2534 return call2 (handler, Qfile_readable_p, absname);
2562 2535
2563 absname = ENCODE_FILE (absname); 2536 absname = ENCODE_FILE (absname);
2564 2537 return (faccessat (AT_FDCWD, SSDATA (absname), R_OK, AT_EACCESS) == 0
2565#if defined (DOS_NT) || defined (macintosh) 2538 ? Qt : Qnil);
2566 /* Under MS-DOS, Windows, and Macintosh, open does not work for
2567 directories. */
2568 if (access (SDATA (absname), 0) == 0)
2569 return Qt;
2570 return Qnil;
2571#else /* not DOS_NT and not macintosh */
2572 flags = O_RDONLY;
2573#ifdef O_NONBLOCK
2574 /* Opening a fifo without O_NONBLOCK can wait.
2575 We don't want to wait. But we don't want to mess wth O_NONBLOCK
2576 except in the case of a fifo, on a system which handles it. */
2577 desc = stat (SSDATA (absname), &statbuf);
2578 if (desc < 0)
2579 return Qnil;
2580 if (S_ISFIFO (statbuf.st_mode))
2581 flags |= O_NONBLOCK;
2582#endif
2583 desc = emacs_open (SSDATA (absname), flags, 0);
2584 if (desc < 0)
2585 return Qnil;
2586 emacs_close (desc);
2587 return Qt;
2588#endif /* not DOS_NT and not macintosh */
2589} 2539}
2590 2540
2591/* Having this before file-symlink-p mysteriously caused it to be forgotten
2592 on the RT/PC. */
2593DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, 2541DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2594 doc: /* Return t if file FILENAME can be written or created by you. */) 2542 doc: /* Return t if file FILENAME can be written or created by you. */)
2595 (Lisp_Object filename) 2543 (Lisp_Object filename)
@@ -2607,14 +2555,15 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2607 return call2 (handler, Qfile_writable_p, absname); 2555 return call2 (handler, Qfile_writable_p, absname);
2608 2556
2609 encoded = ENCODE_FILE (absname); 2557 encoded = ENCODE_FILE (absname);
2610 if (check_existing (SSDATA (encoded))) 2558 if (check_writable (SSDATA (encoded), W_OK))
2611 return (check_writable (SSDATA (encoded)) 2559 return Qt;
2612 ? Qt : Qnil); 2560 if (errno != ENOENT)
2561 return Qnil;
2613 2562
2614 dir = Ffile_name_directory (absname); 2563 dir = Ffile_name_directory (absname);
2564 eassert (!NILP (dir));
2615#ifdef MSDOS 2565#ifdef MSDOS
2616 if (!NILP (dir)) 2566 dir = Fdirectory_file_name (dir);
2617 dir = Fdirectory_file_name (dir);
2618#endif /* MSDOS */ 2567#endif /* MSDOS */
2619 2568
2620 dir = ENCODE_FILE (dir); 2569 dir = ENCODE_FILE (dir);
@@ -2622,10 +2571,9 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0,
2622 /* The read-only attribute of the parent directory doesn't affect 2571 /* The read-only attribute of the parent directory doesn't affect
2623 whether a file or directory can be created within it. Some day we 2572 whether a file or directory can be created within it. Some day we
2624 should check ACLs though, which do affect this. */ 2573 should check ACLs though, which do affect this. */
2625 return (access (SDATA (dir), D_OK) < 0) ? Qnil : Qt; 2574 return file_directory_p (SDATA (dir)) ? Qt : Qnil;
2626#else 2575#else
2627 return (check_writable (!NILP (dir) ? SSDATA (dir) : "") 2576 return check_writable (SSDATA (dir), W_OK | X_OK) ? Qt : Qnil;
2628 ? Qt : Qnil);
2629#endif 2577#endif
2630} 2578}
2631 2579
@@ -2703,8 +2651,7 @@ Symbolic links to directories count as directories.
2703See `file-symlink-p' to distinguish symlinks. */) 2651See `file-symlink-p' to distinguish symlinks. */)
2704 (Lisp_Object filename) 2652 (Lisp_Object filename)
2705{ 2653{
2706 register Lisp_Object absname; 2654 Lisp_Object absname;
2707 struct stat st;
2708 Lisp_Object handler; 2655 Lisp_Object handler;
2709 2656
2710 absname = expand_and_dir_to_file (filename, BVAR (current_buffer, directory)); 2657 absname = expand_and_dir_to_file (filename, BVAR (current_buffer, directory));
@@ -2717,9 +2664,20 @@ See `file-symlink-p' to distinguish symlinks. */)
2717 2664
2718 absname = ENCODE_FILE (absname); 2665 absname = ENCODE_FILE (absname);
2719 2666
2720 if (stat (SSDATA (absname), &st) < 0) 2667 return file_directory_p (SSDATA (absname)) ? Qt : Qnil;
2721 return Qnil; 2668}
2722 return S_ISDIR (st.st_mode) ? Qt : Qnil; 2669
2670/* Return true if FILE is a directory or a symlink to a directory. */
2671bool
2672file_directory_p (char const *file)
2673{
2674#ifdef WINDOWSNT
2675 /* This is cheaper than 'stat'. */
2676 return faccessat (AT_FDCWD, file, D_OK, AT_EACCESS) == 0;
2677#else
2678 struct stat st;
2679 return stat (file, &st) == 0 && S_ISDIR (st.st_mode);
2680#endif
2723} 2681}
2724 2682
2725DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p, 2683DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p,
@@ -2733,21 +2691,65 @@ if the directory so specified exists and really is a readable and
2733searchable directory. */) 2691searchable directory. */)
2734 (Lisp_Object filename) 2692 (Lisp_Object filename)
2735{ 2693{
2694 Lisp_Object absname;
2736 Lisp_Object handler; 2695 Lisp_Object handler;
2737 bool tem; 2696
2738 struct gcpro gcpro1; 2697 CHECK_STRING (filename);
2698 absname = Fexpand_file_name (filename, Qnil);
2739 2699
2740 /* If the file name has special constructs in it, 2700 /* If the file name has special constructs in it,
2741 call the corresponding file handler. */ 2701 call the corresponding file handler. */
2742 handler = Ffind_file_name_handler (filename, Qfile_accessible_directory_p); 2702 handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p);
2743 if (!NILP (handler)) 2703 if (!NILP (handler))
2744 return call2 (handler, Qfile_accessible_directory_p, filename); 2704 return call2 (handler, Qfile_accessible_directory_p, absname);
2745 2705
2746 GCPRO1 (filename); 2706 absname = ENCODE_FILE (absname);
2747 tem = (NILP (Ffile_directory_p (filename)) 2707 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil;
2748 || NILP (Ffile_executable_p (filename))); 2708}
2749 UNGCPRO; 2709
2750 return tem ? Qnil : Qt; 2710/* If FILE is a searchable directory or a symlink to a
2711 searchable directory, return true. Otherwise return
2712 false and set errno to an error number. */
2713bool
2714file_accessible_directory_p (char const *file)
2715{
2716#ifdef DOS_NT
2717 /* There's no need to test whether FILE is searchable, as the
2718 searchable/executable bit is invented on DOS_NT platforms. */
2719 return file_directory_p (file);
2720#else
2721 /* On POSIXish platforms, use just one system call; this avoids a
2722 race and is typically faster. */
2723 ptrdiff_t len = strlen (file);
2724 char const *dir;
2725 bool ok;
2726 int saved_errno;
2727 USE_SAFE_ALLOCA;
2728
2729 /* Normally a file "FOO" is an accessible directory if "FOO/." exists.
2730 There are three exceptions: "", "/", and "//". Leave "" alone,
2731 as it's invalid. Append only "." to the other two exceptions as
2732 "/" and "//" are distinct on some platforms, whereas "/", "///",
2733 "////", etc. are all equivalent. */
2734 if (! len)
2735 dir = file;
2736 else
2737 {
2738 /* Just check for trailing '/' when deciding whether to append '/'.
2739 That's simpler than testing the two special cases "/" and "//",
2740 and it's a safe optimization here. */
2741 char *buf = SAFE_ALLOCA (len + 3);
2742 memcpy (buf, file, len);
2743 strcpy (buf + len, "/." + (file[len - 1] == '/'));
2744 dir = buf;
2745 }
2746
2747 ok = check_existing (dir);
2748 saved_errno = errno;
2749 SAFE_FREE ();
2750 errno = saved_errno;
2751 return ok;
2752#endif
2751} 2753}
2752 2754
2753DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0, 2755DEFUN ("file-regular-p", Ffile_regular_p, Sfile_regular_p, 1, 1, 0,
@@ -3044,10 +3046,8 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
3044 if (set_file_times (-1, SSDATA (encoded_absname), t, t)) 3046 if (set_file_times (-1, SSDATA (encoded_absname), t, t))
3045 { 3047 {
3046#ifdef MSDOS 3048#ifdef MSDOS
3047 struct stat st;
3048
3049 /* Setting times on a directory always fails. */ 3049 /* Setting times on a directory always fails. */
3050 if (stat (SSDATA (encoded_absname), &st) == 0 && S_ISDIR (st.st_mode)) 3050 if (file_directory_p (SSDATA (encoded_absname)))
3051 return Qnil; 3051 return Qnil;
3052#endif 3052#endif
3053 report_file_error ("Setting file times", Fcons (absname, Qnil)); 3053 report_file_error ("Setting file times", Fcons (absname, Qnil));
diff --git a/src/keyboard.c b/src/keyboard.c
index 42c26982086..bf441efef90 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6964,7 +6964,7 @@ tty_read_avail_input (struct terminal *terminal,
6964#elif defined USG || defined CYGWIN 6964#elif defined USG || defined CYGWIN
6965 /* Read some input if available, but don't wait. */ 6965 /* Read some input if available, but don't wait. */
6966 n_to_read = sizeof cbuf; 6966 n_to_read = sizeof cbuf;
6967 fcntl (fileno (tty->input), F_SETFL, O_NDELAY); 6967 fcntl (fileno (tty->input), F_SETFL, O_NONBLOCK);
6968#else 6968#else
6969# error "Cannot read without possibly delaying" 6969# error "Cannot read without possibly delaying"
6970#endif 6970#endif
@@ -6998,7 +6998,7 @@ tty_read_avail_input (struct terminal *terminal,
6998 } 6998 }
6999 while ( 6999 while (
7000 /* We used to retry the read if it was interrupted. 7000 /* We used to retry the read if it was interrupted.
7001 But this does the wrong thing when O_NDELAY causes 7001 But this does the wrong thing when O_NONBLOCK causes
7002 an EAGAIN error. Does anybody know of a situation 7002 an EAGAIN error. Does anybody know of a situation
7003 where a retry is actually needed? */ 7003 where a retry is actually needed? */
7004#if 0 7004#if 0
diff --git a/src/lisp.h b/src/lisp.h
index b56e499ce29..4941f649e79 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3207,6 +3207,8 @@ extern Lisp_Object close_file_unwind (Lisp_Object);
3207extern Lisp_Object restore_point_unwind (Lisp_Object); 3207extern Lisp_Object restore_point_unwind (Lisp_Object);
3208extern _Noreturn void report_file_error (const char *, Lisp_Object); 3208extern _Noreturn void report_file_error (const char *, Lisp_Object);
3209extern void internal_delete_file (Lisp_Object); 3209extern void internal_delete_file (Lisp_Object);
3210extern bool file_directory_p (const char *);
3211extern bool file_accessible_directory_p (const char *);
3210extern void syms_of_fileio (void); 3212extern void syms_of_fileio (void);
3211extern Lisp_Object make_temp_name (Lisp_Object, bool); 3213extern Lisp_Object make_temp_name (Lisp_Object, bool);
3212extern Lisp_Object Qdelete_file; 3214extern Lisp_Object Qdelete_file;
diff --git a/src/lread.c b/src/lread.c
index 3a82e0057e2..5859a2f85a9 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1403,7 +1403,7 @@ Returns the file's name in absolute form, or nil if not found.
1403If SUFFIXES is non-nil, it should be a list of suffixes to append to 1403If SUFFIXES is non-nil, it should be a list of suffixes to append to
1404file name when searching. 1404file name when searching.
1405If non-nil, PREDICATE is used instead of `file-readable-p'. 1405If non-nil, PREDICATE is used instead of `file-readable-p'.
1406PREDICATE can also be an integer to pass to the access(2) function, 1406PREDICATE can also be an integer to pass to the faccessat(2) function,
1407in which case file-name-handlers are ignored. 1407in which case file-name-handlers are ignored.
1408This function will normally skip directories, so if you want it to find 1408This function will normally skip directories, so if you want it to find
1409directories, make sure the PREDICATE function returns `dir-ok' for them. */) 1409directories, make sure the PREDICATE function returns `dir-ok' for them. */)
@@ -1441,7 +1441,6 @@ static Lisp_Object Qdir_ok;
1441int 1441int
1442openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) 1442openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate)
1443{ 1443{
1444 int fd;
1445 ptrdiff_t fn_size = 100; 1444 ptrdiff_t fn_size = 100;
1446 char buf[100]; 1445 char buf[100];
1447 char *fn = buf; 1446 char *fn = buf;
@@ -1496,7 +1495,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1496 { 1495 {
1497 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); 1496 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
1498 Lisp_Object handler; 1497 Lisp_Object handler;
1499 bool exists;
1500 1498
1501 /* Concatenate path element/specified name with the suffix. 1499 /* Concatenate path element/specified name with the suffix.
1502 If the directory starts with /:, remove that. */ 1500 If the directory starts with /:, remove that. */
@@ -1520,6 +1518,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1520 handler = Ffind_file_name_handler (string, Qfile_exists_p); 1518 handler = Ffind_file_name_handler (string, Qfile_exists_p);
1521 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1519 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1522 { 1520 {
1521 bool exists;
1523 if (NILP (predicate)) 1522 if (NILP (predicate))
1524 exists = !NILP (Ffile_readable_p (string)); 1523 exists = !NILP (Ffile_readable_p (string));
1525 else 1524 else
@@ -1541,37 +1540,40 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1541 } 1540 }
1542 else 1541 else
1543 { 1542 {
1544#ifndef WINDOWSNT 1543 int fd;
1545 struct stat st;
1546#endif
1547 const char *pfn; 1544 const char *pfn;
1548 1545
1549 encoded_fn = ENCODE_FILE (string); 1546 encoded_fn = ENCODE_FILE (string);
1550 pfn = SSDATA (encoded_fn); 1547 pfn = SSDATA (encoded_fn);
1551#ifdef WINDOWSNT
1552 exists = access (pfn, F_OK) == 0 && access (pfn, D_OK) < 0;
1553#else
1554 exists = (stat (pfn, &st) == 0 && ! S_ISDIR (st.st_mode));
1555#endif
1556 if (exists)
1557 {
1558 /* Check that we can access or open it. */
1559 if (NATNUMP (predicate))
1560 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
1561 && access (pfn, XFASTINT (predicate)) == 0)
1562 ? 1 : -1);
1563 else
1564 fd = emacs_open (pfn, O_RDONLY, 0);
1565 1548
1566 if (fd >= 0) 1549 /* Check that we can access or open it. */
1550 if (NATNUMP (predicate))
1551 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
1552 && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
1553 AT_EACCESS)
1554 == 0)
1555 && ! file_directory_p (pfn))
1556 ? 1 : -1);
1557 else
1558 {
1559 struct stat st;
1560 fd = emacs_open (pfn, O_RDONLY, 0);
1561 if (0 <= fd
1562 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode)))
1567 { 1563 {
1568 /* We succeeded; return this descriptor and filename. */ 1564 emacs_close (fd);
1569 if (storeptr) 1565 fd = -1;
1570 *storeptr = string;
1571 UNGCPRO;
1572 return fd;
1573 } 1566 }
1574 } 1567 }
1568
1569 if (fd >= 0)
1570 {
1571 /* We succeeded; return this descriptor and filename. */
1572 if (storeptr)
1573 *storeptr = string;
1574 UNGCPRO;
1575 return fd;
1576 }
1575 } 1577 }
1576 } 1578 }
1577 if (absolute) 1579 if (absolute)
@@ -4087,9 +4089,8 @@ load_path_check (void)
4087 if (STRINGP (dirfile)) 4089 if (STRINGP (dirfile))
4088 { 4090 {
4089 dirfile = Fdirectory_file_name (dirfile); 4091 dirfile = Fdirectory_file_name (dirfile);
4090 if (access (SSDATA (dirfile), 0) < 0) 4092 if (! file_accessible_directory_p (SSDATA (dirfile)))
4091 dir_warning ("Warning: Lisp directory `%s' does not exist.\n", 4093 dir_warning ("Lisp directory", XCAR (path_tail));
4092 XCAR (path_tail));
4093 } 4094 }
4094 } 4095 }
4095} 4096}
@@ -4201,11 +4202,11 @@ init_lread (void)
4201 Lisp_Object tem, tem1; 4202 Lisp_Object tem, tem1;
4202 4203
4203 /* Add to the path the lisp subdir of the installation 4204 /* Add to the path the lisp subdir of the installation
4204 dir, if it exists. Note: in out-of-tree builds, 4205 dir, if it is accessible. Note: in out-of-tree builds,
4205 this directory is empty save for Makefile. */ 4206 this directory is empty save for Makefile. */
4206 tem = Fexpand_file_name (build_string ("lisp"), 4207 tem = Fexpand_file_name (build_string ("lisp"),
4207 Vinstallation_directory); 4208 Vinstallation_directory);
4208 tem1 = Ffile_exists_p (tem); 4209 tem1 = Ffile_accessible_directory_p (tem);
4209 if (!NILP (tem1)) 4210 if (!NILP (tem1))
4210 { 4211 {
4211 if (NILP (Fmember (tem, Vload_path))) 4212 if (NILP (Fmember (tem, Vload_path)))
@@ -4222,10 +4223,10 @@ init_lread (void)
4222 Lisp dirs instead. */ 4223 Lisp dirs instead. */
4223 Vload_path = nconc2 (Vload_path, dump_path); 4224 Vload_path = nconc2 (Vload_path, dump_path);
4224 4225
4225 /* Add leim under the installation dir, if it exists. */ 4226 /* Add leim under the installation dir, if it is accessible. */
4226 tem = Fexpand_file_name (build_string ("leim"), 4227 tem = Fexpand_file_name (build_string ("leim"),
4227 Vinstallation_directory); 4228 Vinstallation_directory);
4228 tem1 = Ffile_exists_p (tem); 4229 tem1 = Ffile_accessible_directory_p (tem);
4229 if (!NILP (tem1)) 4230 if (!NILP (tem1))
4230 { 4231 {
4231 if (NILP (Fmember (tem, Vload_path))) 4232 if (NILP (Fmember (tem, Vload_path)))
@@ -4237,7 +4238,7 @@ init_lread (void)
4237 { 4238 {
4238 tem = Fexpand_file_name (build_string ("site-lisp"), 4239 tem = Fexpand_file_name (build_string ("site-lisp"),
4239 Vinstallation_directory); 4240 Vinstallation_directory);
4240 tem1 = Ffile_exists_p (tem); 4241 tem1 = Ffile_accessible_directory_p (tem);
4241 if (!NILP (tem1)) 4242 if (!NILP (tem1))
4242 { 4243 {
4243 if (NILP (Fmember (tem, Vload_path))) 4244 if (NILP (Fmember (tem, Vload_path)))
@@ -4282,7 +4283,7 @@ init_lread (void)
4282 { 4283 {
4283 tem = Fexpand_file_name (build_string ("site-lisp"), 4284 tem = Fexpand_file_name (build_string ("site-lisp"),
4284 Vsource_directory); 4285 Vsource_directory);
4285 tem1 = Ffile_exists_p (tem); 4286 tem1 = Ffile_accessible_directory_p (tem);
4286 if (!NILP (tem1)) 4287 if (!NILP (tem1))
4287 { 4288 {
4288 if (NILP (Fmember (tem, Vload_path))) 4289 if (NILP (Fmember (tem, Vload_path)))
@@ -4338,21 +4339,28 @@ init_lread (void)
4338 Vloads_in_progress = Qnil; 4339 Vloads_in_progress = Qnil;
4339} 4340}
4340 4341
4341/* Print a warning, using format string FORMAT, that directory DIRNAME 4342/* Print a warning that directory intended for use USE and with name
4342 does not exist. Print it on stderr and put it in *Messages*. */ 4343 DIRNAME cannot be accessed. On entry, errno should correspond to
4344 the access failure. Print the warning on stderr and put it in
4345 *Messages*. */
4343 4346
4344void 4347void
4345dir_warning (const char *format, Lisp_Object dirname) 4348dir_warning (char const *use, Lisp_Object dirname)
4346{ 4349{
4347 fprintf (stderr, format, SDATA (dirname)); 4350 static char const format[] = "Warning: %s `%s': %s\n";
4351 int access_errno = errno;
4352 fprintf (stderr, format, use, SSDATA (dirname), strerror (access_errno));
4348 4353
4349 /* Don't log the warning before we've initialized!! */ 4354 /* Don't log the warning before we've initialized!! */
4350 if (initialized) 4355 if (initialized)
4351 { 4356 {
4357 char const *diagnostic = emacs_strerror (access_errno);
4352 USE_SAFE_ALLOCA; 4358 USE_SAFE_ALLOCA;
4353 char *buffer = SAFE_ALLOCA (SBYTES (dirname) 4359 char *buffer = SAFE_ALLOCA (sizeof format - 3 * (sizeof "%s" - 1)
4354 + strlen (format) - (sizeof "%s" - 1) + 1); 4360 + strlen (use) + SBYTES (dirname)
4355 ptrdiff_t message_len = esprintf (buffer, format, SDATA (dirname)); 4361 + strlen (diagnostic));
4362 ptrdiff_t message_len = esprintf (buffer, format, use, SSDATA (dirname),
4363 diagnostic);
4356 message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname)); 4364 message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname));
4357 SAFE_FREE (); 4365 SAFE_FREE ();
4358 } 4366 }
diff --git a/src/makefile.w32-in b/src/makefile.w32-in
index f5cab34d7dc..9778e955677 100644
--- a/src/makefile.w32-in
+++ b/src/makefile.w32-in
@@ -472,6 +472,8 @@ SYSSIGNAL_H = $(SRC)/syssignal.h \
472SYSTTY_H = $(SRC)/systty.h \ 472SYSTTY_H = $(SRC)/systty.h \
473 $(NT_INC)/sys/ioctl.h \ 473 $(NT_INC)/sys/ioctl.h \
474 $(NT_INC)/unistd.h 474 $(NT_INC)/unistd.h
475SYSWAIT_H = $(SRC)/syswait.h \
476 $(NT_INC)/sys/wait.h
475TERMHOOKS_H = $(SRC)/termhooks.h \ 477TERMHOOKS_H = $(SRC)/termhooks.h \
476 $(SYSTIME_H) 478 $(SYSTIME_H)
477W32FONT_H = $(SRC)/w32font.h \ 479W32FONT_H = $(SRC)/w32font.h \
@@ -566,7 +568,6 @@ $(BLD)/callproc.$(O) : \
566 $(SRC)/commands.h \ 568 $(SRC)/commands.h \
567 $(SRC)/composite.h \ 569 $(SRC)/composite.h \
568 $(SRC)/epaths.h \ 570 $(SRC)/epaths.h \
569 $(SRC)/syswait.h \
570 $(SRC)/w32.h \ 571 $(SRC)/w32.h \
571 $(NT_INC)/sys/file.h \ 572 $(NT_INC)/sys/file.h \
572 $(NT_INC)/unistd.h \ 573 $(NT_INC)/unistd.h \
@@ -580,6 +581,7 @@ $(BLD)/callproc.$(O) : \
580 $(PROCESS_H) \ 581 $(PROCESS_H) \
581 $(SYSSIGNAL_H) \ 582 $(SYSSIGNAL_H) \
582 $(SYSTTY_H) \ 583 $(SYSTTY_H) \
584 $(SYSWAIT_H) \
583 $(TERMHOOKS_H) 585 $(TERMHOOKS_H)
584 586
585$(BLD)/casefiddle.$(O) : \ 587$(BLD)/casefiddle.$(O) : \
@@ -737,6 +739,7 @@ $(BLD)/dispnew.$(O) : \
737 $(SRC)/termchar.h \ 739 $(SRC)/termchar.h \
738 $(SRC)/w32.h \ 740 $(SRC)/w32.h \
739 $(NT_INC)/unistd.h \ 741 $(NT_INC)/unistd.h \
742 $(GNU_LIB)/fpending.h \
740 $(BUFFER_H) \ 743 $(BUFFER_H) \
741 $(CHARACTER_H) \ 744 $(CHARACTER_H) \
742 $(CONFIG_H) \ 745 $(CONFIG_H) \
@@ -802,6 +805,7 @@ $(BLD)/emacs.$(O) : \
802 $(SRC)/w32select.h \ 805 $(SRC)/w32select.h \
803 $(NT_INC)/sys/file.h \ 806 $(NT_INC)/sys/file.h \
804 $(NT_INC)/unistd.h \ 807 $(NT_INC)/unistd.h \
808 $(GNU_LIB)/close-stream.h \
805 $(GNU_LIB)/ignore-value.h \ 809 $(GNU_LIB)/ignore-value.h \
806 $(ATIMER_H) \ 810 $(ATIMER_H) \
807 $(BUFFER_H) \ 811 $(BUFFER_H) \
@@ -1214,7 +1218,6 @@ $(BLD)/w32inevt.$(O) : \
1214 1218
1215$(BLD)/w32proc.$(O) : \ 1219$(BLD)/w32proc.$(O) : \
1216 $(SRC)/w32proc.c \ 1220 $(SRC)/w32proc.c \
1217 $(SRC)/syswait.h \
1218 $(SRC)/w32.h \ 1221 $(SRC)/w32.h \
1219 $(SRC)/w32common.h \ 1222 $(SRC)/w32common.h \
1220 $(SRC)/w32heap.h \ 1223 $(SRC)/w32heap.h \
@@ -1228,6 +1231,7 @@ $(BLD)/w32proc.$(O) : \
1228 $(PROCESS_H) \ 1231 $(PROCESS_H) \
1229 $(SYSSIGNAL_H) \ 1232 $(SYSSIGNAL_H) \
1230 $(SYSTIME_H) \ 1233 $(SYSTIME_H) \
1234 $(SYSWAIT_H) \
1231 $(W32TERM_H) 1235 $(W32TERM_H)
1232 1236
1233$(BLD)/w32console.$(O) : \ 1237$(BLD)/w32console.$(O) : \
@@ -1272,7 +1276,6 @@ $(BLD)/process.$(O) : \
1272 $(SRC)/composite.h \ 1276 $(SRC)/composite.h \
1273 $(SRC)/gnutls.h \ 1277 $(SRC)/gnutls.h \
1274 $(SRC)/sysselect.h \ 1278 $(SRC)/sysselect.h \
1275 $(SRC)/syswait.h \
1276 $(SRC)/termopts.h \ 1279 $(SRC)/termopts.h \
1277 $(NT_INC)/arpa/inet.h \ 1280 $(NT_INC)/arpa/inet.h \
1278 $(NT_INC)/netdb.h \ 1281 $(NT_INC)/netdb.h \
@@ -1295,6 +1298,7 @@ $(BLD)/process.$(O) : \
1295 $(SYSSIGNAL_H) \ 1298 $(SYSSIGNAL_H) \
1296 $(SYSTIME_H) \ 1299 $(SYSTIME_H) \
1297 $(SYSTTY_H) \ 1300 $(SYSTTY_H) \
1301 $(SYSWAIT_H) \
1298 $(TERMHOOKS_H) \ 1302 $(TERMHOOKS_H) \
1299 $(W32TERM_H) \ 1303 $(W32TERM_H) \
1300 $(WINDOW_H) 1304 $(WINDOW_H)
@@ -1378,7 +1382,6 @@ $(BLD)/sysdep.$(O) : \
1378 $(SRC)/blockinput.h \ 1382 $(SRC)/blockinput.h \
1379 $(SRC)/cm.h \ 1383 $(SRC)/cm.h \
1380 $(SRC)/sysselect.h \ 1384 $(SRC)/sysselect.h \
1381 $(SRC)/syswait.h \
1382 $(SRC)/termchar.h \ 1385 $(SRC)/termchar.h \
1383 $(SRC)/termopts.h \ 1386 $(SRC)/termopts.h \
1384 $(NT_INC)/netdb.h \ 1387 $(NT_INC)/netdb.h \
@@ -1403,6 +1406,7 @@ $(BLD)/sysdep.$(O) : \
1403 $(SYSSIGNAL_H) \ 1406 $(SYSSIGNAL_H) \
1404 $(SYSTIME_H) \ 1407 $(SYSTIME_H) \
1405 $(SYSTTY_H) \ 1408 $(SYSTTY_H) \
1409 $(SYSWAIT_H) \
1406 $(TERMHOOKS_H) \ 1410 $(TERMHOOKS_H) \
1407 $(WINDOW_H) 1411 $(WINDOW_H)
1408 1412
diff --git a/src/nsterm.m b/src/nsterm.m
index 7ba1608268b..57d32ee0528 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -30,7 +30,9 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
30 interpretation of even the system includes. */ 30 interpretation of even the system includes. */
31#include <config.h> 31#include <config.h>
32 32
33#include <fcntl.h>
33#include <math.h> 34#include <math.h>
35#include <pthread.h>
34#include <sys/types.h> 36#include <sys/types.h>
35#include <time.h> 37#include <time.h>
36#include <signal.h> 38#include <signal.h>
@@ -40,10 +42,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
40#include <c-strcase.h> 42#include <c-strcase.h>
41#include <ftoastr.h> 43#include <ftoastr.h>
42 44
43#ifdef HAVE_FCNTL_H
44#include <fcntl.h>
45#endif
46
47#include "lisp.h" 45#include "lisp.h"
48#include "blockinput.h" 46#include "blockinput.h"
49#include "sysselect.h" 47#include "sysselect.h"
@@ -330,6 +328,9 @@ hold_event (struct input_event *event)
330 } 328 }
331 329
332 hold_event_q.q[hold_event_q.nr++] = *event; 330 hold_event_q.q[hold_event_q.nr++] = *event;
331 /* Make sure ns_read_socket is called, i.e. we have input. */
332 raise (SIGIO);
333 send_appdefined = YES;
333} 334}
334 335
335static Lisp_Object 336static Lisp_Object
@@ -3387,7 +3388,7 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
3387 if ([NSApp modalWindow] != nil) 3388 if ([NSApp modalWindow] != nil)
3388 return -1; 3389 return -1;
3389 3390
3390 if (hold_event_q.nr > 0) 3391 if (hold_event_q.nr > 0)
3391 { 3392 {
3392 int i; 3393 int i;
3393 for (i = 0; i < hold_event_q.nr; ++i) 3394 for (i = 0; i < hold_event_q.nr; ++i)
@@ -3461,6 +3462,14 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3461 3462
3462/* NSTRACE (ns_select); */ 3463/* NSTRACE (ns_select); */
3463 3464
3465 if (hold_event_q.nr > 0)
3466 {
3467 /* We already have events pending. */
3468 raise (SIGIO);
3469 errno = EINTR;
3470 return -1;
3471 }
3472
3464 for (k = 0; k < nfds+1; k++) 3473 for (k = 0; k < nfds+1; k++)
3465 { 3474 {
3466 if (readfds && FD_ISSET(k, readfds)) ++nr; 3475 if (readfds && FD_ISSET(k, readfds)) ++nr;
@@ -3502,7 +3511,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3502 3511
3503 /* Inform fd_handler that select should be called */ 3512 /* Inform fd_handler that select should be called */
3504 c = 'g'; 3513 c = 'g';
3505 write (selfds[1], &c, 1); 3514 emacs_write (selfds[1], &c, 1);
3506 } 3515 }
3507 else if (nr == 0 && timeout) 3516 else if (nr == 0 && timeout)
3508 { 3517 {
@@ -3535,7 +3544,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3535 if (nr > 0 && readfds) 3544 if (nr > 0 && readfds)
3536 { 3545 {
3537 c = 's'; 3546 c = 's';
3538 write (selfds[1], &c, 1); 3547 emacs_write (selfds[1], &c, 1);
3539 } 3548 }
3540 unblock_input (); 3549 unblock_input ();
3541 3550
@@ -4112,8 +4121,6 @@ ns_term_init (Lisp_Object display_name)
4112 4121
4113 color_file = Fexpand_file_name (build_string ("rgb.txt"), 4122 color_file = Fexpand_file_name (build_string ("rgb.txt"),
4114 Fsymbol_value (intern ("data-directory"))); 4123 Fsymbol_value (intern ("data-directory")));
4115 if (NILP (Ffile_readable_p (color_file)))
4116 fatal ("Could not find %s.\n", SDATA (color_file));
4117 4124
4118 color_map = Fx_load_color_file (color_file); 4125 color_map = Fx_load_color_file (color_file);
4119 if (NILP (color_map)) 4126 if (NILP (color_map))
@@ -4576,11 +4583,8 @@ not_in_argv (NSString *arg)
4576 4583
4577 FD_SET (selfds[0], &fds); 4584 FD_SET (selfds[0], &fds);
4578 result = select (selfds[0]+1, &fds, NULL, NULL, NULL); 4585 result = select (selfds[0]+1, &fds, NULL, NULL, NULL);
4579 if (result > 0) 4586 if (result > 0 && read (selfds[0], &c, 1) == 1 && c == 'g')
4580 { 4587 waiting = 0;
4581 read (selfds[0], &c, 1);
4582 if (c == 'g') waiting = 0;
4583 }
4584 } 4588 }
4585 else 4589 else
4586 { 4590 {
@@ -4620,8 +4624,8 @@ not_in_argv (NSString *arg)
4620 { 4624 {
4621 if (FD_ISSET (selfds[0], &readfds)) 4625 if (FD_ISSET (selfds[0], &readfds))
4622 { 4626 {
4623 read (selfds[0], &c, 1); 4627 if (read (selfds[0], &c, 1) == 1 && c == 's')
4624 if (c == 's') waiting = 1; 4628 waiting = 1;
4625 } 4629 }
4626 else 4630 else
4627 { 4631 {
@@ -6696,7 +6700,7 @@ not_in_argv (NSString *arg)
6696 /* Events may come here even if the event loop is not running. 6700 /* Events may come here even if the event loop is not running.
6697 If we don't enter the event loop, the scroll bar will not update. 6701 If we don't enter the event loop, the scroll bar will not update.
6698 So send SIGIO to ourselves. */ 6702 So send SIGIO to ourselves. */
6699 if (apploopnr == 0) kill (0, SIGIO); 6703 if (apploopnr == 0) raise (SIGIO);
6700 6704
6701 return self; 6705 return self;
6702} 6706}
diff --git a/src/process.c b/src/process.c
index 43f0239d301..0036ce595f5 100644
--- a/src/process.c
+++ b/src/process.c
@@ -130,18 +130,6 @@ extern int sys_select (int, SELECT_TYPE *, SELECT_TYPE *, SELECT_TYPE *,
130 EMACS_TIME *, void *); 130 EMACS_TIME *, void *);
131#endif 131#endif
132 132
133/* This is for DOS_NT ports. FIXME: Remove this old portability cruft
134 by having DOS_NT ports implement waitpid instead of wait. Nowadays
135 POSIXish hosts all define waitpid, WNOHANG, and WUNTRACED, as these
136 have been standard since POSIX.1-1988. */
137#ifndef WNOHANG
138# undef waitpid
139# define waitpid(pid, status, options) wait (status)
140#endif
141#ifndef WUNTRACED
142# define WUNTRACED 0
143#endif
144
145/* Work around GCC 4.7.0 bug with strict overflow checking; see 133/* Work around GCC 4.7.0 bug with strict overflow checking; see
146 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. 134 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
147 These lines can be removed once the GCC bug is fixed. */ 135 These lines can be removed once the GCC bug is fixed. */
@@ -208,11 +196,9 @@ static EMACS_INT update_tick;
208#ifndef NON_BLOCKING_CONNECT 196#ifndef NON_BLOCKING_CONNECT
209#ifdef HAVE_SELECT 197#ifdef HAVE_SELECT
210#if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX) 198#if defined (HAVE_GETPEERNAME) || defined (GNU_LINUX)
211#if defined (O_NONBLOCK) || defined (O_NDELAY)
212#if defined (EWOULDBLOCK) || defined (EINPROGRESS) 199#if defined (EWOULDBLOCK) || defined (EINPROGRESS)
213#define NON_BLOCKING_CONNECT 200#define NON_BLOCKING_CONNECT
214#endif /* EWOULDBLOCK || EINPROGRESS */ 201#endif /* EWOULDBLOCK || EINPROGRESS */
215#endif /* O_NONBLOCK || O_NDELAY */
216#endif /* HAVE_GETPEERNAME || GNU_LINUX */ 202#endif /* HAVE_GETPEERNAME || GNU_LINUX */
217#endif /* HAVE_SELECT */ 203#endif /* HAVE_SELECT */
218#endif /* NON_BLOCKING_CONNECT */ 204#endif /* NON_BLOCKING_CONNECT */
@@ -340,9 +326,6 @@ static struct sockaddr_and_len {
340#define DATAGRAM_CONN_P(proc) (0) 326#define DATAGRAM_CONN_P(proc) (0)
341#endif 327#endif
342 328
343/* Maximum number of bytes to send to a pty without an eof. */
344static int pty_max_bytes;
345
346/* These setters are used only in this file, so they can be private. */ 329/* These setters are used only in this file, so they can be private. */
347static void 330static void
348pset_buffer (struct Lisp_Process *p, Lisp_Object val) 331pset_buffer (struct Lisp_Process *p, Lisp_Object val)
@@ -654,13 +637,7 @@ allocate_pty (void)
654#ifdef PTY_OPEN 637#ifdef PTY_OPEN
655 PTY_OPEN; 638 PTY_OPEN;
656#else /* no PTY_OPEN */ 639#else /* no PTY_OPEN */
657 { 640 fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0);
658# ifdef O_NONBLOCK
659 fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0);
660# else
661 fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0);
662# endif
663 }
664#endif /* no PTY_OPEN */ 641#endif /* no PTY_OPEN */
665 642
666 if (fd >= 0) 643 if (fd >= 0)
@@ -672,7 +649,7 @@ allocate_pty (void)
672#else 649#else
673 sprintf (pty_name, "/dev/tty%c%x", c, i); 650 sprintf (pty_name, "/dev/tty%c%x", c, i);
674#endif /* no PTY_TTY_NAME_SPRINTF */ 651#endif /* no PTY_TTY_NAME_SPRINTF */
675 if (access (pty_name, 6) != 0) 652 if (faccessat (AT_FDCWD, pty_name, R_OK | W_OK, AT_EACCESS) != 0)
676 { 653 {
677 emacs_close (fd); 654 emacs_close (fd);
678# ifndef __sgi 655# ifndef __sgi
@@ -1598,7 +1575,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1598 int inchannel, outchannel; 1575 int inchannel, outchannel;
1599 pid_t pid; 1576 pid_t pid;
1600 int sv[2]; 1577 int sv[2];
1601#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) 1578#ifndef WINDOWSNT
1602 int wait_child_setup[2]; 1579 int wait_child_setup[2];
1603#endif 1580#endif
1604#ifdef SIGCHLD 1581#ifdef SIGCHLD
@@ -1624,13 +1601,9 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1624#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 1601#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
1625 /* On most USG systems it does not work to open the pty's tty here, 1602 /* On most USG systems it does not work to open the pty's tty here,
1626 then close it and reopen it in the child. */ 1603 then close it and reopen it in the child. */
1627#ifdef O_NOCTTY
1628 /* Don't let this terminal become our controlling terminal 1604 /* Don't let this terminal become our controlling terminal
1629 (in case we don't have one). */ 1605 (in case we don't have one). */
1630 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); 1606 forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
1631#else
1632 forkout = forkin = emacs_open (pty_name, O_RDWR, 0);
1633#endif
1634 if (forkin < 0) 1607 if (forkin < 0)
1635 report_file_error ("Opening pty", Qnil); 1608 report_file_error ("Opening pty", Qnil);
1636#else 1609#else
@@ -1659,7 +1632,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1659 forkin = sv[0]; 1632 forkin = sv[0];
1660 } 1633 }
1661 1634
1662#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) 1635#ifndef WINDOWSNT
1663 { 1636 {
1664 int tem; 1637 int tem;
1665 1638
@@ -1678,15 +1651,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1678 } 1651 }
1679#endif 1652#endif
1680 1653
1681#ifdef O_NONBLOCK
1682 fcntl (inchannel, F_SETFL, O_NONBLOCK); 1654 fcntl (inchannel, F_SETFL, O_NONBLOCK);
1683 fcntl (outchannel, F_SETFL, O_NONBLOCK); 1655 fcntl (outchannel, F_SETFL, O_NONBLOCK);
1684#else
1685#ifdef O_NDELAY
1686 fcntl (inchannel, F_SETFL, O_NDELAY);
1687 fcntl (outchannel, F_SETFL, O_NDELAY);
1688#endif
1689#endif
1690 1656
1691 /* Record this as an active process, with its channels. 1657 /* Record this as an active process, with its channels.
1692 As a result, child_setup will close Emacs's side of the pipes. */ 1658 As a result, child_setup will close Emacs's side of the pipes. */
@@ -1845,9 +1811,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1845 pid = child_setup (xforkin, xforkout, xforkout, 1811 pid = child_setup (xforkin, xforkout, xforkout,
1846 new_argv, 1, encoded_current_dir); 1812 new_argv, 1, encoded_current_dir);
1847#else /* not WINDOWSNT */ 1813#else /* not WINDOWSNT */
1848#ifdef FD_CLOEXEC
1849 emacs_close (wait_child_setup[0]); 1814 emacs_close (wait_child_setup[0]);
1850#endif
1851 child_setup (xforkin, xforkout, xforkout, 1815 child_setup (xforkin, xforkout, xforkout,
1852 new_argv, 1, encoded_current_dir); 1816 new_argv, 1, encoded_current_dir);
1853#endif /* not WINDOWSNT */ 1817#endif /* not WINDOWSNT */
@@ -1906,7 +1870,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1906 1870
1907 pset_tty_name (XPROCESS (process), lisp_pty_name); 1871 pset_tty_name (XPROCESS (process), lisp_pty_name);
1908 1872
1909#if !defined (WINDOWSNT) && defined (FD_CLOEXEC) 1873#ifndef WINDOWSNT
1910 /* Wait for child_setup to complete in case that vfork is 1874 /* Wait for child_setup to complete in case that vfork is
1911 actually defined as fork. The descriptor wait_child_setup[1] 1875 actually defined as fork. The descriptor wait_child_setup[1]
1912 of a pipe is closed at the child side either by close-on-exec 1876 of a pipe is closed at the child side either by close-on-exec
@@ -1943,13 +1907,9 @@ create_pty (Lisp_Object process)
1943#if ! defined (USG) || defined (USG_SUBTTY_WORKS) 1907#if ! defined (USG) || defined (USG_SUBTTY_WORKS)
1944 /* On most USG systems it does not work to open the pty's tty here, 1908 /* On most USG systems it does not work to open the pty's tty here,
1945 then close it and reopen it in the child. */ 1909 then close it and reopen it in the child. */
1946#ifdef O_NOCTTY
1947 /* Don't let this terminal become our controlling terminal 1910 /* Don't let this terminal become our controlling terminal
1948 (in case we don't have one). */ 1911 (in case we don't have one). */
1949 int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0); 1912 int forkout = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
1950#else
1951 int forkout = emacs_open (pty_name, O_RDWR, 0);
1952#endif
1953 if (forkout < 0) 1913 if (forkout < 0)
1954 report_file_error ("Opening pty", Qnil); 1914 report_file_error ("Opening pty", Qnil);
1955#if defined (DONT_REOPEN_PTY) 1915#if defined (DONT_REOPEN_PTY)
@@ -1963,15 +1923,8 @@ create_pty (Lisp_Object process)
1963 } 1923 }
1964#endif /* HAVE_PTYS */ 1924#endif /* HAVE_PTYS */
1965 1925
1966#ifdef O_NONBLOCK
1967 fcntl (inchannel, F_SETFL, O_NONBLOCK); 1926 fcntl (inchannel, F_SETFL, O_NONBLOCK);
1968 fcntl (outchannel, F_SETFL, O_NONBLOCK); 1927 fcntl (outchannel, F_SETFL, O_NONBLOCK);
1969#else
1970#ifdef O_NDELAY
1971 fcntl (inchannel, F_SETFL, O_NDELAY);
1972 fcntl (outchannel, F_SETFL, O_NDELAY);
1973#endif
1974#endif
1975 1928
1976 /* Record this as an active process, with its channels. 1929 /* Record this as an active process, with its channels.
1977 As a result, child_setup will close Emacs's side of the pipes. */ 1930 As a result, child_setup will close Emacs's side of the pipes. */
@@ -2927,13 +2880,9 @@ usage: (make-network-process &rest ARGS) */)
2927 { 2880 {
2928 /* Don't support network sockets when non-blocking mode is 2881 /* Don't support network sockets when non-blocking mode is
2929 not available, since a blocked Emacs is not useful. */ 2882 not available, since a blocked Emacs is not useful. */
2930#if !defined (O_NONBLOCK) && !defined (O_NDELAY)
2931 error ("Network servers not supported");
2932#else
2933 is_server = 1; 2883 is_server = 1;
2934 if (TYPE_RANGED_INTEGERP (int, tem)) 2884 if (TYPE_RANGED_INTEGERP (int, tem))
2935 backlog = XINT (tem); 2885 backlog = XINT (tem);
2936#endif
2937 } 2886 }
2938 2887
2939 /* Make QCaddress an alias for :local (server) or :remote (client). */ 2888 /* Make QCaddress an alias for :local (server) or :remote (client). */
@@ -3193,11 +3142,7 @@ usage: (make-network-process &rest ARGS) */)
3193#ifdef NON_BLOCKING_CONNECT 3142#ifdef NON_BLOCKING_CONNECT
3194 if (is_non_blocking_client) 3143 if (is_non_blocking_client)
3195 { 3144 {
3196#ifdef O_NONBLOCK
3197 ret = fcntl (s, F_SETFL, O_NONBLOCK); 3145 ret = fcntl (s, F_SETFL, O_NONBLOCK);
3198#else
3199 ret = fcntl (s, F_SETFL, O_NDELAY);
3200#endif
3201 if (ret < 0) 3146 if (ret < 0)
3202 { 3147 {
3203 xerrno = errno; 3148 xerrno = errno;
@@ -3410,13 +3355,7 @@ usage: (make-network-process &rest ARGS) */)
3410 3355
3411 chan_process[inch] = proc; 3356 chan_process[inch] = proc;
3412 3357
3413#ifdef O_NONBLOCK
3414 fcntl (inch, F_SETFL, O_NONBLOCK); 3358 fcntl (inch, F_SETFL, O_NONBLOCK);
3415#else
3416#ifdef O_NDELAY
3417 fcntl (inch, F_SETFL, O_NDELAY);
3418#endif
3419#endif
3420 3359
3421 p = XPROCESS (proc); 3360 p = XPROCESS (proc);
3422 3361
@@ -4145,13 +4084,7 @@ server_accept_connection (Lisp_Object server, int channel)
4145 4084
4146 chan_process[s] = proc; 4085 chan_process[s] = proc;
4147 4086
4148#ifdef O_NONBLOCK
4149 fcntl (s, F_SETFL, O_NONBLOCK); 4087 fcntl (s, F_SETFL, O_NONBLOCK);
4150#else
4151#ifdef O_NDELAY
4152 fcntl (s, F_SETFL, O_NDELAY);
4153#endif
4154#endif
4155 4088
4156 p = XPROCESS (proc); 4089 p = XPROCESS (proc);
4157 4090
@@ -4847,23 +4780,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4847 else if (nread == -1 && errno == EWOULDBLOCK) 4780 else if (nread == -1 && errno == EWOULDBLOCK)
4848 ; 4781 ;
4849#endif 4782#endif
4850 /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK,
4851 and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */
4852#ifdef O_NONBLOCK
4853 else if (nread == -1 && errno == EAGAIN)
4854 ;
4855#else
4856#ifdef O_NDELAY
4857 else if (nread == -1 && errno == EAGAIN) 4783 else if (nread == -1 && errno == EAGAIN)
4858 ; 4784 ;
4785#ifdef WINDOWSNT
4786 /* FIXME: Is this special case still needed? */
4859 /* Note that we cannot distinguish between no input 4787 /* Note that we cannot distinguish between no input
4860 available now and a closed pipe. 4788 available now and a closed pipe.
4861 With luck, a closed pipe will be accompanied by 4789 With luck, a closed pipe will be accompanied by
4862 subprocess termination and SIGCHLD. */ 4790 subprocess termination and SIGCHLD. */
4863 else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc)) 4791 else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc))
4864 ; 4792 ;
4865#endif /* O_NDELAY */ 4793#endif
4866#endif /* O_NONBLOCK */
4867#ifdef HAVE_PTYS 4794#ifdef HAVE_PTYS
4868 /* On some OSs with ptys, when the process on one end of 4795 /* On some OSs with ptys, when the process on one end of
4869 a pty exits, the other end gets an error reading with 4796 a pty exits, the other end gets an error reading with
@@ -5532,19 +5459,6 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
5532 buf = SSDATA (object); 5459 buf = SSDATA (object);
5533 } 5460 }
5534 5461
5535 if (pty_max_bytes == 0)
5536 {
5537#if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON)
5538 pty_max_bytes = fpathconf (p->outfd, _PC_MAX_CANON);
5539 if (pty_max_bytes < 0)
5540 pty_max_bytes = 250;
5541#else
5542 pty_max_bytes = 250;
5543#endif
5544 /* Deduct one, to leave space for the eof. */
5545 pty_max_bytes--;
5546 }
5547
5548 /* If there is already data in the write_queue, put the new data 5462 /* If there is already data in the write_queue, put the new data
5549 in the back of queue. Otherwise, ignore it. */ 5463 in the back of queue. Otherwise, ignore it. */
5550 if (!NILP (p->write_queue)) 5464 if (!NILP (p->write_queue))
@@ -6311,17 +6225,9 @@ record_child_status_change (pid_t pid, int w)
6311{ 6225{
6312#ifdef SIGCHLD 6226#ifdef SIGCHLD
6313 6227
6314# ifdef WNOHANG 6228 /* Record at most one child only if we already know one child that
6315 /* On POSIXish hosts, record at most one child only if we already 6229 has exited. */
6316 know one child that has exited. */
6317 bool record_at_most_one_child = 0 <= pid; 6230 bool record_at_most_one_child = 0 <= pid;
6318# else
6319 /* On DOS_NT (the only porting target that lacks WNOHANG),
6320 record the status of at most one child process, since the SIGCHLD
6321 handler must return right away. If any more processes want to
6322 signal us, we will get another signal. */
6323 bool record_at_most_one_child = 1;
6324# endif
6325 6231
6326 Lisp_Object tail; 6232 Lisp_Object tail;
6327 6233
@@ -7348,9 +7254,7 @@ init_process_emacs (void)
7348#ifdef HAVE_GETSOCKNAME 7254#ifdef HAVE_GETSOCKNAME
7349 ADD_SUBFEATURE (QCservice, Qt); 7255 ADD_SUBFEATURE (QCservice, Qt);
7350#endif 7256#endif
7351#if defined (O_NONBLOCK) || defined (O_NDELAY)
7352 ADD_SUBFEATURE (QCserver, Qt); 7257 ADD_SUBFEATURE (QCserver, Qt);
7353#endif
7354 7258
7355 for (sopt = socket_options; sopt->name; sopt++) 7259 for (sopt = socket_options; sopt->name; sopt++)
7356 subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures); 7260 subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures);
diff --git a/src/sysdep.c b/src/sysdep.c
index aa9d0f38c3c..7c5c144fa8c 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -289,10 +289,6 @@ wait_for_termination_1 (pid_t pid, int interruptible)
289{ 289{
290 while (1) 290 while (1)
291 { 291 {
292#ifdef WINDOWSNT
293 wait (0);
294 break;
295#else /* not WINDOWSNT */
296 int status; 292 int status;
297 int wait_result = waitpid (pid, &status, 0); 293 int wait_result = waitpid (pid, &status, 0);
298 if (wait_result < 0) 294 if (wait_result < 0)
@@ -306,7 +302,8 @@ wait_for_termination_1 (pid_t pid, int interruptible)
306 break; 302 break;
307 } 303 }
308 304
309#endif /* not WINDOWSNT */ 305 /* Note: the MS-Windows emulation of waitpid calls QUIT
306 internally. */
310 if (interruptible) 307 if (interruptible)
311 QUIT; 308 QUIT;
312 } 309 }
@@ -1039,8 +1036,7 @@ init_sys_modes (struct tty_display_info *tty_out)
1039#endif 1036#endif
1040#endif 1037#endif
1041 1038
1042#ifdef F_SETFL 1039#ifdef F_GETOWN
1043#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1044 if (interrupt_input) 1040 if (interrupt_input)
1045 { 1041 {
1046 old_fcntl_owner[fileno (tty_out->input)] = 1042 old_fcntl_owner[fileno (tty_out->input)] =
@@ -1058,7 +1054,6 @@ init_sys_modes (struct tty_display_info *tty_out)
1058#endif /* HAVE_GPM */ 1054#endif /* HAVE_GPM */
1059 } 1055 }
1060#endif /* F_GETOWN */ 1056#endif /* F_GETOWN */
1061#endif /* F_SETFL */
1062 1057
1063#ifdef _IOFBF 1058#ifdef _IOFBF
1064 /* This symbol is defined on recent USG systems. 1059 /* This symbol is defined on recent USG systems.
@@ -1278,8 +1273,8 @@ reset_sys_modes (struct tty_display_info *tty_out)
1278 fsync (fileno (tty_out->output)); 1273 fsync (fileno (tty_out->output));
1279#endif 1274#endif
1280 1275
1281#ifdef F_SETFL 1276#ifndef DOS_NT
1282#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */ 1277#ifdef F_SETOWN
1283 if (interrupt_input) 1278 if (interrupt_input)
1284 { 1279 {
1285 reset_sigio (fileno (tty_out->input)); 1280 reset_sigio (fileno (tty_out->input));
@@ -1287,11 +1282,9 @@ reset_sys_modes (struct tty_display_info *tty_out)
1287 old_fcntl_owner[fileno (tty_out->input)]); 1282 old_fcntl_owner[fileno (tty_out->input)]);
1288 } 1283 }
1289#endif /* F_SETOWN */ 1284#endif /* F_SETOWN */
1290#ifdef O_NDELAY
1291 fcntl (fileno (tty_out->input), F_SETFL, 1285 fcntl (fileno (tty_out->input), F_SETFL,
1292 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY); 1286 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NONBLOCK);
1293#endif 1287#endif
1294#endif /* F_SETFL */
1295 1288
1296 if (tty_out->old_tty) 1289 if (tty_out->old_tty)
1297 while (emacs_set_tty (fileno (tty_out->input), 1290 while (emacs_set_tty (fileno (tty_out->input),
@@ -2380,19 +2373,7 @@ safe_strsignal (int code)
2380int 2373int
2381serial_open (char *port) 2374serial_open (char *port)
2382{ 2375{
2383 int fd = -1; 2376 int fd = emacs_open (port, O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
2384
2385 fd = emacs_open ((char*) port,
2386 O_RDWR
2387#ifdef O_NONBLOCK
2388 | O_NONBLOCK
2389#else
2390 | O_NDELAY
2391#endif
2392#ifdef O_NOCTTY
2393 | O_NOCTTY
2394#endif
2395 , 0);
2396 if (fd < 0) 2377 if (fd < 0)
2397 { 2378 {
2398 error ("Could not open %s: %s", 2379 error ("Could not open %s: %s",
diff --git a/src/term.c b/src/term.c
index 578c701858f..481a3423989 100644
--- a/src/term.c
+++ b/src/term.c
@@ -20,8 +20,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */ 20/* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>. */
21 21
22#include <config.h> 22#include <config.h>
23#include <stdio.h>
24#include <errno.h> 23#include <errno.h>
24#include <fcntl.h>
25#include <stdio.h>
25#include <sys/file.h> 26#include <sys/file.h>
26#include <sys/time.h> 27#include <sys/time.h>
27#include <unistd.h> 28#include <unistd.h>
@@ -55,14 +56,6 @@ static int been_here = -1;
55#include "xterm.h" 56#include "xterm.h"
56#endif 57#endif
57 58
58#ifndef O_RDWR
59#define O_RDWR 2
60#endif
61
62#ifndef O_NOCTTY
63#define O_NOCTTY 0
64#endif
65
66/* The name of the default console device. */ 59/* The name of the default console device. */
67#ifdef WINDOWSNT 60#ifdef WINDOWSNT
68#define DEV_TTY "CONOUT$" 61#define DEV_TTY "CONOUT$"
@@ -2989,22 +2982,18 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
2989 set_tty_hooks (terminal); 2982 set_tty_hooks (terminal);
2990 2983
2991 { 2984 {
2992 int fd; 2985 /* Open the terminal device. */
2993 FILE *file; 2986 FILE *file;
2994 2987
2995#ifdef O_IGNORE_CTTY 2988 /* If !ctty, don't recognize it as our controlling terminal, and
2996 if (!ctty) 2989 don't make it the controlling tty if we don't have one now.
2997 /* Open the terminal device. Don't recognize it as our 2990
2998 controlling terminal, and don't make it the controlling tty 2991 Alas, O_IGNORE_CTTY is a GNU extension that seems to be only
2999 if we don't have one at the moment. */ 2992 defined on Hurd. On other systems, we need to explicitly
3000 fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0); 2993 dissociate ourselves from the controlling tty when we want to
3001 else 2994 open a frame on the same terminal. */
3002#endif /* O_IGNORE_CTTY */ 2995 int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY);
3003 /* Alas, O_IGNORE_CTTY is a GNU extension that seems to be only 2996 int fd = emacs_open (name, flags, 0);
3004 defined on Hurd. On other systems, we need to explicitly
3005 dissociate ourselves from the controlling tty when we want to
3006 open a frame on the same terminal. */
3007 fd = emacs_open (name, O_RDWR | O_NOCTTY, 0);
3008 2997
3009 tty->name = xstrdup (name); 2998 tty->name = xstrdup (name);
3010 terminal->name = xstrdup (name); 2999 terminal->name = xstrdup (name);
@@ -3023,10 +3012,8 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3023 name); 3012 name);
3024 } 3013 }
3025 3014
3026#ifndef O_IGNORE_CTTY 3015 if (!O_IGNORE_CTTY && !ctty)
3027 if (!ctty)
3028 dissociate_if_controlling_tty (fd); 3016 dissociate_if_controlling_tty (fd);
3029#endif
3030 3017
3031 file = fdopen (fd, "w+"); 3018 file = fdopen (fd, "w+");
3032 tty->input = file; 3019 tty->input = file;
diff --git a/src/unexelf.c b/src/unexelf.c
index 121e6042fc9..b9f8e05e959 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -461,7 +461,7 @@ typedef struct {
461/* 461/*
462 * NetBSD does not have normal-looking user-land ELF support. 462 * NetBSD does not have normal-looking user-land ELF support.
463 */ 463 */
464# if defined __alpha__ || defined __sparc_v9__ 464# if defined __alpha__ || defined __sparc_v9__ || defined _LP64
465# define ELFSIZE 64 465# define ELFSIZE 64
466# else 466# else
467# define ELFSIZE 32 467# define ELFSIZE 32
diff --git a/src/w32.c b/src/w32.c
index 5ac1bc3eb7c..94cf472a4ae 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1597,7 +1597,7 @@ init_environment (char ** argv)
1597 see if it succeeds. But I think that's too much to ask. */ 1597 see if it succeeds. But I think that's too much to ask. */
1598 1598
1599 /* MSVCRT's _access crashes with D_OK. */ 1599 /* MSVCRT's _access crashes with D_OK. */
1600 if (tmp && sys_access (tmp, D_OK) == 0) 1600 if (tmp && faccessat (AT_FDCWD, tmp, D_OK, AT_EACCESS) == 0)
1601 { 1601 {
1602 char * var = alloca (strlen (tmp) + 8); 1602 char * var = alloca (strlen (tmp) + 8);
1603 sprintf (var, "TMPDIR=%s", tmp); 1603 sprintf (var, "TMPDIR=%s", tmp);
@@ -2708,16 +2708,20 @@ logon_network_drive (const char *path)
2708 WNetAddConnection2 (&resource, NULL, NULL, CONNECT_INTERACTIVE); 2708 WNetAddConnection2 (&resource, NULL, NULL, CONNECT_INTERACTIVE);
2709} 2709}
2710 2710
2711/* Shadow some MSVC runtime functions to map requests for long filenames 2711/* Emulate faccessat(2). */
2712 to reasonable short names if necessary. This was originally added to
2713 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
2714 long file names. */
2715
2716int 2712int
2717sys_access (const char * path, int mode) 2713faccessat (int dirfd, const char * path, int mode, int flags)
2718{ 2714{
2719 DWORD attributes; 2715 DWORD attributes;
2720 2716
2717 if (dirfd != AT_FDCWD
2718 && !(IS_DIRECTORY_SEP (path[0])
2719 || IS_DEVICE_SEP (path[1])))
2720 {
2721 errno = EBADF;
2722 return -1;
2723 }
2724
2721 /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its 2725 /* MSVCRT implementation of 'access' doesn't recognize D_OK, and its
2722 newer versions blow up when passed D_OK. */ 2726 newer versions blow up when passed D_OK. */
2723 path = map_w32_filename (path, NULL); 2727 path = map_w32_filename (path, NULL);
@@ -2725,7 +2729,8 @@ sys_access (const char * path, int mode)
2725 to get the attributes of its target file. Note: any symlinks in 2729 to get the attributes of its target file. Note: any symlinks in
2726 PATH elements other than the last one are transparently resolved 2730 PATH elements other than the last one are transparently resolved
2727 by GetFileAttributes below. */ 2731 by GetFileAttributes below. */
2728 if ((volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0) 2732 if ((volume_info.flags & FILE_SUPPORTS_REPARSE_POINTS) != 0
2733 && (flags & AT_SYMLINK_NOFOLLOW) == 0)
2729 path = chase_symlinks (path); 2734 path = chase_symlinks (path);
2730 2735
2731 if ((attributes = GetFileAttributes (path)) == -1) 2736 if ((attributes = GetFileAttributes (path)) == -1)
@@ -2757,7 +2762,8 @@ sys_access (const char * path, int mode)
2757 } 2762 }
2758 return -1; 2763 return -1;
2759 } 2764 }
2760 if ((mode & X_OK) != 0 && !is_exec (path)) 2765 if ((mode & X_OK) != 0
2766 && !(is_exec (path) || (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0))
2761 { 2767 {
2762 errno = EACCES; 2768 errno = EACCES;
2763 return -1; 2769 return -1;
@@ -2775,6 +2781,11 @@ sys_access (const char * path, int mode)
2775 return 0; 2781 return 0;
2776} 2782}
2777 2783
2784/* Shadow some MSVC runtime functions to map requests for long filenames
2785 to reasonable short names if necessary. This was originally added to
2786 permit running Emacs on NT 3.1 on a FAT partition, which doesn't support
2787 long file names. */
2788
2778int 2789int
2779sys_chdir (const char * path) 2790sys_chdir (const char * path)
2780{ 2791{
@@ -2960,7 +2971,7 @@ sys_mktemp (char * template)
2960 { 2971 {
2961 int save_errno = errno; 2972 int save_errno = errno;
2962 p[0] = first_char[i]; 2973 p[0] = first_char[i];
2963 if (sys_access (template, 0) < 0) 2974 if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0)
2964 { 2975 {
2965 errno = save_errno; 2976 errno = save_errno;
2966 return template; 2977 return template;
@@ -4011,7 +4022,7 @@ symlink (char const *filename, char const *linkname)
4011 { 4022 {
4012 /* Non-absolute FILENAME is understood as being relative to 4023 /* Non-absolute FILENAME is understood as being relative to
4013 LINKNAME's directory. We need to prepend that directory to 4024 LINKNAME's directory. We need to prepend that directory to
4014 FILENAME to get correct results from sys_access below, since 4025 FILENAME to get correct results from faccessat below, since
4015 otherwise it will interpret FILENAME relative to the 4026 otherwise it will interpret FILENAME relative to the
4016 directory where the Emacs process runs. Note that 4027 directory where the Emacs process runs. Note that
4017 make-symbolic-link always makes sure LINKNAME is a fully 4028 make-symbolic-link always makes sure LINKNAME is a fully
@@ -4025,10 +4036,10 @@ symlink (char const *filename, char const *linkname)
4025 strncpy (tem, linkfn, p - linkfn); 4036 strncpy (tem, linkfn, p - linkfn);
4026 tem[p - linkfn] = '\0'; 4037 tem[p - linkfn] = '\0';
4027 strcat (tem, filename); 4038 strcat (tem, filename);
4028 dir_access = sys_access (tem, D_OK); 4039 dir_access = faccessat (AT_FDCWD, tem, D_OK, AT_EACCESS);
4029 } 4040 }
4030 else 4041 else
4031 dir_access = sys_access (filename, D_OK); 4042 dir_access = faccessat (AT_FDCWD, filename, D_OK, AT_EACCESS);
4032 4043
4033 /* Since Windows distinguishes between symlinks to directories and 4044 /* Since Windows distinguishes between symlinks to directories and
4034 to files, we provide a kludgy feature: if FILENAME doesn't 4045 to files, we provide a kludgy feature: if FILENAME doesn't
@@ -5843,7 +5854,7 @@ fcntl (int s, int cmd, int options)
5843 check_errno (); 5854 check_errno ();
5844 if (fd_info[s].flags & FILE_SOCKET) 5855 if (fd_info[s].flags & FILE_SOCKET)
5845 { 5856 {
5846 if (cmd == F_SETFL && options == O_NDELAY) 5857 if (cmd == F_SETFL && options == O_NONBLOCK)
5847 { 5858 {
5848 unsigned long nblock = 1; 5859 unsigned long nblock = 1;
5849 int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock); 5860 int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock);
diff --git a/src/w32proc.c b/src/w32proc.c
index f35a2da537c..9b111b40e36 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -431,13 +431,14 @@ timer_loop (LPVOID arg)
431 /* Simulate a signal delivered to the thread which installed 431 /* Simulate a signal delivered to the thread which installed
432 the timer, by suspending that thread while the handler 432 the timer, by suspending that thread while the handler
433 runs. */ 433 runs. */
434 DWORD result = SuspendThread (itimer->caller_thread); 434 HANDLE th = itimer->caller_thread;
435 DWORD result = SuspendThread (th);
435 436
436 if (result == (DWORD)-1) 437 if (result == (DWORD)-1)
437 return 2; 438 return 2;
438 439
439 handler (sig); 440 handler (sig);
440 ResumeThread (itimer->caller_thread); 441 ResumeThread (th);
441 } 442 }
442 443
443 /* Update expiration time and loop. */ 444 /* Update expiration time and loop. */
@@ -562,6 +563,7 @@ static int
562start_timer_thread (int which) 563start_timer_thread (int which)
563{ 564{
564 DWORD exit_code; 565 DWORD exit_code;
566 HANDLE th;
565 struct itimer_data *itimer = 567 struct itimer_data *itimer =
566 (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; 568 (which == ITIMER_REAL) ? &real_itimer : &prof_itimer;
567 569
@@ -570,9 +572,29 @@ start_timer_thread (int which)
570 && exit_code == STILL_ACTIVE) 572 && exit_code == STILL_ACTIVE)
571 return 0; 573 return 0;
572 574
575 /* Clean up after possibly exited thread. */
576 if (itimer->timer_thread)
577 {
578 CloseHandle (itimer->timer_thread);
579 itimer->timer_thread = NULL;
580 }
581 if (itimer->caller_thread)
582 {
583 CloseHandle (itimer->caller_thread);
584 itimer->caller_thread = NULL;
585 }
586
573 /* Start a new thread. */ 587 /* Start a new thread. */
588 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
589 GetCurrentProcess (), &th, 0, FALSE,
590 DUPLICATE_SAME_ACCESS))
591 {
592 errno = ESRCH;
593 return -1;
594 }
574 itimer->terminate = 0; 595 itimer->terminate = 0;
575 itimer->type = which; 596 itimer->type = which;
597 itimer->caller_thread = th;
576 /* Request that no more than 64KB of stack be reserved for this 598 /* Request that no more than 64KB of stack be reserved for this
577 thread, to avoid reserving too much memory, which would get in 599 thread, to avoid reserving too much memory, which would get in
578 the way of threads we start to wait for subprocesses. See also 600 the way of threads we start to wait for subprocesses. See also
@@ -591,7 +613,7 @@ start_timer_thread (int which)
591 /* This is needed to make sure that the timer thread running for 613 /* This is needed to make sure that the timer thread running for
592 profiling gets CPU as soon as the Sleep call terminates. */ 614 profiling gets CPU as soon as the Sleep call terminates. */
593 if (which == ITIMER_PROF) 615 if (which == ITIMER_PROF)
594 SetThreadPriority (itimer->caller_thread, THREAD_PRIORITY_TIME_CRITICAL); 616 SetThreadPriority (itimer->timer_thread, THREAD_PRIORITY_TIME_CRITICAL);
595 617
596 return 0; 618 return 0;
597} 619}
@@ -626,17 +648,9 @@ getitimer (int which, struct itimerval *value)
626 648
627 itimer = (which == ITIMER_REAL) ? &real_itimer : &prof_itimer; 649 itimer = (which == ITIMER_REAL) ? &real_itimer : &prof_itimer;
628 650
629 if (!DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
630 GetCurrentProcess (), &itimer->caller_thread, 0,
631 FALSE, DUPLICATE_SAME_ACCESS))
632 {
633 errno = ESRCH;
634 return -1;
635 }
636
637 ticks_now = w32_get_timer_time ((which == ITIMER_REAL) 651 ticks_now = w32_get_timer_time ((which == ITIMER_REAL)
638 ? NULL 652 ? NULL
639 : itimer->caller_thread); 653 : GetCurrentThread ());
640 654
641 t_expire = &itimer->expire; 655 t_expire = &itimer->expire;
642 t_reload = &itimer->reload; 656 t_reload = &itimer->reload;
@@ -775,7 +789,6 @@ alarm (int seconds)
775/* Child process management list. */ 789/* Child process management list. */
776int child_proc_count = 0; 790int child_proc_count = 0;
777child_process child_procs[ MAX_CHILDREN ]; 791child_process child_procs[ MAX_CHILDREN ];
778child_process *dead_child = NULL;
779 792
780static DWORD WINAPI reader_thread (void *arg); 793static DWORD WINAPI reader_thread (void *arg);
781 794
@@ -1028,9 +1041,6 @@ create_child (char *exe, char *cmdline, char *env, int is_gui_app,
1028 if (cp->pid < 0) 1041 if (cp->pid < 0)
1029 cp->pid = -cp->pid; 1042 cp->pid = -cp->pid;
1030 1043
1031 /* pid must fit in a Lisp_Int */
1032 cp->pid = cp->pid & INTMASK;
1033
1034 *pPid = cp->pid; 1044 *pPid = cp->pid;
1035 1045
1036 return TRUE; 1046 return TRUE;
@@ -1106,55 +1116,110 @@ reap_subprocess (child_process *cp)
1106 delete_child (cp); 1116 delete_child (cp);
1107} 1117}
1108 1118
1109/* Wait for any of our existing child processes to die 1119/* Wait for a child process specified by PID, or for any of our
1110 When it does, close its handle 1120 existing child processes (if PID is nonpositive) to die. When it
1111 Return the pid and fill in the status if non-NULL. */ 1121 does, close its handle. Return the pid of the process that died
1122 and fill in STATUS if non-NULL. */
1112 1123
1113int 1124pid_t
1114sys_wait (int *status) 1125waitpid (pid_t pid, int *status, int options)
1115{ 1126{
1116 DWORD active, retval; 1127 DWORD active, retval;
1117 int nh; 1128 int nh;
1118 int pid;
1119 child_process *cp, *cps[MAX_CHILDREN]; 1129 child_process *cp, *cps[MAX_CHILDREN];
1120 HANDLE wait_hnd[MAX_CHILDREN]; 1130 HANDLE wait_hnd[MAX_CHILDREN];
1131 DWORD timeout_ms;
1132 int dont_wait = (options & WNOHANG) != 0;
1121 1133
1122 nh = 0; 1134 nh = 0;
1123 if (dead_child != NULL) 1135 /* According to Posix:
1136
1137 PID = -1 means status is requested for any child process.
1138
1139 PID > 0 means status is requested for a single child process
1140 whose pid is PID.
1141
1142 PID = 0 means status is requested for any child process whose
1143 process group ID is equal to that of the calling process. But
1144 since Windows has only a limited support for process groups (only
1145 for console processes and only for the purposes of passing
1146 Ctrl-BREAK signal to them), and since we have no documented way
1147 of determining whether a given process belongs to our group, we
1148 treat 0 as -1.
1149
1150 PID < -1 means status is requested for any child process whose
1151 process group ID is equal to the absolute value of PID. Again,
1152 since we don't support process groups, we treat that as -1. */
1153 if (pid > 0)
1124 { 1154 {
1125 /* We want to wait for a specific child */ 1155 int our_child = 0;
1126 wait_hnd[nh] = dead_child->procinfo.hProcess; 1156
1127 cps[nh] = dead_child; 1157 /* We are requested to wait for a specific child. */
1128 if (!wait_hnd[nh]) emacs_abort (); 1158 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
1129 nh++; 1159 {
1130 active = 0; 1160 /* Some child_procs might be sockets; ignore them. Also
1131 goto get_result; 1161 ignore subprocesses whose output is not yet completely
1162 read. */
1163 if (CHILD_ACTIVE (cp)
1164 && cp->procinfo.hProcess
1165 && cp->pid == pid)
1166 {
1167 our_child = 1;
1168 break;
1169 }
1170 }
1171 if (our_child)
1172 {
1173 if (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)
1174 {
1175 wait_hnd[nh] = cp->procinfo.hProcess;
1176 cps[nh] = cp;
1177 nh++;
1178 }
1179 else if (dont_wait)
1180 {
1181 /* PID specifies our subprocess, but its status is not
1182 yet available. */
1183 return 0;
1184 }
1185 }
1186 if (nh == 0)
1187 {
1188 /* No such child process, or nothing to wait for, so fail. */
1189 errno = ECHILD;
1190 return -1;
1191 }
1132 } 1192 }
1133 else 1193 else
1134 { 1194 {
1135 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--) 1195 for (cp = child_procs + (child_proc_count-1); cp >= child_procs; cp--)
1136 /* some child_procs might be sockets; ignore them */ 1196 {
1137 if (CHILD_ACTIVE (cp) && cp->procinfo.hProcess 1197 if (CHILD_ACTIVE (cp)
1138 && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0)) 1198 && cp->procinfo.hProcess
1139 { 1199 && (cp->fd < 0 || (fd_info[cp->fd].flags & FILE_AT_EOF) != 0))
1140 wait_hnd[nh] = cp->procinfo.hProcess; 1200 {
1141 cps[nh] = cp; 1201 wait_hnd[nh] = cp->procinfo.hProcess;
1142 nh++; 1202 cps[nh] = cp;
1143 } 1203 nh++;
1204 }
1205 }
1206 if (nh == 0)
1207 {
1208 /* Nothing to wait on, so fail. */
1209 errno = ECHILD;
1210 return -1;
1211 }
1144 } 1212 }
1145 1213
1146 if (nh == 0) 1214 if (dont_wait)
1147 { 1215 timeout_ms = 0;
1148 /* Nothing to wait on, so fail */ 1216 else
1149 errno = ECHILD; 1217 timeout_ms = 1000; /* check for quit about once a second. */
1150 return -1;
1151 }
1152 1218
1153 do 1219 do
1154 { 1220 {
1155 /* Check for quit about once a second. */
1156 QUIT; 1221 QUIT;
1157 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, 1000); 1222 active = WaitForMultipleObjects (nh, wait_hnd, FALSE, timeout_ms);
1158 } while (active == WAIT_TIMEOUT); 1223 } while (active == WAIT_TIMEOUT);
1159 1224
1160 if (active == WAIT_FAILED) 1225 if (active == WAIT_FAILED)
@@ -1175,7 +1240,6 @@ sys_wait (int *status)
1175 else 1240 else
1176 emacs_abort (); 1241 emacs_abort ();
1177 1242
1178get_result:
1179 if (!GetExitCodeProcess (wait_hnd[active], &retval)) 1243 if (!GetExitCodeProcess (wait_hnd[active], &retval))
1180 { 1244 {
1181 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n", 1245 DebPrint (("Wait.GetExitCodeProcess failed with %lu\n",
@@ -1184,8 +1248,10 @@ get_result:
1184 } 1248 }
1185 if (retval == STILL_ACTIVE) 1249 if (retval == STILL_ACTIVE)
1186 { 1250 {
1187 /* Should never happen */ 1251 /* Should never happen. */
1188 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n")); 1252 DebPrint (("Wait.WaitForMultipleObjects returned an active process\n"));
1253 if (pid > 0 && dont_wait)
1254 return 0;
1189 errno = EINVAL; 1255 errno = EINVAL;
1190 return -1; 1256 return -1;
1191 } 1257 }
@@ -1199,6 +1265,8 @@ get_result:
1199 else 1265 else
1200 retval <<= 8; 1266 retval <<= 8;
1201 1267
1268 if (pid > 0 && active != 0)
1269 emacs_abort ();
1202 cp = cps[active]; 1270 cp = cps[active];
1203 pid = cp->pid; 1271 pid = cp->pid;
1204#ifdef FULL_DEBUG 1272#ifdef FULL_DEBUG
@@ -1987,9 +2055,7 @@ count_children:
1987 DebPrint (("select calling SIGCHLD handler for pid %d\n", 2055 DebPrint (("select calling SIGCHLD handler for pid %d\n",
1988 cp->pid)); 2056 cp->pid));
1989#endif 2057#endif
1990 dead_child = cp;
1991 sig_handlers[SIGCHLD] (SIGCHLD); 2058 sig_handlers[SIGCHLD] (SIGCHLD);
1992 dead_child = NULL;
1993 } 2059 }
1994 } 2060 }
1995 else if (fdindex[active] == -1) 2061 else if (fdindex[active] == -1)
diff --git a/src/w32select.c b/src/w32select.c
index 1b10c74cfe9..6a2a840f914 100644
--- a/src/w32select.c
+++ b/src/w32select.c
@@ -74,8 +74,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
74 74
75#include <config.h> 75#include <config.h>
76#include "lisp.h" 76#include "lisp.h"
77#include "w32term.h" /* for all of the w32 includes */
78#include "w32common.h" /* os_subtype */ 77#include "w32common.h" /* os_subtype */
78#include "w32term.h" /* for all of the w32 includes */
79#include "keyboard.h" 79#include "keyboard.h"
80#include "blockinput.h" 80#include "blockinput.h"
81#include "charset.h" 81#include "charset.h"
diff --git a/src/w32term.h b/src/w32term.h
index 72fb8a76e35..83535b8faa3 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -745,6 +745,21 @@ extern int w32_system_caret_height;
745extern int w32_system_caret_x; 745extern int w32_system_caret_x;
746extern int w32_system_caret_y; 746extern int w32_system_caret_y;
747 747
748#ifdef _MSC_VER
749#ifndef EnumSystemLocales
750/* MSVC headers define these only for _WIN32_WINNT >= 0x0500. */
751typedef BOOL (CALLBACK *LOCALE_ENUMPROCA)(LPSTR);
752typedef BOOL (CALLBACK *LOCALE_ENUMPROCW)(LPWSTR);
753BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD);
754BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD)
755#ifdef UNICODE
756#define EnumSystemLocales EnumSystemLocalesW
757#else
758#define EnumSystemLocales EnumSystemLocalesA
759#endif
760#endif
761#endif
762
748#if EMACSDEBUG 763#if EMACSDEBUG
749extern const char* 764extern const char*
750w32_name_of_message (UINT msg); 765w32_name_of_message (UINT msg);
diff --git a/src/xdisp.c b/src/xdisp.c
index 679b51b0d7d..5e53168cf0e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10823,7 +10823,7 @@ clear_garbaged_frames (void)
10823 { 10823 {
10824 if (f->resized_p) 10824 if (f->resized_p)
10825 { 10825 {
10826 Fredraw_frame (frame); 10826 redraw_frame (f);
10827 f->force_flush_display_p = 1; 10827 f->force_flush_display_p = 1;
10828 } 10828 }
10829 clear_current_matrices (f); 10829 clear_current_matrices (f);
@@ -10870,8 +10870,7 @@ echo_area_display (int update_frame_p)
10870#endif /* HAVE_WINDOW_SYSTEM */ 10870#endif /* HAVE_WINDOW_SYSTEM */
10871 10871
10872 /* Redraw garbaged frames. */ 10872 /* Redraw garbaged frames. */
10873 if (frame_garbaged) 10873 clear_garbaged_frames ();
10874 clear_garbaged_frames ();
10875 10874
10876 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0) 10875 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
10877 { 10876 {
@@ -13158,8 +13157,7 @@ redisplay_internal (void)
13158 } 13157 }
13159 13158
13160 /* Clear frames marked as garbaged. */ 13159 /* Clear frames marked as garbaged. */
13161 if (frame_garbaged) 13160 clear_garbaged_frames ();
13162 clear_garbaged_frames ();
13163 13161
13164 /* Build menubar and tool-bar items. */ 13162 /* Build menubar and tool-bar items. */
13165 if (NILP (Vmemory_full)) 13163 if (NILP (Vmemory_full))
@@ -13243,8 +13241,7 @@ redisplay_internal (void)
13243 /* If window configuration was changed, frames may have been 13241 /* If window configuration was changed, frames may have been
13244 marked garbaged. Clear them or we will experience 13242 marked garbaged. Clear them or we will experience
13245 surprises wrt scrolling. */ 13243 surprises wrt scrolling. */
13246 if (frame_garbaged) 13244 clear_garbaged_frames ();
13247 clear_garbaged_frames ();
13248 } 13245 }
13249 } 13246 }
13250 else if (EQ (selected_window, minibuf_window) 13247 else if (EQ (selected_window, minibuf_window)
@@ -13267,8 +13264,7 @@ redisplay_internal (void)
13267 /* If window configuration was changed, frames may have been 13264 /* If window configuration was changed, frames may have been
13268 marked garbaged. Clear them or we will experience 13265 marked garbaged. Clear them or we will experience
13269 surprises wrt scrolling. */ 13266 surprises wrt scrolling. */
13270 if (frame_garbaged) 13267 clear_garbaged_frames ();
13271 clear_garbaged_frames ();
13272 } 13268 }
13273 13269
13274 13270
diff --git a/src/xfaces.c b/src/xfaces.c
index daf329791c1..1e27d5cc043 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -2870,6 +2870,12 @@ FRAME 0 means change the face on all frames, and change the default
2870 Lisp_Object key, val, list; 2870 Lisp_Object key, val, list;
2871 2871
2872 list = value; 2872 list = value;
2873 /* FIXME? This errs on the side of acceptance. Eg it accepts:
2874 (defface foo '((t :underline 'foo) "doc")
2875 Maybe this is intentional, maybe it isn't.
2876 Non-nil symbols other than t are not documented as being valid.
2877 Eg compare with inverse-video, which explicitly rejects them.
2878 */
2873 valid_p = 1; 2879 valid_p = 1;
2874 2880
2875 while (!NILP (CAR_SAFE(list))) 2881 while (!NILP (CAR_SAFE(list)))
@@ -5660,6 +5666,8 @@ realize_x_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE])
5660 face->underline_defaulted_p = 1; 5666 face->underline_defaulted_p = 1;
5661 face->underline_type = FACE_UNDER_LINE; 5667 face->underline_type = FACE_UNDER_LINE;
5662 5668
5669 /* FIXME? This is also not robust about checking the precise form.
5670 See comments in Finternal_set_lisp_face_attribute. */
5663 while (CONSP (underline)) 5671 while (CONSP (underline))
5664 { 5672 {
5665 Lisp_Object keyword, value; 5673 Lisp_Object keyword, value;
diff --git a/src/xrdb.c b/src/xrdb.c
index 9d056a607e4..59b0876ebf8 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -41,7 +41,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
41#ifdef HAVE_PWD_H 41#ifdef HAVE_PWD_H
42#include <pwd.h> 42#include <pwd.h>
43#endif 43#endif
44#include <sys/stat.h>
45 44
46#ifdef USE_MOTIF 45#ifdef USE_MOTIF
47/* For Vdouble_click_time. */ 46/* For Vdouble_click_time. */
@@ -50,7 +49,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50 49
51char *x_get_string_resource (XrmDatabase rdb, const char *name, 50char *x_get_string_resource (XrmDatabase rdb, const char *name,
52 const char *class); 51 const char *class);
53static int file_p (const char *filename);
54 52
55 53
56/* X file search path processing. */ 54/* X file search path processing. */
@@ -108,7 +106,7 @@ x_get_customization_string (XrmDatabase db, const char *name,
108 database associated with display. 106 database associated with display.
109 (This is x_customization_string.) 107 (This is x_customization_string.)
110 108
111 Return the expanded file name if it exists and is readable, and 109 Return the resource database if its file was read successfully, and
112 refers to %L only when the LANG environment variable is set, or 110 refers to %L only when the LANG environment variable is set, or
113 otherwise provided by X. 111 otherwise provided by X.
114 112
@@ -117,10 +115,11 @@ x_get_customization_string (XrmDatabase db, const char *name,
117 115
118 Return NULL otherwise. */ 116 Return NULL otherwise. */
119 117
120static char * 118static XrmDatabase
121magic_file_p (const char *string, ptrdiff_t string_len, const char *class, 119magic_db (const char *string, ptrdiff_t string_len, const char *class,
122 const char *escaped_suffix) 120 const char *escaped_suffix)
123{ 121{
122 XrmDatabase db;
124 char *lang = getenv ("LANG"); 123 char *lang = getenv ("LANG");
125 124
126 ptrdiff_t path_size = 100; 125 ptrdiff_t path_size = 100;
@@ -217,14 +216,9 @@ magic_file_p (const char *string, ptrdiff_t string_len, const char *class,
217 } 216 }
218 217
219 path[path_len] = '\0'; 218 path[path_len] = '\0';
220 219 db = XrmGetFileDatabase (path);
221 if (! file_p (path)) 220 xfree (path);
222 { 221 return db;
223 xfree (path);
224 return NULL;
225 }
226
227 return path;
228} 222}
229 223
230 224
@@ -258,22 +252,11 @@ gethomedir (void)
258} 252}
259 253
260 254
261static int
262file_p (const char *filename)
263{
264 struct stat status;
265
266 return (access (filename, 4) == 0 /* exists and is readable */
267 && stat (filename, &status) == 0 /* get the status */
268 && (S_ISDIR (status.st_mode)) == 0); /* not a directory */
269}
270
271
272/* Find the first element of SEARCH_PATH which exists and is readable, 255/* Find the first element of SEARCH_PATH which exists and is readable,
273 after expanding the %-escapes. Return 0 if we didn't find any, and 256 after expanding the %-escapes. Return 0 if we didn't find any, and
274 the path name of the one we found otherwise. */ 257 the path name of the one we found otherwise. */
275 258
276static char * 259static XrmDatabase
277search_magic_path (const char *search_path, const char *class, 260search_magic_path (const char *search_path, const char *class,
278 const char *escaped_suffix) 261 const char *escaped_suffix)
279{ 262{
@@ -286,18 +269,16 @@ search_magic_path (const char *search_path, const char *class,
286 269
287 if (p > s) 270 if (p > s)
288 { 271 {
289 char *path = magic_file_p (s, p - s, class, escaped_suffix); 272 XrmDatabase db = magic_db (s, p - s, class, escaped_suffix);
290 if (path) 273 if (db)
291 return path; 274 return db;
292 } 275 }
293 else if (*p == ':') 276 else if (*p == ':')
294 { 277 {
295 char *path; 278 static char const ns[] = "%N%S";
296 279 XrmDatabase db = magic_db (ns, strlen (ns), class, escaped_suffix);
297 s = "%N%S"; 280 if (db)
298 path = magic_file_p (s, strlen (s), class, escaped_suffix); 281 return db;
299 if (path)
300 return path;
301 } 282 }
302 283
303 if (*p == ':') 284 if (*p == ':')
@@ -312,21 +293,12 @@ search_magic_path (const char *search_path, const char *class,
312static XrmDatabase 293static XrmDatabase
313get_system_app (const char *class) 294get_system_app (const char *class)
314{ 295{
315 XrmDatabase db = NULL;
316 const char *path; 296 const char *path;
317 char *p;
318 297
319 path = getenv ("XFILESEARCHPATH"); 298 path = getenv ("XFILESEARCHPATH");
320 if (! path) path = PATH_X_DEFAULTS; 299 if (! path) path = PATH_X_DEFAULTS;
321 300
322 p = search_magic_path (path, class, 0); 301 return search_magic_path (path, class, 0);
323 if (p)
324 {
325 db = XrmGetFileDatabase (p);
326 xfree (p);
327 }
328
329 return db;
330} 302}
331 303
332 304
@@ -340,35 +312,40 @@ get_fallback (Display *display)
340static XrmDatabase 312static XrmDatabase
341get_user_app (const char *class) 313get_user_app (const char *class)
342{ 314{
315 XrmDatabase db = 0;
343 const char *path; 316 const char *path;
344 char *file = 0;
345 char *free_it = 0;
346 317
347 /* Check for XUSERFILESEARCHPATH. It is a path of complete file 318 /* Check for XUSERFILESEARCHPATH. It is a path of complete file
348 names, not directories. */ 319 names, not directories. */
349 if (((path = getenv ("XUSERFILESEARCHPATH")) 320 path = getenv ("XUSERFILESEARCHPATH");
350 && (file = search_magic_path (path, class, 0))) 321 if (path)
322 db = search_magic_path (path, class, 0);
351 323
324 if (! db)
325 {
352 /* Check for APPLRESDIR; it is a path of directories. In each, 326 /* Check for APPLRESDIR; it is a path of directories. In each,
353 we have to search for LANG/CLASS and then CLASS. */ 327 we have to search for LANG/CLASS and then CLASS. */
354 || ((path = getenv ("XAPPLRESDIR")) 328 path = getenv ("XAPPLRESDIR");
355 && ((file = search_magic_path (path, class, "/%L/%N")) 329 if (path)
356 || (file = search_magic_path (path, class, "/%N")))) 330 {
331 db = search_magic_path (path, class, "/%L/%N");
332 if (!db)
333 db = search_magic_path (path, class, "/%N");
334 }
335 }
357 336
337 if (! db)
338 {
358 /* Check in the home directory. This is a bit of a hack; let's 339 /* Check in the home directory. This is a bit of a hack; let's
359 hope one's home directory doesn't contain any %-escapes. */ 340 hope one's home directory doesn't contain any %-escapes. */
360 || (free_it = gethomedir (), 341 char *home = gethomedir ();
361 ((file = search_magic_path (free_it, class, "%L/%N")) 342 db = search_magic_path (home, class, "%L/%N");
362 || (file = search_magic_path (free_it, class, "%N"))))) 343 if (! db)
363 { 344 db = search_magic_path (home, class, "%N");
364 XrmDatabase db = XrmGetFileDatabase (file); 345 xfree (home);
365 xfree (file);
366 xfree (free_it);
367 return db;
368 } 346 }
369 347
370 xfree (free_it); 348 return db;
371 return NULL;
372} 349}
373 350
374 351