Mercurial > hg > xemacs-beta
comparison src/process.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 8de8e3f6228a |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* Asynchronous subprocess control for XEmacs. | |
2 Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995 | |
3 Free Software Foundation, Inc. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
5 Copyright (C) 1995, 1996 Ben Wing. | |
6 | |
7 This file is part of XEmacs. | |
8 | |
9 XEmacs is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 2, or (at your option) any | |
12 later version. | |
13 | |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with XEmacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 Boston, MA 02111-1307, USA. */ | |
23 | |
24 /* This file has been Mule-ized except for `start-process-internal', | |
25 `open-network-stream-internal' and `open-multicast-group-internal'. */ | |
26 | |
27 /* This file has been split into process.c and process-unix.c by | |
28 Kirill M. Katsnelson <kkm@kis.ru>, so please bash him and not | |
29 the original author(s) */ | |
30 | |
31 #include <config.h> | |
32 | |
33 #if !defined (NO_SUBPROCESSES) | |
34 | |
35 /* The entire file is within this conditional */ | |
36 | |
37 #include "lisp.h" | |
38 | |
39 #include "buffer.h" | |
40 #include "commands.h" | |
41 #include "events.h" | |
42 #include "frame.h" | |
43 #include "hash.h" | |
44 #include "insdel.h" | |
45 #include "lstream.h" | |
46 #include "opaque.h" | |
47 #include "process.h" | |
48 #include "procimpl.h" | |
49 #include "window.h" | |
50 #ifdef FILE_CODING | |
51 #include "file-coding.h" | |
52 #endif | |
53 | |
54 #include "sysfile.h" | |
55 #include "sysproc.h" | |
56 #include "systime.h" | |
57 #include "syssignal.h" /* Always include before systty.h */ | |
58 #include "systty.h" | |
59 #include "syswait.h" | |
60 | |
61 Lisp_Object Qprocessp; | |
62 | |
63 /* Process methods */ | |
64 struct process_methods the_process_methods; | |
65 | |
66 /* a process object is a network connection when its pid field a cons | |
67 (name of name of port we are connected to . foreign host name) */ | |
68 | |
69 /* Valid values of process->status_symbol */ | |
70 Lisp_Object Qrun, Qstop; | |
71 /* Qrun => Qopen, Qexit => Qclosed for "network connection" processes */ | |
72 Lisp_Object Qopen, Qclosed; | |
73 /* Protocol families */ | |
74 Lisp_Object Qtcp, Qudp; | |
75 | |
76 #ifdef HAVE_MULTICAST | |
77 Lisp_Object Qmulticast; /* Will be used for occasional warnings */ | |
78 #endif | |
79 | |
80 /* t means use pty, nil means use a pipe, | |
81 maybe other values to come. */ | |
82 Lisp_Object Vprocess_connection_type; | |
83 | |
84 /* Read comments to DEFVAR of this */ | |
85 int windowed_process_io; | |
86 | |
87 #ifdef PROCESS_IO_BLOCKING | |
88 /* List of port numbers or port names to set a blocking I/O mode. | |
89 Nil means set a non-blocking I/O mode [default]. */ | |
90 Lisp_Object network_stream_blocking_port_list; | |
91 #endif /* PROCESS_IO_BLOCKING */ | |
92 | |
93 /* Number of events of change of status of a process. */ | |
94 volatile int process_tick; | |
95 | |
96 /* Number of events for which the user or sentinel has been notified. */ | |
97 static int update_tick; | |
98 | |
99 /* Nonzero means delete a process right away if it exits. */ | |
100 int delete_exited_processes; | |
101 | |
102 /* Hash table which maps USIDs as returned by create_stream_pair_cb to | |
103 process objects. Processes are not GC-protected through this! */ | |
104 struct hash_table *usid_to_process; | |
105 | |
106 /* List of process objects. */ | |
107 Lisp_Object Vprocess_list; | |
108 | |
109 extern Lisp_Object Vlisp_EXEC_SUFFIXES; | |
110 | |
111 | |
112 | |
113 static Lisp_Object | |
114 mark_process (Lisp_Object obj) | |
115 { | |
116 struct Lisp_Process *proc = XPROCESS (obj); | |
117 MAYBE_PROCMETH (mark_process_data, (proc)); | |
118 mark_object (proc->name); | |
119 mark_object (proc->command); | |
120 mark_object (proc->filter); | |
121 mark_object (proc->sentinel); | |
122 mark_object (proc->buffer); | |
123 mark_object (proc->mark); | |
124 mark_object (proc->pid); | |
125 mark_object (proc->pipe_instream); | |
126 mark_object (proc->pipe_outstream); | |
127 #ifdef FILE_CODING | |
128 mark_object (proc->coding_instream); | |
129 mark_object (proc->coding_outstream); | |
130 #endif | |
131 return proc->status_symbol; | |
132 } | |
133 | |
134 static void | |
135 print_process (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
136 { | |
137 struct Lisp_Process *proc = XPROCESS (obj); | |
138 | |
139 if (print_readably) | |
140 error ("printing unreadable object #<process %s>", | |
141 XSTRING_DATA (proc->name)); | |
142 | |
143 if (!escapeflag) | |
144 { | |
145 print_internal (proc->name, printcharfun, 0); | |
146 } | |
147 else | |
148 { | |
149 int netp = network_connection_p (obj); | |
150 write_c_string ((netp ? GETTEXT ("#<network connection ") : | |
151 GETTEXT ("#<process ")), printcharfun); | |
152 print_internal (proc->name, printcharfun, 1); | |
153 write_c_string ((netp ? " " : " pid "), printcharfun); | |
154 print_internal (proc->pid, printcharfun, 1); | |
155 write_c_string (" state:", printcharfun); | |
156 print_internal (proc->status_symbol, printcharfun, 1); | |
157 MAYBE_PROCMETH (print_process_data, (proc, printcharfun)); | |
158 write_c_string (">", printcharfun); | |
159 } | |
160 } | |
161 | |
162 #ifdef HAVE_WINDOW_SYSTEM | |
163 extern void debug_process_finalization (struct Lisp_Process *p); | |
164 #endif /* HAVE_WINDOW_SYSTEM */ | |
165 | |
166 static void | |
167 finalize_process (void *header, int for_disksave) | |
168 { | |
169 /* #### this probably needs to be tied into the tty event loop */ | |
170 /* #### when there is one */ | |
171 struct Lisp_Process *p = (struct Lisp_Process *) header; | |
172 #ifdef HAVE_WINDOW_SYSTEM | |
173 if (!for_disksave) | |
174 { | |
175 debug_process_finalization (p); | |
176 } | |
177 #endif /* HAVE_WINDOW_SYSTEM */ | |
178 | |
179 if (p->process_data) | |
180 { | |
181 MAYBE_PROCMETH (finalize_process_data, (p, for_disksave)); | |
182 if (!for_disksave) | |
183 xfree (p->process_data); | |
184 } | |
185 } | |
186 | |
187 DEFINE_LRECORD_IMPLEMENTATION ("process", process, | |
188 mark_process, print_process, finalize_process, | |
189 0, 0, 0, struct Lisp_Process); | |
190 | |
191 /************************************************************************/ | |
192 /* basic process accessors */ | |
193 /************************************************************************/ | |
194 | |
195 /* Under FILE_CODING, this function returns low-level streams, connected | |
196 directly to the child process, rather than en/decoding FILE_CODING | |
197 streams */ | |
198 void | |
199 get_process_streams (struct Lisp_Process *p, | |
200 Lisp_Object *instr, Lisp_Object *outstr) | |
201 { | |
202 assert (p); | |
203 assert (NILP (p->pipe_instream) || LSTREAMP(p->pipe_instream)); | |
204 assert (NILP (p->pipe_outstream) || LSTREAMP(p->pipe_outstream)); | |
205 *instr = p->pipe_instream; | |
206 *outstr = p->pipe_outstream; | |
207 } | |
208 | |
209 struct Lisp_Process * | |
210 get_process_from_usid (USID usid) | |
211 { | |
212 CONST void *vval; | |
213 | |
214 assert (usid != USID_ERROR && usid != USID_DONTHASH); | |
215 | |
216 if (gethash ((CONST void*)usid, usid_to_process, &vval)) | |
217 { | |
218 Lisp_Object proc; | |
219 CVOID_TO_LISP (proc, vval); | |
220 return XPROCESS (proc); | |
221 } | |
222 else | |
223 return 0; | |
224 } | |
225 | |
226 int | |
227 get_process_selected_p (struct Lisp_Process *p) | |
228 { | |
229 return p->selected; | |
230 } | |
231 | |
232 void | |
233 set_process_selected_p (struct Lisp_Process *p, int selected_p) | |
234 { | |
235 p->selected = !!selected_p; | |
236 } | |
237 | |
238 int | |
239 connected_via_filedesc_p (struct Lisp_Process *p) | |
240 { | |
241 return MAYBE_INT_PROCMETH (tooltalk_connection_p, (p)); | |
242 } | |
243 | |
244 #ifdef HAVE_SOCKETS | |
245 int | |
246 network_connection_p (Lisp_Object process) | |
247 { | |
248 return CONSP (XPROCESS (process)->pid); | |
249 } | |
250 #endif | |
251 | |
252 DEFUN ("processp", Fprocessp, 1, 1, 0, /* | |
253 Return t if OBJECT is a process. | |
254 */ | |
255 (obj)) | |
256 { | |
257 return PROCESSP (obj) ? Qt : Qnil; | |
258 } | |
259 | |
260 DEFUN ("process-list", Fprocess_list, 0, 0, 0, /* | |
261 Return a list of all processes. | |
262 */ | |
263 ()) | |
264 { | |
265 return Fcopy_sequence (Vprocess_list); | |
266 } | |
267 | |
268 DEFUN ("get-process", Fget_process, 1, 1, 0, /* | |
269 Return the process named NAME, or nil if there is none. | |
270 */ | |
271 (name)) | |
272 { | |
273 Lisp_Object tail; | |
274 | |
275 if (PROCESSP (name)) | |
276 return name; | |
277 | |
278 if (!gc_in_progress) | |
279 /* this only gets called during GC when emacs is going away as a result | |
280 of a signal or crash. */ | |
281 CHECK_STRING (name); | |
282 | |
283 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail)) | |
284 { | |
285 Lisp_Object proc = XCAR (tail); | |
286 QUIT; | |
287 if (internal_equal (name, XPROCESS (proc)->name, 0)) | |
288 return XCAR (tail); | |
289 } | |
290 return Qnil; | |
291 } | |
292 | |
293 DEFUN ("get-buffer-process", Fget_buffer_process, 1, 1, 0, /* | |
294 Return the (or, a) process associated with BUFFER. | |
295 BUFFER may be a buffer or the name of one. | |
296 */ | |
297 (name)) | |
298 { | |
299 Lisp_Object buf, tail, proc; | |
300 | |
301 if (NILP (name)) return Qnil; | |
302 buf = Fget_buffer (name); | |
303 if (NILP (buf)) return Qnil; | |
304 | |
305 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail)) | |
306 { | |
307 /* jwz: do not quit here - it isn't necessary, as there is no way for | |
308 Vprocess_list to get circular or overwhelmingly long, and this | |
309 function is called from layout_mode_element under redisplay. */ | |
310 /* QUIT; */ | |
311 proc = XCAR (tail); | |
312 if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf)) | |
313 return proc; | |
314 } | |
315 return Qnil; | |
316 } | |
317 | |
318 /* This is how commands for the user decode process arguments. It | |
319 accepts a process, a process name, a buffer, a buffer name, or nil. | |
320 Buffers denote the first process in the buffer, and nil denotes the | |
321 current buffer. */ | |
322 | |
323 static Lisp_Object | |
324 get_process (Lisp_Object name) | |
325 { | |
326 Lisp_Object proc, obj; | |
327 | |
328 #ifdef I18N3 | |
329 /* #### Look more closely into translating process names. */ | |
330 #endif | |
331 | |
332 /* This may be called during a GC from process_send_signal() from | |
333 kill_buffer_processes() if emacs decides to abort(). */ | |
334 if (PROCESSP (name)) | |
335 return name; | |
336 | |
337 if (STRINGP (name)) | |
338 { | |
339 obj = Fget_process (name); | |
340 if (NILP (obj)) | |
341 obj = Fget_buffer (name); | |
342 if (NILP (obj)) | |
343 error ("Process %s does not exist", XSTRING_DATA (name)); | |
344 } | |
345 else if (NILP (name)) | |
346 obj = Fcurrent_buffer (); | |
347 else | |
348 obj = name; | |
349 | |
350 /* Now obj should be either a buffer object or a process object. | |
351 */ | |
352 if (BUFFERP (obj)) | |
353 { | |
354 proc = Fget_buffer_process (obj); | |
355 if (NILP (proc)) | |
356 error ("Buffer %s has no process", XSTRING_DATA (XBUFFER(obj)->name)); | |
357 } | |
358 else | |
359 { | |
360 /* #### This was commented out. Although, simple | |
361 (kill-process 7 "qqq") resulted in a fatal error. - kkm */ | |
362 CHECK_PROCESS (obj); | |
363 proc = obj; | |
364 } | |
365 return proc; | |
366 } | |
367 | |
368 DEFUN ("process-id", Fprocess_id, 1, 1, 0, /* | |
369 Return the process id of PROCESS. | |
370 This is the pid of the Unix process which PROCESS uses or talks to. | |
371 For a network connection, this value is a cons of | |
372 (foreign-network-port . foreign-host-name). | |
373 */ | |
374 (proc)) | |
375 { | |
376 Lisp_Object pid; | |
377 CHECK_PROCESS (proc); | |
378 | |
379 pid = XPROCESS (proc)->pid; | |
380 if (network_connection_p (proc)) | |
381 /* return Qnil; */ | |
382 return Fcons (Fcar (pid), Fcdr (pid)); | |
383 else | |
384 return pid; | |
385 } | |
386 | |
387 DEFUN ("process-name", Fprocess_name, 1, 1, 0, /* | |
388 Return the name of PROCESS, as a string. | |
389 This is the name of the program invoked in PROCESS, | |
390 possibly modified to make it unique among process names. | |
391 */ | |
392 (proc)) | |
393 { | |
394 CHECK_PROCESS (proc); | |
395 return XPROCESS (proc)->name; | |
396 } | |
397 | |
398 DEFUN ("process-command", Fprocess_command, 1, 1, 0, /* | |
399 Return the command that was executed to start PROCESS. | |
400 This is a list of strings, the first string being the program executed | |
401 and the rest of the strings being the arguments given to it. | |
402 */ | |
403 (proc)) | |
404 { | |
405 CHECK_PROCESS (proc); | |
406 return XPROCESS (proc)->command; | |
407 } | |
408 | |
409 | |
410 /************************************************************************/ | |
411 /* creating a process */ | |
412 /************************************************************************/ | |
413 | |
414 Lisp_Object | |
415 make_process_internal (Lisp_Object name) | |
416 { | |
417 Lisp_Object val, name1; | |
418 int i; | |
419 struct Lisp_Process *p = | |
420 alloc_lcrecord_type (struct Lisp_Process, &lrecord_process); | |
421 | |
422 /* If name is already in use, modify it until it is unused. */ | |
423 name1 = name; | |
424 for (i = 1; ; i++) | |
425 { | |
426 char suffix[10]; | |
427 Lisp_Object tem = Fget_process (name1); | |
428 if (NILP (tem)) | |
429 break; | |
430 sprintf (suffix, "<%d>", i); | |
431 name1 = concat2 (name, build_string (suffix)); | |
432 } | |
433 name = name1; | |
434 p->name = name; | |
435 | |
436 p->command = Qnil; | |
437 p->filter = Qnil; | |
438 p->sentinel = Qnil; | |
439 p->buffer = Qnil; | |
440 p->mark = Fmake_marker (); | |
441 p->pid = Qnil; | |
442 p->status_symbol = Qrun; | |
443 p->exit_code = 0; | |
444 p->core_dumped = 0; | |
445 p->filter_does_read = 0; | |
446 p->kill_without_query = 0; | |
447 p->selected = 0; | |
448 p->tick = 0; | |
449 p->update_tick = 0; | |
450 p->pipe_instream = Qnil; | |
451 p->pipe_outstream = Qnil; | |
452 #ifdef FILE_CODING | |
453 p->coding_instream = Qnil; | |
454 p->coding_outstream = Qnil; | |
455 #endif | |
456 | |
457 p->process_data = 0; | |
458 MAYBE_PROCMETH (alloc_process_data, (p)); | |
459 | |
460 XSETPROCESS (val, p); | |
461 | |
462 Vprocess_list = Fcons (val, Vprocess_list); | |
463 return val; | |
464 } | |
465 | |
466 void | |
467 init_process_io_handles (struct Lisp_Process *p, void* in, void* out, int flags) | |
468 { | |
469 USID usid = event_stream_create_stream_pair (in, out, | |
470 &p->pipe_instream, &p->pipe_outstream, | |
471 flags); | |
472 | |
473 if (usid == USID_ERROR) | |
474 report_file_error ("Setting up communication with subprocess", Qnil); | |
475 | |
476 if (usid != USID_DONTHASH) | |
477 { | |
478 Lisp_Object proc = Qnil; | |
479 XSETPROCESS (proc, p); | |
480 puthash ((CONST void*)usid, LISP_TO_VOID (proc), usid_to_process); | |
481 } | |
482 | |
483 MAYBE_PROCMETH (init_process_io_handles, (p, in, out, flags)); | |
484 | |
485 #ifdef FILE_CODING | |
486 p->coding_instream = make_decoding_input_stream | |
487 (XLSTREAM (p->pipe_instream), | |
488 Fget_coding_system (Vcoding_system_for_read)); | |
489 Lstream_set_character_mode (XLSTREAM (p->coding_instream)); | |
490 p->coding_outstream = make_encoding_output_stream | |
491 (XLSTREAM (p->pipe_outstream), | |
492 Fget_coding_system (Vcoding_system_for_write)); | |
493 /* CODE_CNTL (&out_state[outchannel]) |= CC_END; !!#### | |
494 What's going on here? */ | |
495 #endif /* FILE_CODING */ | |
496 } | |
497 | |
498 static void | |
499 create_process (Lisp_Object process, Lisp_Object *argv, int nargv, | |
500 Lisp_Object program, Lisp_Object cur_dir) | |
501 { | |
502 struct Lisp_Process *p = XPROCESS (process); | |
503 int pid; | |
504 | |
505 /* *_create_process may change status_symbol, if the process | |
506 is a kind of "fire-and-forget" (no I/O, unwaitable) */ | |
507 p->status_symbol = Qrun; | |
508 p->exit_code = 0; | |
509 | |
510 pid = PROCMETH (create_process, (p, argv, nargv, program, cur_dir)); | |
511 | |
512 p->pid = make_int (pid); | |
513 if (!NILP(p->pipe_instream)) | |
514 event_stream_select_process (p); | |
515 } | |
516 | |
517 /* This function is the unwind_protect form for Fstart_process_internal. If | |
518 PROC doesn't have its pid set, then we know someone has signalled | |
519 an error and the process wasn't started successfully, so we should | |
520 remove it from the process list. */ | |
521 static void remove_process (Lisp_Object proc); | |
522 static Lisp_Object | |
523 start_process_unwind (Lisp_Object proc) | |
524 { | |
525 /* Was PROC started successfully? */ | |
526 if (EQ (XPROCESS (proc)->pid, Qnil)) | |
527 remove_process (proc); | |
528 return Qnil; | |
529 } | |
530 | |
531 DEFUN ("start-process-internal", Fstart_process_internal, 3, MANY, 0, /* | |
532 Start a program in a subprocess. Return the process object for it. | |
533 Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS | |
534 NAME is name for process. It is modified if necessary to make it unique. | |
535 BUFFER is the buffer or (buffer-name) to associate with the process. | |
536 Process output goes at end of that buffer, unless you specify | |
537 an output stream or filter function to handle the output. | |
538 BUFFER may be also nil, meaning that this process is not associated | |
539 with any buffer | |
540 Third arg is program file name. It is searched for as in the shell. | |
541 Remaining arguments are strings to give program as arguments. | |
542 INCODE and OUTCODE specify the coding-system objects used in input/output | |
543 from/to the process. | |
544 */ | |
545 (int nargs, Lisp_Object *args)) | |
546 { | |
547 /* This function can call lisp */ | |
548 /* !!#### This function has not been Mule-ized */ | |
549 Lisp_Object buffer, name, program, proc, current_dir; | |
550 Lisp_Object tem; | |
551 int speccount = specpdl_depth (); | |
552 struct gcpro gcpro1, gcpro2, gcpro3; | |
553 | |
554 name = args[0]; | |
555 buffer = args[1]; | |
556 program = args[2]; | |
557 current_dir = Qnil; | |
558 | |
559 /* Protect against various file handlers doing GCs below. */ | |
560 GCPRO3 (buffer, program, current_dir); | |
561 | |
562 if (!NILP (buffer)) | |
563 buffer = Fget_buffer_create (buffer); | |
564 | |
565 CHECK_STRING (name); | |
566 CHECK_STRING (program); | |
567 | |
568 /* Make sure that the child will be able to chdir to the current | |
569 buffer's current directory, or its unhandled equivalent. We | |
570 can't just have the child check for an error when it does the | |
571 chdir, since it's in a vfork. | |
572 | |
573 Note: these assignments and calls are like this in order to insure | |
574 "caller protects args" GC semantics. */ | |
575 current_dir = current_buffer->directory; | |
576 current_dir = Funhandled_file_name_directory (current_dir); | |
577 current_dir = expand_and_dir_to_file (current_dir, Qnil); | |
578 | |
579 #if 0 /* This loser breaks ange-ftp */ | |
580 /* dmoore - if you re-enable this code, you have to gcprotect | |
581 current_buffer through the above calls. */ | |
582 if (NILP (Ffile_accessible_directory_p (current_dir))) | |
583 report_file_error ("Setting current directory", | |
584 list1 (current_buffer->directory)); | |
585 #endif /* 0 */ | |
586 | |
587 /* If program file name is not absolute, search our path for it */ | |
588 if (!IS_DIRECTORY_SEP (XSTRING_BYTE (program, 0)) | |
589 && !(XSTRING_LENGTH (program) > 1 | |
590 && IS_DEVICE_SEP (XSTRING_BYTE (program, 1)))) | |
591 { | |
592 struct gcpro ngcpro1; | |
593 | |
594 tem = Qnil; | |
595 NGCPRO1 (tem); | |
596 locate_file (Vexec_path, program, Vlisp_EXEC_SUFFIXES, &tem, X_OK); | |
597 if (NILP (tem)) | |
598 report_file_error ("Searching for program", list1 (program)); | |
599 program = Fexpand_file_name (tem, Qnil); | |
600 NUNGCPRO; | |
601 } | |
602 else | |
603 { | |
604 if (!NILP (Ffile_directory_p (program))) | |
605 error ("Specified program for new process is a directory"); | |
606 } | |
607 | |
608 proc = make_process_internal (name); | |
609 | |
610 XPROCESS (proc)->buffer = buffer; | |
611 XPROCESS (proc)->command = Flist (nargs - 2, | |
612 args + 2); | |
613 | |
614 /* Make the process marker point into the process buffer (if any). */ | |
615 if (!NILP (buffer)) | |
616 Fset_marker (XPROCESS (proc)->mark, | |
617 make_int (BUF_ZV (XBUFFER (buffer))), buffer); | |
618 | |
619 /* If an error occurs and we can't start the process, we want to | |
620 remove it from the process list. This means that each error | |
621 check in create_process doesn't need to call remove_process | |
622 itself; it's all taken care of here. */ | |
623 record_unwind_protect (start_process_unwind, proc); | |
624 | |
625 create_process (proc, args + 3, nargs - 3, program, current_dir); | |
626 | |
627 UNGCPRO; | |
628 return unbind_to (speccount, proc); | |
629 } | |
630 | |
631 | |
632 #ifdef HAVE_SOCKETS | |
633 | |
634 | |
635 /* #### The network support is fairly synthetical. What we actually | |
636 need is a single function, which supports all datagram, stream and | |
637 packet stream connections, arbitrary protocol families should they | |
638 be supported by the target system, multicast groups, in both data | |
639 and control rooted/nonrooted flavors, service quality etc whatever | |
640 is supported by the underlying network. | |
641 | |
642 It must accept a property list describing the connection. The current | |
643 functions must then go to lisp and provide a suitable list for the | |
644 generalized connection function. | |
645 | |
646 Both UNIX and Win32 support BSD sockets, and there are many extensions | |
647 available (Sockets 2 spec). | |
648 | |
649 A todo is define a consistent set of properties abstracting a | |
650 network connection. -kkm | |
651 */ | |
652 | |
653 | |
654 /* open a TCP network connection to a given HOST/SERVICE. Treated | |
655 exactly like a normal process when reading and writing. Only | |
656 differences are in status display and process deletion. A network | |
657 connection has no PID; you cannot signal it. All you can do is | |
658 deactivate and close it via delete-process */ | |
659 | |
660 DEFUN ("open-network-stream-internal", Fopen_network_stream_internal, 4, 5, 0, /* | |
661 Open a TCP connection for a service to a host. | |
662 Return a subprocess-object to represent the connection. | |
663 Input and output work as for subprocesses; `delete-process' closes it. | |
664 | |
665 NAME is name for process. It is modified if necessary to make it unique. | |
666 BUFFER is the buffer (or buffer-name) to associate with the process. | |
667 Process output goes at end of that buffer, unless you specify | |
668 an output stream or filter function to handle the output. | |
669 BUFFER may also be nil, meaning that this process is not associated | |
670 with any buffer. | |
671 Third arg is name of the host to connect to, or its IP address. | |
672 Fourth arg SERVICE is name of the service desired, or an integer | |
673 specifying a port number to connect to. | |
674 Fifth argument PROTOCOL is a network protocol. Currently 'tcp | |
675 (Transmission Control Protocol) and 'udp (User Datagram Protocol) are | |
676 supported. When omitted, 'tcp is assumed. | |
677 | |
678 Ouput via `process-send-string' and input via buffer or filter (see | |
679 `set-process-filter') are stream-oriented. That means UDP datagrams are | |
680 not guaranteed to be sent and received in discrete packets. (But small | |
681 datagrams around 500 bytes that are not truncated by `process-send-string' | |
682 are usually fine.) Note further that UDP protocol does not guard against | |
683 lost packets. | |
684 */ | |
685 (name, buffer, host, service, protocol)) | |
686 { | |
687 /* !!#### This function has not been Mule-ized */ | |
688 /* This function can GC */ | |
689 Lisp_Object proc = Qnil; | |
690 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, ngcpro1; | |
691 void *inch, *outch; | |
692 | |
693 GCPRO5 (name, buffer, host, service, protocol); | |
694 CHECK_STRING (name); | |
695 | |
696 if (NILP(protocol)) | |
697 protocol = Qtcp; | |
698 else | |
699 CHECK_SYMBOL (protocol); | |
700 | |
701 /* Since this code is inside HAVE_SOCKETS, existence of | |
702 open_network_stream is mandatory */ | |
703 PROCMETH (open_network_stream, (name, host, service, protocol, | |
704 &inch, &outch)); | |
705 | |
706 if (!NILP (buffer)) | |
707 buffer = Fget_buffer_create (buffer); | |
708 proc = make_process_internal (name); | |
709 NGCPRO1 (proc); | |
710 | |
711 XPROCESS (proc)->pid = Fcons (service, host); | |
712 XPROCESS (proc)->buffer = buffer; | |
713 init_process_io_handles (XPROCESS (proc), (void*)inch, (void*)outch, | |
714 STREAM_NETWORK_CONNECTION); | |
715 | |
716 event_stream_select_process (XPROCESS (proc)); | |
717 | |
718 UNGCPRO; | |
719 NUNGCPRO; | |
720 return proc; | |
721 } | |
722 | |
723 #ifdef HAVE_MULTICAST | |
724 | |
725 DEFUN ("open-multicast-group-internal", Fopen_multicast_group_internal, 5, 5, 0, /* | |
726 Open a multicast connection on the specified dest/port/ttl. | |
727 Return a subprocess-object to represent the connection. | |
728 Input and output work as for subprocesses; `delete-process' closes it. | |
729 | |
730 NAME is name for process. It is modified if necessary to make it unique. | |
731 BUFFER is the buffer (or buffer-name) to associate with the process. | |
732 Process output goes at end of that buffer, unless you specify | |
733 an output stream or filter function to handle the output. | |
734 BUFFER may also be nil, meaning that this process is not associated | |
735 with any buffer. | |
736 Third, fourth and fifth args are the multicast destination group, port and ttl. | |
737 dest must be an internet address between 224.0.0.0 and 239.255.255.255 | |
738 port is a communication port like in traditional unicast | |
739 ttl is the time-to-live (15 for site, 63 for region and 127 for world) | |
740 */ | |
741 (name, buffer, dest, port, ttl)) | |
742 { | |
743 /* !!#### This function has not been Mule-ized */ | |
744 /* This function can GC */ | |
745 Lisp_Object proc = Qnil; | |
746 struct gcpro gcpro1; | |
747 void *inch, *outch; | |
748 | |
749 CHECK_STRING (name); | |
750 | |
751 /* Since this code is inside HAVE_MULTICAST, existence of | |
752 open_network_stream is mandatory */ | |
753 PROCMETH (open_multicast_group, (name, dest, port, ttl, | |
754 &inch, &outch)); | |
755 | |
756 if (!NILP (buffer)) | |
757 buffer = Fget_buffer_create (buffer); | |
758 | |
759 proc = make_process_internal (name); | |
760 GCPRO1 (proc); | |
761 | |
762 XPROCESS (proc)->pid = Fcons (port, dest); | |
763 XPROCESS (proc)->buffer = buffer; | |
764 init_process_io_handles (XPROCESS (proc), (void*)inch, (void*)outch, | |
765 STREAM_NETWORK_CONNECTION); | |
766 | |
767 event_stream_select_process (XPROCESS (proc)); | |
768 | |
769 UNGCPRO; | |
770 return proc; | |
771 } | |
772 #endif /* HAVE_MULTICAST */ | |
773 | |
774 #endif /* HAVE_SOCKETS */ | |
775 | |
776 Lisp_Object | |
777 canonicalize_host_name (Lisp_Object host) | |
778 { | |
779 return PROCMETH_OR_GIVEN (canonicalize_host_name, (host), host); | |
780 } | |
781 | |
782 | |
783 DEFUN ("set-process-window-size", Fset_process_window_size, 3, 3, 0, /* | |
784 Tell PROCESS that it has logical window size HEIGHT and WIDTH. | |
785 */ | |
786 (proc, height, width)) | |
787 { | |
788 CHECK_PROCESS (proc); | |
789 CHECK_NATNUM (height); | |
790 CHECK_NATNUM (width); | |
791 return | |
792 MAYBE_INT_PROCMETH (set_window_size, (XPROCESS (proc), XINT (height), XINT (width))) <= 0 | |
793 ? Qnil : Qt; | |
794 } | |
795 | |
796 | |
797 /************************************************************************/ | |
798 /* Process I/O */ | |
799 /************************************************************************/ | |
800 | |
801 /* Read pending output from the process channel, | |
802 starting with our buffered-ahead character if we have one. | |
803 Yield number of characters read. | |
804 | |
805 This function reads at most 1024 bytes. | |
806 If you want to read all available subprocess output, | |
807 you must call it repeatedly until it returns zero. */ | |
808 | |
809 Charcount | |
810 read_process_output (Lisp_Object proc) | |
811 { | |
812 /* This function can GC */ | |
813 Bytecount nbytes, nchars; | |
814 Bufbyte chars[1024]; | |
815 Lisp_Object outstream; | |
816 struct Lisp_Process *p = XPROCESS (proc); | |
817 | |
818 /* If there is a lot of output from the subprocess, the loop in | |
819 execute_internal_event() might call read_process_output() more | |
820 than once. If the filter that was executed from one of these | |
821 calls set the filter to t, we have to stop now. Return -1 rather | |
822 than 0 so execute_internal_event() doesn't close the process. | |
823 Really, the loop in execute_internal_event() should check itself | |
824 for a process-filter change, like in status_notify(); but the | |
825 struct Lisp_Process is not exported outside of this file. */ | |
826 if (NILP(p->pipe_instream)) | |
827 return -1; /* already closed */ | |
828 | |
829 if (!NILP (p->filter) && (p->filter_does_read)) | |
830 { | |
831 Lisp_Object filter_result; | |
832 | |
833 /* Some weird FSFmacs crap here with | |
834 Vdeactivate_mark and current_buffer->keymap */ | |
835 running_asynch_code = 1; | |
836 filter_result = call2_trapping_errors ("Error in process filter", | |
837 p->filter, proc, Qnil); | |
838 running_asynch_code = 0; | |
839 restore_match_data (); | |
840 CHECK_INT (filter_result); | |
841 return XINT (filter_result); | |
842 } | |
843 | |
844 nbytes = Lstream_read (XLSTREAM (DATA_INSTREAM(p)), chars, sizeof (chars)); | |
845 if (nbytes <= 0) return nbytes; | |
846 | |
847 nchars = bytecount_to_charcount (chars, nbytes); | |
848 outstream = p->filter; | |
849 if (!NILP (outstream)) | |
850 { | |
851 /* We used to bind inhibit-quit to t here, but | |
852 call2_trapping_errors() does that for us. */ | |
853 running_asynch_code = 1; | |
854 call2_trapping_errors ("Error in process filter", | |
855 outstream, proc, make_string (chars, nbytes)); | |
856 running_asynch_code = 0; | |
857 restore_match_data (); | |
858 return nchars; | |
859 } | |
860 | |
861 /* If no filter, write into buffer if it isn't dead. */ | |
862 if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) | |
863 { | |
864 Lisp_Object old_read_only = Qnil; | |
865 Bufpos old_point; | |
866 Bufpos old_begv; | |
867 Bufpos old_zv; | |
868 int old_zmacs_region_stays = zmacs_region_stays; | |
869 struct gcpro gcpro1, gcpro2; | |
870 struct buffer *buf = XBUFFER (p->buffer); | |
871 | |
872 GCPRO2 (proc, old_read_only); | |
873 | |
874 old_point = BUF_PT (buf); | |
875 old_begv = BUF_BEGV (buf); | |
876 old_zv = BUF_ZV (buf); | |
877 old_read_only = buf->read_only; | |
878 buf->read_only = Qnil; | |
879 | |
880 /* Insert new output into buffer | |
881 at the current end-of-output marker, | |
882 thus preserving logical ordering of input and output. */ | |
883 if (XMARKER (p->mark)->buffer) | |
884 BUF_SET_PT (buf, | |
885 bufpos_clip_to_bounds (old_begv, marker_position (p->mark), | |
886 old_zv)); | |
887 else | |
888 BUF_SET_PT (buf, old_zv); | |
889 | |
890 /* If the output marker is outside of the visible region, save | |
891 the restriction and widen. */ | |
892 if (! (BUF_BEGV (buf) <= BUF_PT (buf) && | |
893 BUF_PT (buf) <= BUF_ZV (buf))) | |
894 Fwiden (p->buffer); | |
895 | |
896 /* Make sure opoint floats ahead of any new text, just as point | |
897 would. */ | |
898 if (BUF_PT (buf) <= old_point) | |
899 old_point += nchars; | |
900 | |
901 /* Insert after old_begv, but before old_zv. */ | |
902 if (BUF_PT (buf) < old_begv) | |
903 old_begv += nchars; | |
904 if (BUF_PT (buf) <= old_zv) | |
905 old_zv += nchars; | |
906 | |
907 #if 0 | |
908 /* This screws up initial display of the window. jla */ | |
909 | |
910 /* Insert before markers in case we are inserting where | |
911 the buffer's mark is, and the user's next command is Meta-y. */ | |
912 buffer_insert_raw_string_1 (buf, -1, chars, | |
913 nbytes, INSDEL_BEFORE_MARKERS); | |
914 #else | |
915 buffer_insert_raw_string (buf, chars, nbytes); | |
916 #endif | |
917 | |
918 Fset_marker (p->mark, make_int (BUF_PT (buf)), p->buffer); | |
919 | |
920 MARK_MODELINE_CHANGED; | |
921 | |
922 /* If the restriction isn't what it should be, set it. */ | |
923 if (old_begv != BUF_BEGV (buf) || old_zv != BUF_ZV (buf)) | |
924 { | |
925 Fwiden(p->buffer); | |
926 old_begv = bufpos_clip_to_bounds (BUF_BEG (buf), | |
927 old_begv, | |
928 BUF_Z (buf)); | |
929 old_zv = bufpos_clip_to_bounds (BUF_BEG (buf), | |
930 old_zv, | |
931 BUF_Z (buf)); | |
932 Fnarrow_to_region (make_int (old_begv), make_int (old_zv), | |
933 p->buffer); | |
934 } | |
935 | |
936 /* Handling the process output should not deactivate the mark. */ | |
937 zmacs_region_stays = old_zmacs_region_stays; | |
938 buf->read_only = old_read_only; | |
939 old_point = bufpos_clip_to_bounds (BUF_BEGV (buf), | |
940 old_point, | |
941 BUF_ZV (buf)); | |
942 BUF_SET_PT (buf, old_point); | |
943 | |
944 UNGCPRO; | |
945 } | |
946 return nchars; | |
947 } | |
948 | |
949 /* Sending data to subprocess */ | |
950 | |
951 /* send some data to process PROC. If NONRELOCATABLE is non-NULL, it | |
952 specifies the address of the data. Otherwise, the data comes from the | |
953 object RELOCATABLE (either a string or a buffer). START and LEN | |
954 specify the offset and length of the data to send. | |
955 | |
956 Note that START and LEN are in Bufpos's if RELOCATABLE is a buffer, | |
957 and in Bytecounts otherwise. */ | |
958 | |
959 void | |
960 send_process (Lisp_Object proc, | |
961 Lisp_Object relocatable, CONST Bufbyte *nonrelocatable, | |
962 int start, int len) | |
963 { | |
964 /* This function can GC */ | |
965 struct gcpro gcpro1, gcpro2; | |
966 Lisp_Object lstream = Qnil; | |
967 | |
968 GCPRO2 (proc, lstream); | |
969 | |
970 if (NILP (DATA_OUTSTREAM (XPROCESS (proc)))) | |
971 signal_simple_error ("Process not open for writing", proc); | |
972 | |
973 if (nonrelocatable) | |
974 lstream = | |
975 make_fixed_buffer_input_stream (nonrelocatable + start, len); | |
976 else if (BUFFERP (relocatable)) | |
977 lstream = make_lisp_buffer_input_stream (XBUFFER (relocatable), | |
978 start, start + len, 0); | |
979 else | |
980 lstream = make_lisp_string_input_stream (relocatable, start, len); | |
981 | |
982 PROCMETH (send_process, (proc, XLSTREAM (lstream))); | |
983 | |
984 UNGCPRO; | |
985 Lstream_delete (XLSTREAM (lstream)); | |
986 } | |
987 | |
988 DEFUN ("process-tty-name", Fprocess_tty_name, 1, 1, 0, /* | |
989 Return the name of the terminal PROCESS uses, or nil if none. | |
990 This is the terminal that the process itself reads and writes on, | |
991 not the name of the pty that Emacs uses to talk with that terminal. | |
992 */ | |
993 (proc)) | |
994 { | |
995 CHECK_PROCESS (proc); | |
996 return MAYBE_LISP_PROCMETH (get_tty_name, (XPROCESS (proc))); | |
997 } | |
998 | |
999 DEFUN ("set-process-buffer", Fset_process_buffer, 2, 2, 0, /* | |
1000 Set buffer associated with PROCESS to BUFFER (a buffer, or nil). | |
1001 */ | |
1002 (proc, buffer)) | |
1003 { | |
1004 CHECK_PROCESS (proc); | |
1005 if (!NILP (buffer)) | |
1006 CHECK_BUFFER (buffer); | |
1007 XPROCESS (proc)->buffer = buffer; | |
1008 return buffer; | |
1009 } | |
1010 | |
1011 DEFUN ("process-buffer", Fprocess_buffer, 1, 1, 0, /* | |
1012 Return the buffer PROCESS is associated with. | |
1013 Output from PROCESS is inserted in this buffer | |
1014 unless PROCESS has a filter. | |
1015 */ | |
1016 (proc)) | |
1017 { | |
1018 CHECK_PROCESS (proc); | |
1019 return XPROCESS (proc)->buffer; | |
1020 } | |
1021 | |
1022 DEFUN ("process-mark", Fprocess_mark, 1, 1, 0, /* | |
1023 Return the marker for the end of the last output from PROCESS. | |
1024 */ | |
1025 (proc)) | |
1026 { | |
1027 CHECK_PROCESS (proc); | |
1028 return XPROCESS (proc)->mark; | |
1029 } | |
1030 | |
1031 void | |
1032 set_process_filter (Lisp_Object proc, Lisp_Object filter, int filter_does_read) | |
1033 { | |
1034 CHECK_PROCESS (proc); | |
1035 if (PROCESS_LIVE_P (proc)) { | |
1036 if (EQ (filter, Qt)) | |
1037 event_stream_unselect_process (XPROCESS (proc)); | |
1038 else | |
1039 event_stream_select_process (XPROCESS (proc)); | |
1040 } | |
1041 | |
1042 XPROCESS (proc)->filter = filter; | |
1043 XPROCESS (proc)->filter_does_read = filter_does_read; | |
1044 } | |
1045 | |
1046 DEFUN ("set-process-filter", Fset_process_filter, 2, 2, 0, /* | |
1047 Give PROCESS the filter function FILTER; nil means no filter. | |
1048 t means stop accepting output from the process. | |
1049 When a process has a filter, each time it does output | |
1050 the entire string of output is passed to the filter. | |
1051 The filter gets two arguments: the process and the string of output. | |
1052 If the process has a filter, its buffer is not used for output. | |
1053 */ | |
1054 (proc, filter)) | |
1055 { | |
1056 set_process_filter (proc, filter, 0); | |
1057 return filter; | |
1058 } | |
1059 | |
1060 DEFUN ("process-filter", Fprocess_filter, 1, 1, 0, /* | |
1061 Return the filter function of PROCESS; nil if none. | |
1062 See `set-process-filter' for more info on filter functions. | |
1063 */ | |
1064 (proc)) | |
1065 { | |
1066 CHECK_PROCESS (proc); | |
1067 return XPROCESS (proc)->filter; | |
1068 } | |
1069 | |
1070 DEFUN ("process-send-region", Fprocess_send_region, 3, 3, 0, /* | |
1071 Send current contents of region as input to PROCESS. | |
1072 PROCESS may be a process name or an actual process. | |
1073 Called from program, takes three arguments, PROCESS, START and END. | |
1074 If the region is more than 500 or so characters long, | |
1075 it is sent in several bunches. This may happen even for shorter regions. | |
1076 Output from processes can arrive in between bunches. | |
1077 */ | |
1078 (process, start, end)) | |
1079 { | |
1080 /* This function can GC */ | |
1081 Lisp_Object proc = get_process (process); | |
1082 Bufpos st, en; | |
1083 | |
1084 get_buffer_range_char (current_buffer, start, end, &st, &en, 0); | |
1085 | |
1086 send_process (proc, Fcurrent_buffer (), 0, | |
1087 st, en - st); | |
1088 return Qnil; | |
1089 } | |
1090 | |
1091 DEFUN ("process-send-string", Fprocess_send_string, 2, 4, 0, /* | |
1092 Send PROCESS the contents of STRING as input. | |
1093 PROCESS may be a process name or an actual process. | |
1094 Optional arguments FROM and TO specify part of STRING, see `substring'. | |
1095 If STRING is more than 500 or so characters long, | |
1096 it is sent in several bunches. This may happen even for shorter strings. | |
1097 Output from processes can arrive in between bunches. | |
1098 */ | |
1099 (process, string, from, to)) | |
1100 { | |
1101 /* This function can GC */ | |
1102 Lisp_Object proc; | |
1103 Bytecount len; | |
1104 Bytecount bfr, bto; | |
1105 | |
1106 proc = get_process (process); | |
1107 CHECK_STRING (string); | |
1108 get_string_range_byte (string, from, to, &bfr, &bto, | |
1109 GB_HISTORICAL_STRING_BEHAVIOR); | |
1110 len = bto - bfr; | |
1111 | |
1112 send_process (proc, string, 0, bfr, len); | |
1113 return Qnil; | |
1114 } | |
1115 | |
1116 #ifdef FILE_CODING | |
1117 | |
1118 DEFUN ("process-input-coding-system", Fprocess_input_coding_system, 1, 1, 0, /* | |
1119 Return PROCESS's input coding system. | |
1120 */ | |
1121 (process)) | |
1122 { | |
1123 process = get_process (process); | |
1124 return decoding_stream_coding_system (XLSTREAM (XPROCESS (process)->coding_instream) ); | |
1125 } | |
1126 | |
1127 DEFUN ("process-output-coding-system", Fprocess_output_coding_system, 1, 1, 0, /* | |
1128 Return PROCESS's output coding system. | |
1129 */ | |
1130 (process)) | |
1131 { | |
1132 process = get_process (process); | |
1133 return encoding_stream_coding_system (XLSTREAM (XPROCESS (process)->coding_outstream)); | |
1134 } | |
1135 | |
1136 DEFUN ("process-coding-system", Fprocess_coding_system, 1, 1, 0, /* | |
1137 Return a pair of coding-system for decoding and encoding of PROCESS. | |
1138 */ | |
1139 (process)) | |
1140 { | |
1141 process = get_process (process); | |
1142 return Fcons (decoding_stream_coding_system | |
1143 (XLSTREAM (XPROCESS (process)->coding_instream)), | |
1144 encoding_stream_coding_system | |
1145 (XLSTREAM (XPROCESS (process)->coding_outstream))); | |
1146 } | |
1147 | |
1148 DEFUN ("set-process-input-coding-system", Fset_process_input_coding_system, | |
1149 2, 2, 0, /* | |
1150 Set PROCESS's input coding system to CODESYS. | |
1151 */ | |
1152 (process, codesys)) | |
1153 { | |
1154 codesys = Fget_coding_system (codesys); | |
1155 process = get_process (process); | |
1156 set_decoding_stream_coding_system | |
1157 (XLSTREAM (XPROCESS (process)->coding_instream), codesys); | |
1158 return Qnil; | |
1159 } | |
1160 | |
1161 DEFUN ("set-process-output-coding-system", Fset_process_output_coding_system, | |
1162 2, 2, 0, /* | |
1163 Set PROCESS's output coding system to CODESYS. | |
1164 */ | |
1165 (process, codesys)) | |
1166 { | |
1167 codesys = Fget_coding_system (codesys); | |
1168 process = get_process (process); | |
1169 set_encoding_stream_coding_system | |
1170 (XLSTREAM (XPROCESS (process)->coding_outstream), codesys); | |
1171 return Qnil; | |
1172 } | |
1173 | |
1174 DEFUN ("set-process-coding-system", Fset_process_coding_system, | |
1175 1, 3, 0, /* | |
1176 Set coding-systems of PROCESS to DECODING and ENCODING. | |
1177 */ | |
1178 (process, decoding, encoding)) | |
1179 { | |
1180 if (!NILP (decoding)) | |
1181 Fset_process_input_coding_system (process, decoding); | |
1182 | |
1183 if (!NILP (encoding)) | |
1184 Fset_process_output_coding_system (process, encoding); | |
1185 | |
1186 return Qnil; | |
1187 } | |
1188 | |
1189 #endif /* FILE_CODING */ | |
1190 | |
1191 /************************************************************************/ | |
1192 /* process status */ | |
1193 /************************************************************************/ | |
1194 | |
1195 static Lisp_Object | |
1196 exec_sentinel_unwind (Lisp_Object datum) | |
1197 { | |
1198 struct Lisp_Cons *d = XCONS (datum); | |
1199 XPROCESS (d->car)->sentinel = d->cdr; | |
1200 free_cons (d); | |
1201 return Qnil; | |
1202 } | |
1203 | |
1204 static void | |
1205 exec_sentinel (Lisp_Object proc, Lisp_Object reason) | |
1206 { | |
1207 /* This function can GC */ | |
1208 int speccount = specpdl_depth (); | |
1209 struct Lisp_Process *p = XPROCESS (proc); | |
1210 Lisp_Object sentinel = p->sentinel; | |
1211 | |
1212 if (NILP (sentinel)) | |
1213 return; | |
1214 | |
1215 /* Some weird FSFmacs crap here with | |
1216 Vdeactivate_mark and current_buffer->keymap */ | |
1217 | |
1218 /* Zilch the sentinel while it's running, to avoid recursive invocations; | |
1219 assure that it gets restored no matter how the sentinel exits. */ | |
1220 p->sentinel = Qnil; | |
1221 record_unwind_protect (exec_sentinel_unwind, noseeum_cons (proc, sentinel)); | |
1222 /* We used to bind inhibit-quit to t here, but call2_trapping_errors() | |
1223 does that for us. */ | |
1224 running_asynch_code = 1; | |
1225 call2_trapping_errors ("Error in process sentinel", sentinel, proc, reason); | |
1226 running_asynch_code = 0; | |
1227 restore_match_data (); | |
1228 unbind_to (speccount, Qnil); | |
1229 } | |
1230 | |
1231 DEFUN ("set-process-sentinel", Fset_process_sentinel, 2, 2, 0, /* | |
1232 Give PROCESS the sentinel SENTINEL; nil for none. | |
1233 The sentinel is called as a function when the process changes state. | |
1234 It gets two arguments: the process, and a string describing the change. | |
1235 */ | |
1236 (proc, sentinel)) | |
1237 { | |
1238 CHECK_PROCESS (proc); | |
1239 XPROCESS (proc)->sentinel = sentinel; | |
1240 return sentinel; | |
1241 } | |
1242 | |
1243 DEFUN ("process-sentinel", Fprocess_sentinel, 1, 1, 0, /* | |
1244 Return the sentinel of PROCESS; nil if none. | |
1245 See `set-process-sentinel' for more info on sentinels. | |
1246 */ | |
1247 (proc)) | |
1248 { | |
1249 CHECK_PROCESS (proc); | |
1250 return XPROCESS (proc)->sentinel; | |
1251 } | |
1252 | |
1253 | |
1254 CONST char * | |
1255 signal_name (int signum) | |
1256 { | |
1257 if (signum >= 0 && signum < NSIG) | |
1258 return (CONST char *) sys_siglist[signum]; | |
1259 | |
1260 return (CONST char *) GETTEXT ("unknown signal"); | |
1261 } | |
1262 | |
1263 void | |
1264 update_process_status (Lisp_Object p, | |
1265 Lisp_Object status_symbol, | |
1266 int exit_code, | |
1267 int core_dumped) | |
1268 { | |
1269 XPROCESS (p)->tick++; | |
1270 process_tick++; | |
1271 XPROCESS (p)->status_symbol = status_symbol; | |
1272 XPROCESS (p)->exit_code = exit_code; | |
1273 XPROCESS (p)->core_dumped = core_dumped; | |
1274 } | |
1275 | |
1276 /* Return a string describing a process status list. */ | |
1277 | |
1278 static Lisp_Object | |
1279 status_message (struct Lisp_Process *p) | |
1280 { | |
1281 Lisp_Object symbol = p->status_symbol; | |
1282 int code = p->exit_code; | |
1283 int coredump = p->core_dumped; | |
1284 Lisp_Object string, string2; | |
1285 | |
1286 if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) | |
1287 { | |
1288 string = build_string (signal_name (code)); | |
1289 if (coredump) | |
1290 string2 = build_translated_string (" (core dumped)\n"); | |
1291 else | |
1292 string2 = build_string ("\n"); | |
1293 set_string_char (XSTRING (string), 0, | |
1294 DOWNCASE (current_buffer, | |
1295 string_char (XSTRING (string), 0))); | |
1296 return concat2 (string, string2); | |
1297 } | |
1298 else if (EQ (symbol, Qexit)) | |
1299 { | |
1300 if (code == 0) | |
1301 return build_translated_string ("finished\n"); | |
1302 string = Fnumber_to_string (make_int (code)); | |
1303 if (coredump) | |
1304 string2 = build_translated_string (" (core dumped)\n"); | |
1305 else | |
1306 string2 = build_string ("\n"); | |
1307 return concat2 (build_translated_string ("exited abnormally with code "), | |
1308 concat2 (string, string2)); | |
1309 } | |
1310 else | |
1311 return Fcopy_sequence (Fsymbol_name (symbol)); | |
1312 } | |
1313 | |
1314 /* Tell status_notify() to check for terminated processes. We do this | |
1315 because on some systems we sometimes miss SIGCHLD calls. (Not sure | |
1316 why.) */ | |
1317 | |
1318 void | |
1319 kick_status_notify (void) | |
1320 { | |
1321 process_tick++; | |
1322 } | |
1323 | |
1324 | |
1325 /* Report all recent events of a change in process status | |
1326 (either run the sentinel or output a message). | |
1327 This is done while Emacs is waiting for keyboard input. */ | |
1328 | |
1329 void | |
1330 status_notify (void) | |
1331 { | |
1332 /* This function can GC */ | |
1333 Lisp_Object tail = Qnil; | |
1334 Lisp_Object symbol = Qnil; | |
1335 Lisp_Object msg = Qnil; | |
1336 struct gcpro gcpro1, gcpro2, gcpro3; | |
1337 /* process_tick is volatile, so we have to remember it now. | |
1338 Otherwise, we get a race condition is SIGCHLD happens during | |
1339 this function. | |
1340 | |
1341 (Actually, this is not the case anymore. The code to | |
1342 update the process structures has been moved out of the | |
1343 SIGCHLD handler. But for the moment I'm leaving this | |
1344 stuff in -- it can't hurt.) */ | |
1345 int temp_process_tick; | |
1346 | |
1347 MAYBE_PROCMETH (reap_exited_processes, ()); | |
1348 | |
1349 temp_process_tick = process_tick; | |
1350 | |
1351 if (update_tick == temp_process_tick) | |
1352 return; | |
1353 | |
1354 /* We need to gcpro tail; if read_process_output calls a filter | |
1355 which deletes a process and removes the cons to which tail points | |
1356 from Vprocess_alist, and then causes a GC, tail is an unprotected | |
1357 reference. */ | |
1358 GCPRO3 (tail, symbol, msg); | |
1359 | |
1360 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail)) | |
1361 { | |
1362 Lisp_Object proc = XCAR (tail); | |
1363 struct Lisp_Process *p = XPROCESS (proc); | |
1364 /* p->tick is also volatile. Same thing as above applies. */ | |
1365 int this_process_tick; | |
1366 | |
1367 /* #### extra check for terminated processes, in case a SIGCHLD | |
1368 got missed (this seems to happen sometimes, I'm not sure why). | |
1369 */ | |
1370 if (INTP (p->pid)) | |
1371 MAYBE_PROCMETH (update_status_if_terminated, (p)); | |
1372 | |
1373 this_process_tick = p->tick; | |
1374 if (this_process_tick != p->update_tick) | |
1375 { | |
1376 p->update_tick = this_process_tick; | |
1377 | |
1378 /* If process is still active, read any output that remains. */ | |
1379 while (!EQ (p->filter, Qt) | |
1380 && read_process_output (proc) > 0) | |
1381 ; | |
1382 | |
1383 /* Get the text to use for the message. */ | |
1384 msg = status_message (p); | |
1385 | |
1386 /* If process is terminated, deactivate it or delete it. */ | |
1387 symbol = p->status_symbol; | |
1388 | |
1389 if (EQ (symbol, Qsignal) | |
1390 || EQ (symbol, Qexit)) | |
1391 { | |
1392 if (delete_exited_processes) | |
1393 remove_process (proc); | |
1394 else | |
1395 deactivate_process (proc); | |
1396 } | |
1397 | |
1398 /* Now output the message suitably. */ | |
1399 if (!NILP (p->sentinel)) | |
1400 exec_sentinel (proc, msg); | |
1401 /* Don't bother with a message in the buffer | |
1402 when a process becomes runnable. */ | |
1403 else if (!EQ (symbol, Qrun) && !NILP (p->buffer)) | |
1404 { | |
1405 Lisp_Object old_read_only = Qnil; | |
1406 Lisp_Object old = Fcurrent_buffer (); | |
1407 Bufpos opoint; | |
1408 struct gcpro ngcpro1, ngcpro2; | |
1409 | |
1410 /* Avoid error if buffer is deleted | |
1411 (probably that's why the process is dead, too) */ | |
1412 if (!BUFFER_LIVE_P (XBUFFER (p->buffer))) | |
1413 continue; | |
1414 | |
1415 NGCPRO2 (old, old_read_only); | |
1416 Fset_buffer (p->buffer); | |
1417 opoint = BUF_PT (current_buffer); | |
1418 /* Insert new output into buffer | |
1419 at the current end-of-output marker, | |
1420 thus preserving logical ordering of input and output. */ | |
1421 if (XMARKER (p->mark)->buffer) | |
1422 BUF_SET_PT (current_buffer, marker_position (p->mark)); | |
1423 else | |
1424 BUF_SET_PT (current_buffer, BUF_ZV (current_buffer)); | |
1425 if (BUF_PT (current_buffer) <= opoint) | |
1426 opoint += (string_char_length (XSTRING (msg)) | |
1427 + string_char_length (XSTRING (p->name)) | |
1428 + 10); | |
1429 | |
1430 old_read_only = current_buffer->read_only; | |
1431 current_buffer->read_only = Qnil; | |
1432 buffer_insert_c_string (current_buffer, "\nProcess "); | |
1433 Finsert (1, &p->name); | |
1434 buffer_insert_c_string (current_buffer, " "); | |
1435 Finsert (1, &msg); | |
1436 current_buffer->read_only = old_read_only; | |
1437 Fset_marker (p->mark, make_int (BUF_PT (current_buffer)), | |
1438 p->buffer); | |
1439 | |
1440 opoint = bufpos_clip_to_bounds(BUF_BEGV (XBUFFER (p->buffer)), | |
1441 opoint, | |
1442 BUF_ZV (XBUFFER (p->buffer))); | |
1443 BUF_SET_PT (current_buffer, opoint); | |
1444 Fset_buffer (old); | |
1445 NUNGCPRO; | |
1446 } | |
1447 } | |
1448 } /* end for */ | |
1449 | |
1450 /* in case buffers use %s in modeline-format */ | |
1451 MARK_MODELINE_CHANGED; | |
1452 redisplay (); | |
1453 | |
1454 update_tick = temp_process_tick; | |
1455 | |
1456 UNGCPRO; | |
1457 } | |
1458 | |
1459 DEFUN ("process-status", Fprocess_status, 1, 1, 0, /* | |
1460 Return the status of PROCESS. | |
1461 This is a symbol, one of these: | |
1462 | |
1463 run -- for a process that is running. | |
1464 stop -- for a process stopped but continuable. | |
1465 exit -- for a process that has exited. | |
1466 signal -- for a process that has got a fatal signal. | |
1467 open -- for a network stream connection that is open. | |
1468 closed -- for a network stream connection that is closed. | |
1469 nil -- if arg is a process name and no such process exists. | |
1470 | |
1471 PROCESS may be a process, a buffer, the name of a process or buffer, or | |
1472 nil, indicating the current buffer's process. | |
1473 */ | |
1474 (proc)) | |
1475 { | |
1476 Lisp_Object status_symbol; | |
1477 | |
1478 if (STRINGP (proc)) | |
1479 proc = Fget_process (proc); | |
1480 else | |
1481 proc = get_process (proc); | |
1482 | |
1483 if (NILP (proc)) | |
1484 return Qnil; | |
1485 | |
1486 status_symbol = XPROCESS (proc)->status_symbol; | |
1487 if (network_connection_p (proc)) | |
1488 { | |
1489 if (EQ (status_symbol, Qrun)) | |
1490 status_symbol = Qopen; | |
1491 else if (EQ (status_symbol, Qexit)) | |
1492 status_symbol = Qclosed; | |
1493 } | |
1494 return status_symbol; | |
1495 } | |
1496 | |
1497 DEFUN ("process-exit-status", Fprocess_exit_status, 1, 1, 0, /* | |
1498 Return the exit status of PROCESS or the signal number that killed it. | |
1499 If PROCESS has not yet exited or died, return 0. | |
1500 */ | |
1501 (proc)) | |
1502 { | |
1503 CHECK_PROCESS (proc); | |
1504 return make_int (XPROCESS (proc)->exit_code); | |
1505 } | |
1506 | |
1507 | |
1508 | |
1509 /* send a signal number SIGNO to PROCESS. | |
1510 CURRENT_GROUP means send to the process group that currently owns | |
1511 the terminal being used to communicate with PROCESS. | |
1512 This is used for various commands in shell mode. | |
1513 If NOMSG is zero, insert signal-announcements into process's buffers | |
1514 right away. | |
1515 | |
1516 If we can, we try to signal PROCESS by sending control characters | |
1517 down the pty. This allows us to signal inferiors who have changed | |
1518 their uid, for which killpg would return an EPERM error. */ | |
1519 | |
1520 static void | |
1521 process_send_signal (Lisp_Object process, int signo, | |
1522 int current_group, int nomsg) | |
1523 { | |
1524 /* This function can GC */ | |
1525 Lisp_Object proc = get_process (process); | |
1526 | |
1527 if (network_connection_p (proc)) | |
1528 error ("Network connection %s is not a subprocess", | |
1529 XSTRING_DATA (XPROCESS(proc)->name)); | |
1530 if (!PROCESS_LIVE_P (proc)) | |
1531 error ("Process %s is not active", | |
1532 XSTRING_DATA (XPROCESS(proc)->name)); | |
1533 | |
1534 MAYBE_PROCMETH (kill_child_process, (proc, signo, current_group, nomsg)); | |
1535 } | |
1536 | |
1537 DEFUN ("interrupt-process", Finterrupt_process, 0, 2, 0, /* | |
1538 Interrupt process PROCESS. May be process or name of one. | |
1539 Nil or no arg means current buffer's process. | |
1540 Second arg CURRENT-GROUP non-nil means send signal to | |
1541 the current process-group of the process's controlling terminal | |
1542 rather than to the process's own process group. | |
1543 If the process is a shell, this means interrupt current subjob | |
1544 rather than the shell. | |
1545 */ | |
1546 (process, current_group)) | |
1547 { | |
1548 /* This function can GC */ | |
1549 process_send_signal (process, SIGINT, !NILP (current_group), 0); | |
1550 return process; | |
1551 } | |
1552 | |
1553 DEFUN ("kill-process", Fkill_process, 0, 2, 0, /* | |
1554 Kill process PROCESS. May be process or name of one. | |
1555 See function `interrupt-process' for more details on usage. | |
1556 */ | |
1557 (process, current_group)) | |
1558 { | |
1559 /* This function can GC */ | |
1560 #ifdef SIGKILL | |
1561 process_send_signal (process, SIGKILL, !NILP (current_group), 0); | |
1562 #else | |
1563 error ("kill-process: Not supported on this system"); | |
1564 #endif | |
1565 return process; | |
1566 } | |
1567 | |
1568 DEFUN ("quit-process", Fquit_process, 0, 2, 0, /* | |
1569 Send QUIT signal to process PROCESS. May be process or name of one. | |
1570 See function `interrupt-process' for more details on usage. | |
1571 */ | |
1572 (process, current_group)) | |
1573 { | |
1574 /* This function can GC */ | |
1575 #ifdef SIGQUIT | |
1576 process_send_signal (process, SIGQUIT, !NILP (current_group), 0); | |
1577 #else | |
1578 error ("quit-process: Not supported on this system"); | |
1579 #endif | |
1580 return process; | |
1581 } | |
1582 | |
1583 DEFUN ("stop-process", Fstop_process, 0, 2, 0, /* | |
1584 Stop process PROCESS. May be process or name of one. | |
1585 See function `interrupt-process' for more details on usage. | |
1586 */ | |
1587 (process, current_group)) | |
1588 { | |
1589 /* This function can GC */ | |
1590 #ifdef SIGTSTP | |
1591 process_send_signal (process, SIGTSTP, !NILP (current_group), 0); | |
1592 #else | |
1593 error ("stop-process: Not supported on this system"); | |
1594 #endif | |
1595 return process; | |
1596 } | |
1597 | |
1598 DEFUN ("continue-process", Fcontinue_process, 0, 2, 0, /* | |
1599 Continue process PROCESS. May be process or name of one. | |
1600 See function `interrupt-process' for more details on usage. | |
1601 */ | |
1602 (process, current_group)) | |
1603 { | |
1604 /* This function can GC */ | |
1605 #ifdef SIGCONT | |
1606 process_send_signal (process, SIGCONT, !NILP (current_group), 0); | |
1607 #else | |
1608 error ("continue-process: Not supported on this system"); | |
1609 #endif | |
1610 return process; | |
1611 } | |
1612 | |
1613 DEFUN ("signal-process", Fsignal_process, 2, 2, | |
1614 "nProcess number: \nnSignal code: ", /* | |
1615 Send the process with process id PID the signal with code SIGCODE. | |
1616 PID must be an integer. The process need not be a child of this Emacs. | |
1617 SIGCODE may be an integer, or a symbol whose name is a signal name. | |
1618 */ | |
1619 (pid, sigcode)) | |
1620 { | |
1621 CHECK_INT (pid); | |
1622 | |
1623 if (INTP (sigcode)) | |
1624 ; | |
1625 else | |
1626 { | |
1627 Bufbyte *name; | |
1628 | |
1629 CHECK_SYMBOL (sigcode); | |
1630 name = string_data (XSYMBOL (sigcode)->name); | |
1631 | |
1632 #define handle_signal(signal) \ | |
1633 else if (!strcmp ((CONST char *) name, #signal)) \ | |
1634 XSETINT (sigcode, signal) | |
1635 | |
1636 if (0) | |
1637 ; | |
1638 handle_signal (SIGINT); /* ANSI */ | |
1639 handle_signal (SIGILL); /* ANSI */ | |
1640 handle_signal (SIGABRT); /* ANSI */ | |
1641 handle_signal (SIGFPE); /* ANSI */ | |
1642 handle_signal (SIGSEGV); /* ANSI */ | |
1643 handle_signal (SIGTERM); /* ANSI */ | |
1644 | |
1645 #ifdef SIGHUP | |
1646 handle_signal (SIGHUP); /* POSIX */ | |
1647 #endif | |
1648 #ifdef SIGQUIT | |
1649 handle_signal (SIGQUIT); /* POSIX */ | |
1650 #endif | |
1651 #ifdef SIGTRAP | |
1652 handle_signal (SIGTRAP); /* POSIX */ | |
1653 #endif | |
1654 #ifdef SIGKILL | |
1655 handle_signal (SIGKILL); /* POSIX */ | |
1656 #endif | |
1657 #ifdef SIGUSR1 | |
1658 handle_signal (SIGUSR1); /* POSIX */ | |
1659 #endif | |
1660 #ifdef SIGUSR2 | |
1661 handle_signal (SIGUSR2); /* POSIX */ | |
1662 #endif | |
1663 #ifdef SIGPIPE | |
1664 handle_signal (SIGPIPE); /* POSIX */ | |
1665 #endif | |
1666 #ifdef SIGALRM | |
1667 handle_signal (SIGALRM); /* POSIX */ | |
1668 #endif | |
1669 #ifdef SIGCHLD | |
1670 handle_signal (SIGCHLD); /* POSIX */ | |
1671 #endif | |
1672 #ifdef SIGCONT | |
1673 handle_signal (SIGCONT); /* POSIX */ | |
1674 #endif | |
1675 #ifdef SIGSTOP | |
1676 handle_signal (SIGSTOP); /* POSIX */ | |
1677 #endif | |
1678 #ifdef SIGTSTP | |
1679 handle_signal (SIGTSTP); /* POSIX */ | |
1680 #endif | |
1681 #ifdef SIGTTIN | |
1682 handle_signal (SIGTTIN); /* POSIX */ | |
1683 #endif | |
1684 #ifdef SIGTTOU | |
1685 handle_signal (SIGTTOU); /* POSIX */ | |
1686 #endif | |
1687 | |
1688 #ifdef SIGBUS | |
1689 handle_signal (SIGBUS); /* XPG5 */ | |
1690 #endif | |
1691 #ifdef SIGPOLL | |
1692 handle_signal (SIGPOLL); /* XPG5 */ | |
1693 #endif | |
1694 #ifdef SIGPROF | |
1695 handle_signal (SIGPROF); /* XPG5 */ | |
1696 #endif | |
1697 #ifdef SIGSYS | |
1698 handle_signal (SIGSYS); /* XPG5 */ | |
1699 #endif | |
1700 #ifdef SIGURG | |
1701 handle_signal (SIGURG); /* XPG5 */ | |
1702 #endif | |
1703 #ifdef SIGXCPU | |
1704 handle_signal (SIGXCPU); /* XPG5 */ | |
1705 #endif | |
1706 #ifdef SIGXFSZ | |
1707 handle_signal (SIGXFSZ); /* XPG5 */ | |
1708 #endif | |
1709 #ifdef SIGVTALRM | |
1710 handle_signal (SIGVTALRM); /* XPG5 */ | |
1711 #endif | |
1712 | |
1713 #ifdef SIGIO | |
1714 handle_signal (SIGIO); /* BSD 4.2 */ | |
1715 #endif | |
1716 #ifdef SIGWINCH | |
1717 handle_signal (SIGWINCH); /* BSD 4.3 */ | |
1718 #endif | |
1719 | |
1720 #ifdef SIGEMT | |
1721 handle_signal (SIGEMT); | |
1722 #endif | |
1723 #ifdef SIGINFO | |
1724 handle_signal (SIGINFO); | |
1725 #endif | |
1726 #ifdef SIGHWE | |
1727 handle_signal (SIGHWE); | |
1728 #endif | |
1729 #ifdef SIGPRE | |
1730 handle_signal (SIGPRE); | |
1731 #endif | |
1732 #ifdef SIGUME | |
1733 handle_signal (SIGUME); | |
1734 #endif | |
1735 #ifdef SIGDLK | |
1736 handle_signal (SIGDLK); | |
1737 #endif | |
1738 #ifdef SIGCPULIM | |
1739 handle_signal (SIGCPULIM); | |
1740 #endif | |
1741 #ifdef SIGIOT | |
1742 handle_signal (SIGIOT); | |
1743 #endif | |
1744 #ifdef SIGLOST | |
1745 handle_signal (SIGLOST); | |
1746 #endif | |
1747 #ifdef SIGSTKFLT | |
1748 handle_signal (SIGSTKFLT); | |
1749 #endif | |
1750 #ifdef SIGUNUSED | |
1751 handle_signal (SIGUNUSED); | |
1752 #endif | |
1753 #ifdef SIGDANGER | |
1754 handle_signal (SIGDANGER); /* AIX */ | |
1755 #endif | |
1756 #ifdef SIGMSG | |
1757 handle_signal (SIGMSG); | |
1758 #endif | |
1759 #ifdef SIGSOUND | |
1760 handle_signal (SIGSOUND); | |
1761 #endif | |
1762 #ifdef SIGRETRACT | |
1763 handle_signal (SIGRETRACT); | |
1764 #endif | |
1765 #ifdef SIGGRANT | |
1766 handle_signal (SIGGRANT); | |
1767 #endif | |
1768 #ifdef SIGPWR | |
1769 handle_signal (SIGPWR); | |
1770 #endif | |
1771 else | |
1772 error ("Undefined signal name %s", name); | |
1773 } | |
1774 | |
1775 #undef handle_signal | |
1776 | |
1777 return make_int (PROCMETH_OR_GIVEN (kill_process_by_pid, | |
1778 (XINT (pid), XINT (sigcode)), -1)); | |
1779 } | |
1780 | |
1781 DEFUN ("process-send-eof", Fprocess_send_eof, 0, 1, 0, /* | |
1782 Make PROCESS see end-of-file in its input. | |
1783 PROCESS may be a process, a buffer, the name of a process or buffer, or | |
1784 nil, indicating the current buffer's process. | |
1785 If PROCESS is a network connection, or is a process communicating | |
1786 through a pipe (as opposed to a pty), then you cannot send any more | |
1787 text to PROCESS after you call this function. | |
1788 */ | |
1789 (process)) | |
1790 { | |
1791 /* This function can GC */ | |
1792 Lisp_Object proc = get_process (process); | |
1793 | |
1794 /* Make sure the process is really alive. */ | |
1795 if (! EQ (XPROCESS (proc)->status_symbol, Qrun)) | |
1796 error ("Process %s not running", XSTRING_DATA (XPROCESS (proc)->name)); | |
1797 | |
1798 if (!MAYBE_INT_PROCMETH (process_send_eof, (proc))) | |
1799 { | |
1800 if (!NILP (DATA_OUTSTREAM (XPROCESS (proc)))) | |
1801 { | |
1802 Lstream_close (XLSTREAM (DATA_OUTSTREAM (XPROCESS (proc)))); | |
1803 event_stream_delete_stream_pair (Qnil, XPROCESS (proc)->pipe_outstream); | |
1804 XPROCESS (proc)->pipe_outstream = Qnil; | |
1805 #ifdef FILE_CODING | |
1806 XPROCESS (proc)->coding_outstream = Qnil; | |
1807 #endif | |
1808 } | |
1809 } | |
1810 | |
1811 return process; | |
1812 } | |
1813 | |
1814 | |
1815 /************************************************************************/ | |
1816 /* deleting a process */ | |
1817 /************************************************************************/ | |
1818 | |
1819 void | |
1820 deactivate_process (Lisp_Object proc) | |
1821 { | |
1822 struct Lisp_Process *p = XPROCESS (proc); | |
1823 USID usid; | |
1824 | |
1825 /* It's possible that we got as far in the process-creation | |
1826 process as creating the descriptors but didn't get so | |
1827 far as selecting the process for input. In this | |
1828 case, p->pid is nil: p->pid is set at the same time that | |
1829 the process is selected for input. */ | |
1830 /* #### The comment does not look correct. event_stream_unselect_process | |
1831 is guarded by process->selected, so this is not a problem. - kkm*/ | |
1832 /* Must call this before setting the streams to nil */ | |
1833 event_stream_unselect_process (p); | |
1834 | |
1835 if (!NILP (DATA_OUTSTREAM (p))) | |
1836 Lstream_close (XLSTREAM (DATA_OUTSTREAM (p))); | |
1837 if (!NILP (DATA_INSTREAM (p))) | |
1838 Lstream_close (XLSTREAM (DATA_INSTREAM (p))); | |
1839 | |
1840 /* Provide minimal implementation for deactivate_process | |
1841 if there's no process-specific one */ | |
1842 if (HAS_PROCMETH_P (deactivate_process)) | |
1843 usid = PROCMETH (deactivate_process, (p)); | |
1844 else | |
1845 usid = event_stream_delete_stream_pair (p->pipe_instream, | |
1846 p->pipe_outstream); | |
1847 | |
1848 if (usid != USID_DONTHASH) | |
1849 remhash ((CONST void*)usid, usid_to_process); | |
1850 | |
1851 p->pipe_instream = Qnil; | |
1852 p->pipe_outstream = Qnil; | |
1853 #ifdef FILE_CODING | |
1854 p->coding_instream = Qnil; | |
1855 p->coding_outstream = Qnil; | |
1856 #endif | |
1857 } | |
1858 | |
1859 static void | |
1860 remove_process (Lisp_Object proc) | |
1861 { | |
1862 Vprocess_list = delq_no_quit (proc, Vprocess_list); | |
1863 Fset_marker (XPROCESS (proc)->mark, Qnil, Qnil); | |
1864 | |
1865 deactivate_process (proc); | |
1866 } | |
1867 | |
1868 DEFUN ("delete-process", Fdelete_process, 1, 1, 0, /* | |
1869 Delete PROCESS: kill it and forget about it immediately. | |
1870 PROCESS may be a process or the name of one, or a buffer name. | |
1871 */ | |
1872 (proc)) | |
1873 { | |
1874 /* This function can GC */ | |
1875 struct Lisp_Process *p; | |
1876 proc = get_process (proc); | |
1877 p = XPROCESS (proc); | |
1878 if (network_connection_p (proc)) | |
1879 { | |
1880 p->status_symbol = Qexit; | |
1881 p->exit_code = 0; | |
1882 p->core_dumped = 0; | |
1883 p->tick++; | |
1884 process_tick++; | |
1885 } | |
1886 else if (!NILP(p->pipe_instream)) | |
1887 { | |
1888 Fkill_process (proc, Qnil); | |
1889 /* Do this now, since remove_process will make sigchld_handler do nothing. */ | |
1890 p->status_symbol = Qsignal; | |
1891 p->exit_code = SIGKILL; | |
1892 p->core_dumped = 0; | |
1893 p->tick++; | |
1894 process_tick++; | |
1895 status_notify (); | |
1896 } | |
1897 remove_process (proc); | |
1898 return Qnil; | |
1899 } | |
1900 | |
1901 /* Kill all processes associated with `buffer'. | |
1902 If `buffer' is nil, kill all processes */ | |
1903 | |
1904 void | |
1905 kill_buffer_processes (Lisp_Object buffer) | |
1906 { | |
1907 Lisp_Object tail; | |
1908 | |
1909 for (tail = Vprocess_list; CONSP (tail); | |
1910 tail = XCDR (tail)) | |
1911 { | |
1912 Lisp_Object proc = XCAR (tail); | |
1913 if (PROCESSP (proc) | |
1914 && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer))) | |
1915 { | |
1916 if (network_connection_p (proc)) | |
1917 Fdelete_process (proc); | |
1918 else if (!NILP (XPROCESS (proc)->pipe_instream)) | |
1919 process_send_signal (proc, SIGHUP, 0, 1); | |
1920 } | |
1921 } | |
1922 } | |
1923 | |
1924 DEFUN ("process-kill-without-query", Fprocess_kill_without_query, 1, 2, 0, /* | |
1925 Say no query needed if PROCESS is running when Emacs is exited. | |
1926 Optional second argument if non-nil says to require a query. | |
1927 Value is t if a query was formerly required. | |
1928 */ | |
1929 (proc, require_query_p)) | |
1930 { | |
1931 int tem; | |
1932 | |
1933 CHECK_PROCESS (proc); | |
1934 tem = XPROCESS (proc)->kill_without_query; | |
1935 XPROCESS (proc)->kill_without_query = NILP (require_query_p); | |
1936 | |
1937 return tem ? Qnil : Qt; | |
1938 } | |
1939 | |
1940 DEFUN ("process-kill-without-query-p", Fprocess_kill_without_query_p, 1, 1, 0, /* | |
1941 Whether PROC will be killed without query if running when emacs is exited. | |
1942 */ | |
1943 (proc)) | |
1944 { | |
1945 CHECK_PROCESS (proc); | |
1946 return XPROCESS (proc)->kill_without_query ? Qt : Qnil; | |
1947 } | |
1948 | |
1949 | |
1950 /* This is not named init_process in order to avoid a conflict with NS 3.3 */ | |
1951 void | |
1952 init_xemacs_process (void) | |
1953 { | |
1954 MAYBE_PROCMETH (init_process, ()); | |
1955 | |
1956 Vprocess_list = Qnil; | |
1957 | |
1958 if (usid_to_process) | |
1959 clrhash (usid_to_process); | |
1960 else | |
1961 usid_to_process = make_hash_table (32); | |
1962 } | |
1963 | |
1964 #if 0 | |
1965 | |
1966 xxDEFUN ("process-connection", Fprocess_connection, 0, 1, 0, /* | |
1967 Return the connection type of `PROCESS'. This can be nil (pipe), | |
1968 t or pty (pty) or stream (socket connection). | |
1969 */ | |
1970 (process)) | |
1971 { | |
1972 return XPROCESS (process)->type; | |
1973 } | |
1974 | |
1975 #endif /* 0 */ | |
1976 | |
1977 void | |
1978 syms_of_process (void) | |
1979 { | |
1980 defsymbol (&Qprocessp, "processp"); | |
1981 defsymbol (&Qrun, "run"); | |
1982 defsymbol (&Qstop, "stop"); | |
1983 defsymbol (&Qopen, "open"); | |
1984 defsymbol (&Qclosed, "closed"); | |
1985 | |
1986 defsymbol (&Qtcp, "tcp"); | |
1987 defsymbol (&Qudp, "udp"); | |
1988 | |
1989 #ifdef HAVE_MULTICAST | |
1990 defsymbol(&Qmulticast, "multicast"); /* Used for occasional warnings */ | |
1991 #endif | |
1992 | |
1993 DEFSUBR (Fprocessp); | |
1994 DEFSUBR (Fget_process); | |
1995 DEFSUBR (Fget_buffer_process); | |
1996 DEFSUBR (Fdelete_process); | |
1997 DEFSUBR (Fprocess_status); | |
1998 DEFSUBR (Fprocess_exit_status); | |
1999 DEFSUBR (Fprocess_id); | |
2000 DEFSUBR (Fprocess_name); | |
2001 DEFSUBR (Fprocess_tty_name); | |
2002 DEFSUBR (Fprocess_command); | |
2003 DEFSUBR (Fset_process_buffer); | |
2004 DEFSUBR (Fprocess_buffer); | |
2005 DEFSUBR (Fprocess_mark); | |
2006 DEFSUBR (Fset_process_filter); | |
2007 DEFSUBR (Fprocess_filter); | |
2008 DEFSUBR (Fset_process_window_size); | |
2009 DEFSUBR (Fset_process_sentinel); | |
2010 DEFSUBR (Fprocess_sentinel); | |
2011 DEFSUBR (Fprocess_kill_without_query); | |
2012 DEFSUBR (Fprocess_kill_without_query_p); | |
2013 DEFSUBR (Fprocess_list); | |
2014 DEFSUBR (Fstart_process_internal); | |
2015 #ifdef HAVE_SOCKETS | |
2016 DEFSUBR (Fopen_network_stream_internal); | |
2017 #ifdef HAVE_MULTICAST | |
2018 DEFSUBR (Fopen_multicast_group_internal); | |
2019 #endif /* HAVE_MULTICAST */ | |
2020 #endif /* HAVE_SOCKETS */ | |
2021 DEFSUBR (Fprocess_send_region); | |
2022 DEFSUBR (Fprocess_send_string); | |
2023 DEFSUBR (Finterrupt_process); | |
2024 DEFSUBR (Fkill_process); | |
2025 DEFSUBR (Fquit_process); | |
2026 DEFSUBR (Fstop_process); | |
2027 DEFSUBR (Fcontinue_process); | |
2028 DEFSUBR (Fprocess_send_eof); | |
2029 DEFSUBR (Fsignal_process); | |
2030 /* DEFSUBR (Fprocess_connection); */ | |
2031 #ifdef FILE_CODING | |
2032 DEFSUBR (Fprocess_input_coding_system); | |
2033 DEFSUBR (Fprocess_output_coding_system); | |
2034 DEFSUBR (Fset_process_input_coding_system); | |
2035 DEFSUBR (Fset_process_output_coding_system); | |
2036 DEFSUBR (Fprocess_coding_system); | |
2037 DEFSUBR (Fset_process_coding_system); | |
2038 #endif /* FILE_CODING */ | |
2039 } | |
2040 | |
2041 void | |
2042 vars_of_process (void) | |
2043 { | |
2044 Fprovide (intern ("subprocesses")); | |
2045 #ifdef HAVE_SOCKETS | |
2046 Fprovide (intern ("network-streams")); | |
2047 #ifdef HAVE_MULTICAST | |
2048 Fprovide (intern ("multicast")); | |
2049 #endif /* HAVE_MULTICAST */ | |
2050 #endif /* HAVE_SOCKETS */ | |
2051 staticpro (&Vprocess_list); | |
2052 | |
2053 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes /* | |
2054 *Non-nil means delete processes immediately when they exit. | |
2055 nil means don't delete them until `list-processes' is run. | |
2056 */ ); | |
2057 | |
2058 delete_exited_processes = 1; | |
2059 | |
2060 DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type /* | |
2061 Control type of device used to communicate with subprocesses. | |
2062 Values are nil to use a pipe, or t or `pty' to use a pty. | |
2063 The value has no effect if the system has no ptys or if all ptys are busy: | |
2064 then a pipe is used in any case. | |
2065 The value takes effect when `start-process' is called. | |
2066 */ ); | |
2067 Vprocess_connection_type = Qt; | |
2068 | |
2069 DEFVAR_BOOL ("windowed-process-io", &windowed_process_io /* | |
2070 Enables input/output on standard handles of a windowed process. | |
2071 When this variable is nil (the default), XEmacs does not attempt to read | |
2072 standard output handle of a windowed process. Instead, the process is | |
2073 immediately marked as exited immediately upon successful launching. This is | |
2074 done because normal windowed processes do not use standard I/O, as they are | |
2075 not connected to any console. | |
2076 | |
2077 When launching a specially crafted windowed process, which expects to be | |
2078 launched by XEmacs, or by other program which pipes its standard input and | |
2079 output, this variable must be set to non-nil, in which case XEmacs will | |
2080 treat this process just like a console process. | |
2081 | |
2082 NOTE: You should never set this variable, only bind it. | |
2083 | |
2084 Only Windows processes can be "windowed" or "console". This variable has no | |
2085 effect on UNIX processes, because all UNIX processes are "console". | |
2086 */ ); | |
2087 windowed_process_io = 0; | |
2088 | |
2089 #ifdef PROCESS_IO_BLOCKING | |
2090 DEFVAR_LISP ("network-stream-blocking-port-list", &network_stream_blocking_port_list /* | |
2091 List of port numbers or port names to set a blocking I/O mode with connection. | |
2092 Nil value means to set a default(non-blocking) I/O mode. | |
2093 The value takes effect when `open-network-stream-internal' is called. | |
2094 */ ); | |
2095 network_stream_blocking_port_list = Qnil; | |
2096 #endif /* PROCESS_IO_BLOCKING */ | |
2097 } | |
2098 | |
2099 #endif /* not NO_SUBPROCESSES */ |