Mercurial > hg > xemacs-beta
annotate src/event-tty.c @ 5518:3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
2011-06-03 Aidan Kehoe <kehoea@parhasard.net>
* gnuslib.c (connect_to_unix_server):
Retry with /tmp as a directory in which to search for Unix sockets
if an attempt to connect with some other directory failed (which
may be because gnuclient and gnuserv don't share an environment
value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR
turned off).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 03 Jun 2011 18:40:57 +0100 |
parents | 308d34e9f07d |
children |
rev | line source |
---|---|
428 | 1 /* The event_stream interface for tty's. |
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1995 Sun Microsystems, Inc. | |
1268 | 4 Copyright (C) 1995, 2002, 2003 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
3735
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
428 | 9 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
3735
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
3735
diff
changeset
|
11 option) any later version. |
428 | 12 |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
3735
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 20 |
21 /* Synched up with: Not in FSF. */ | |
22 | |
23 #include <config.h> | |
24 #include "lisp.h" | |
25 | |
26 #include "device.h" | |
872 | 27 #include "console-tty-impl.h" |
428 | 28 #include "events.h" |
29 #include "frame.h" | |
30 #include "process.h" | |
31 | |
32 #include "sysproc.h" | |
33 #include "syswait.h" | |
34 #include "systime.h" | |
35 | |
36 /* Mask of bits indicating the descriptors that we wait for input on */ | |
37 extern SELECT_TYPE input_wait_mask, non_fake_input_wait_mask; | |
38 extern SELECT_TYPE process_only_mask, tty_only_mask; | |
39 | |
40 static struct event_stream *tty_event_stream; | |
41 | |
1292 | 42 #ifdef WIN32_ANY |
43 extern int mswindows_is_blocking; | |
44 #endif | |
45 | |
3735 | 46 static int last_quit_check_signal_tick_count; |
47 | |
428 | 48 |
49 /************************************************************************/ | |
50 /* timeout events */ | |
51 /************************************************************************/ | |
52 | |
53 /* The pending timers are stored in an ordered list, where the first timer | |
54 on the list is the first one to fire. Times recorded here are | |
55 absolute. */ | |
56 static struct low_level_timeout *tty_timer_queue; | |
57 | |
58 static int | |
59 emacs_tty_add_timeout (EMACS_TIME thyme) | |
60 { | |
61 return add_low_level_timeout (&tty_timer_queue, thyme); | |
62 } | |
63 | |
64 static void | |
65 emacs_tty_remove_timeout (int id) | |
66 { | |
67 remove_low_level_timeout (&tty_timer_queue, id); | |
68 } | |
69 | |
70 static void | |
440 | 71 tty_timeout_to_emacs_event (Lisp_Event *emacs_event) |
428 | 72 { |
934 | 73 /* timeout events have nil as channel */ |
74 SET_EVENT_TYPE (emacs_event, timeout_event); | |
75 SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### */ | |
1268 | 76 SET_EVENT_TIMEOUT_INTERVAL_ID (emacs_event, |
77 pop_low_level_timeout (&tty_timer_queue, 0)); | |
1204 | 78 SET_EVENT_TIMEOUT_FUNCTION (emacs_event, Qnil); |
79 SET_EVENT_TIMEOUT_OBJECT (emacs_event, Qnil); | |
428 | 80 } |
81 | |
82 | |
83 | |
84 static int | |
1268 | 85 emacs_tty_event_pending_p (int how_many) |
428 | 86 { |
3735 | 87 Lisp_Object event; |
88 int tick_count_val; | |
89 | |
90 /* Cf. the comments on emacs_Xt_event_pending_p in event-xlike-inc.c . */ | |
91 | |
1268 | 92 if (!how_many) |
428 | 93 { |
94 EMACS_TIME sometime; | |
3735 | 95 |
96 /* (1) Any pending events in the dispatch queue? */ | |
97 if (!NILP(dispatch_event_queue)) | |
98 { | |
99 return 1; | |
100 } | |
101 | |
102 /* (2) Any TTY or process input available? */ | |
103 if (poll_fds_for_input (non_fake_input_wait_mask)) | |
104 return 1; | |
105 | |
106 /* (3) Any timeout input available? */ | |
428 | 107 EMACS_GET_TIME (sometime); |
108 if (tty_timer_queue && | |
109 EMACS_TIME_EQUAL_OR_GREATER (sometime, tty_timer_queue->time)) | |
110 return 1; | |
3735 | 111 } |
112 else | |
113 { | |
114 /* HOW_MANY > 0 */ | |
115 EVENT_CHAIN_LOOP (event, dispatch_event_queue) | |
116 { | |
117 if (command_event_p (event)) | |
118 { | |
119 how_many--; | |
120 if (how_many <= 0) | |
121 return 1; | |
122 } | |
123 } | |
1268 | 124 |
428 | 125 } |
126 | |
3735 | 127 tick_count_val = quit_check_signal_tick_count; |
128 | |
129 /* Checking in_modal_loop here is a bit cargo-cultish, since its use is | |
130 specific to builds with a window system. */ | |
131 if (!in_modal_loop && | |
132 (last_quit_check_signal_tick_count != tick_count_val)) | |
133 { | |
134 last_quit_check_signal_tick_count = tick_count_val; | |
135 | |
136 /* We need to drain the entire queue now -- if we only drain part of | |
137 it, we may later on end up with events actually pending but | |
138 detect_input_pending() returning false because there wasn't | |
139 another SIGIO. */ | |
140 event_stream_drain_queue (); | |
141 | |
142 if (!how_many) | |
143 return !NILP (dispatch_event_queue); | |
144 | |
145 EVENT_CHAIN_LOOP (event, dispatch_event_queue) | |
146 { | |
147 if (command_event_p (event)) | |
148 { | |
149 how_many--; | |
150 if (how_many <= 0) | |
151 return 1; | |
152 } | |
153 } | |
154 } | |
155 | |
156 return 0; | |
428 | 157 } |
158 | |
159 static void | |
440 | 160 emacs_tty_next_event (Lisp_Event *emacs_event) |
428 | 161 { |
162 while (1) | |
163 { | |
164 int ndesc; | |
165 int i; | |
166 SELECT_TYPE temp_mask = input_wait_mask; | |
167 EMACS_TIME time_to_block; | |
168 EMACS_SELECT_TIME select_time_to_block, *pointer_to_this; | |
169 | |
3541 | 170 if (!NILP (dispatch_event_queue)) |
171 { | |
172 Lisp_Object event, event2; | |
173 event2 = wrap_event (emacs_event); | |
174 event = dequeue_dispatch_event (); | |
175 Fcopy_event (event, event2); | |
176 Fdeallocate_event (event); | |
177 return; | |
178 } | |
179 | |
428 | 180 if (!get_low_level_timeout_interval (tty_timer_queue, &time_to_block)) |
181 /* no timer events; block indefinitely */ | |
182 pointer_to_this = 0; | |
183 else | |
184 { | |
185 EMACS_TIME_TO_SELECT_TIME (time_to_block, select_time_to_block); | |
186 pointer_to_this = &select_time_to_block; | |
187 } | |
188 | |
1292 | 189 #ifdef WIN32_ANY |
190 mswindows_is_blocking = 1; | |
191 #endif | |
428 | 192 ndesc = select (MAXDESC, &temp_mask, 0, 0, pointer_to_this); |
1292 | 193 #ifdef WIN32_ANY |
194 mswindows_is_blocking = 0; | |
195 #endif | |
428 | 196 if (ndesc > 0) |
197 { | |
198 /* Look for a TTY event */ | |
199 for (i = 0; i < MAXDESC; i++) | |
200 { | |
201 /* To avoid race conditions (among other things, an infinite | |
202 loop when called from Fdiscard_input()), we must return | |
203 user events ahead of process events. */ | |
204 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &tty_only_mask)) | |
205 { | |
1204 | 206 struct console *c = find_tty_or_stream_console_from_fd (i); |
428 | 207 |
208 assert (c); | |
771 | 209 if (read_event_from_tty_or_stream_desc (emacs_event, c)) |
428 | 210 return; |
211 } | |
212 } | |
213 | |
214 /* Look for a process event */ | |
215 for (i = 0; i < MAXDESC; i++) | |
216 { | |
217 if (FD_ISSET (i, &temp_mask) && FD_ISSET (i, &process_only_mask)) | |
218 { | |
219 Lisp_Object process; | |
440 | 220 Lisp_Process *p = get_process_from_usid (FD_TO_USID(i)); |
428 | 221 |
222 assert (p); | |
793 | 223 process = wrap_process (p); |
934 | 224 set_event_type (emacs_event, process_event); |
225 /* process events have nil as channel */ | |
226 SET_EVENT_TIMESTAMP_ZERO (emacs_event); /* #### */ | |
1204 | 227 SET_EVENT_PROCESS_PROCESS (emacs_event, process); |
428 | 228 return; |
229 } | |
230 } | |
231 | |
232 /* We might get here when a fake event came through a signal. */ | |
233 /* Return a dummy event, so that a cycle of the command loop will | |
234 occur. */ | |
235 drain_signal_event_pipe (); | |
934 | 236 set_event_type (emacs_event, eval_event); |
237 /* eval events have nil as channel */ | |
1204 | 238 SET_EVENT_EVAL_FUNCTION (emacs_event, Qidentity); |
239 SET_EVENT_EVAL_OBJECT (emacs_event, Qnil); | |
428 | 240 return; |
241 } | |
242 else if (ndesc == 0) /* timeout fired */ | |
243 { | |
244 tty_timeout_to_emacs_event (emacs_event); | |
245 return; | |
246 } | |
247 } | |
248 } | |
249 | |
250 static void | |
2286 | 251 emacs_tty_format_magic_event (Lisp_Event *UNUSED (emacs_event), |
252 Lisp_Object UNUSED (pstream)) | |
788 | 253 { |
254 /* Nothing to do currently */ | |
255 } | |
256 | |
257 static int | |
2286 | 258 emacs_tty_compare_magic_event (Lisp_Event *UNUSED (e1), |
259 Lisp_Event *UNUSED (e2)) | |
788 | 260 { |
261 return 1; | |
262 } | |
263 | |
264 static Hashcode | |
2286 | 265 emacs_tty_hash_magic_event (Lisp_Event *UNUSED (e)) |
788 | 266 { |
267 return 0; | |
268 } | |
269 | |
270 static void | |
2286 | 271 emacs_tty_handle_magic_event (Lisp_Event *UNUSED (emacs_event)) |
428 | 272 { |
273 /* Nothing to do currently */ | |
274 } | |
275 | |
276 | |
277 static void | |
853 | 278 emacs_tty_select_process (Lisp_Process *process, int doin, int doerr) |
428 | 279 { |
853 | 280 int infd, errfd; |
281 | |
282 event_stream_unixoid_select_process (process, doin, doerr, &infd, &errfd); | |
428 | 283 } |
284 | |
285 static void | |
853 | 286 emacs_tty_unselect_process (Lisp_Process *process, int doin, int doerr) |
428 | 287 { |
853 | 288 int infd, errfd; |
289 | |
290 event_stream_unixoid_unselect_process (process, doin, doerr, &infd, &errfd); | |
428 | 291 } |
292 | |
293 static void | |
294 emacs_tty_select_console (struct console *con) | |
295 { | |
296 event_stream_unixoid_select_console (con); | |
297 } | |
298 | |
299 static void | |
300 emacs_tty_unselect_console (struct console *con) | |
301 { | |
302 event_stream_unixoid_unselect_console (con); | |
303 } | |
304 | |
305 static void | |
1204 | 306 emacs_tty_drain_queue (void) |
428 | 307 { |
1204 | 308 drain_tty_devices (); |
428 | 309 } |
310 | |
853 | 311 static void |
312 emacs_tty_create_io_streams (void* inhandle, void* outhandle, | |
313 void *errhandle, Lisp_Object* instream, | |
314 Lisp_Object* outstream, | |
315 Lisp_Object* errstream, | |
316 USID* in_usid, | |
317 USID* err_usid, | |
318 int flags) | |
428 | 319 { |
853 | 320 event_stream_unixoid_create_io_streams |
321 (inhandle, outhandle, errhandle, instream, outstream, | |
322 errstream, in_usid, err_usid, flags); | |
428 | 323 } |
324 | |
853 | 325 static void |
326 emacs_tty_delete_io_streams (Lisp_Object instream, | |
327 Lisp_Object outstream, | |
328 Lisp_Object errstream, | |
329 USID* in_usid, | |
330 USID* err_usid) | |
428 | 331 { |
853 | 332 event_stream_unixoid_delete_io_streams |
333 (instream, outstream, errstream, in_usid, err_usid); | |
428 | 334 } |
335 | |
336 | |
337 /************************************************************************/ | |
338 /* initialization */ | |
339 /************************************************************************/ | |
340 | |
341 void | |
342 reinit_vars_of_event_tty (void) | |
343 { | |
1204 | 344 tty_event_stream = xnew_and_zero (struct event_stream); |
428 | 345 |
346 tty_event_stream->event_pending_p = emacs_tty_event_pending_p; | |
347 tty_event_stream->next_event_cb = emacs_tty_next_event; | |
348 tty_event_stream->handle_magic_event_cb = emacs_tty_handle_magic_event; | |
788 | 349 tty_event_stream->format_magic_event_cb = emacs_tty_format_magic_event; |
350 tty_event_stream->compare_magic_event_cb= emacs_tty_compare_magic_event; | |
351 tty_event_stream->hash_magic_event_cb = emacs_tty_hash_magic_event; | |
428 | 352 tty_event_stream->add_timeout_cb = emacs_tty_add_timeout; |
353 tty_event_stream->remove_timeout_cb = emacs_tty_remove_timeout; | |
354 tty_event_stream->select_console_cb = emacs_tty_select_console; | |
355 tty_event_stream->unselect_console_cb = emacs_tty_unselect_console; | |
356 tty_event_stream->select_process_cb = emacs_tty_select_process; | |
357 tty_event_stream->unselect_process_cb = emacs_tty_unselect_process; | |
1204 | 358 tty_event_stream->drain_queue_cb = emacs_tty_drain_queue; |
853 | 359 tty_event_stream->create_io_streams_cb = emacs_tty_create_io_streams; |
360 tty_event_stream->delete_io_streams_cb = emacs_tty_delete_io_streams; | |
3735 | 361 |
362 last_quit_check_signal_tick_count = 0; | |
428 | 363 } |
364 | |
365 void | |
366 vars_of_event_tty (void) | |
367 { | |
368 } | |
369 | |
370 void | |
371 init_event_tty_late (void) | |
372 { | |
373 event_stream = tty_event_stream; | |
374 } |