Mercurial > hg > xemacs-beta
annotate src/process.c @ 5191:71ee43b8a74d
Add #'equalp as a hash test by default; add #'define-hash-table-test, GNU API
tests/ChangeLog addition:
2010-04-05 Aidan Kehoe <kehoea@parhasard.net>
* automated/hash-table-tests.el:
Test the new built-in #'equalp hash table test. Test
#'define-hash-table-test.
* automated/lisp-tests.el:
When asserting that two objects are #'equalp, also assert that
their #'equalp-hash is identical.
man/ChangeLog addition:
2010-04-03 Aidan Kehoe <kehoea@parhasard.net>
* lispref/hash-tables.texi (Introduction to Hash Tables):
Document that we now support #'equalp as a hash table test by
default, and mention #'define-hash-table-test.
(Working With Hash Tables): Document #'define-hash-table-test.
src/ChangeLog addition:
2010-04-05 Aidan Kehoe <kehoea@parhasard.net>
* elhash.h:
* elhash.c (struct Hash_Table_Test, lisp_object_eql_equal)
(lisp_object_eql_hash, lisp_object_equal_equal)
(lisp_object_equal_hash, lisp_object_equalp_hash)
(lisp_object_equalp_equal, lisp_object_general_hash)
(lisp_object_general_equal, Feq_hash, Feql_hash, Fequal_hash)
(Fequalp_hash, define_hash_table_test, Fdefine_hash_table_test)
(init_elhash_once_early, mark_hash_table_tests, string_equalp_hash):
* glyphs.c (vars_of_glyphs):
Add a new hash table test in C, #'equalp.
Make it possible to specify new hash table tests with functions
define_hash_table_test, #'define-hash-table-test.
Use define_hash_table_test() in glyphs.c.
Expose the hash functions (besides that used for #'equal) to Lisp,
for people writing functions to be used with #'define-hash-table-test.
Call define_hash_table_test() very early in temacs, to create the
built-in hash table tests.
* ui-gtk.c (emacs_gtk_boxed_hash):
* specifier.h (struct specifier_methods):
* specifier.c (specifier_hash):
* rangetab.c (range_table_entry_hash, range_table_hash):
* number.c (bignum_hash, ratio_hash, bigfloat_hash):
* marker.c (marker_hash):
* lrecord.h (struct lrecord_implementation):
* keymap.c (keymap_hash):
* gui.c (gui_item_id_hash, gui_item_hash):
* glyphs.c (image_instance_hash, glyph_hash):
* glyphs-x.c (x_image_instance_hash):
* glyphs-msw.c (mswindows_image_instance_hash):
* glyphs-gtk.c (gtk_image_instance_hash):
* frame-msw.c (mswindows_set_title_from_ibyte):
* fontcolor.c (color_instance_hash, font_instance_hash):
* fontcolor-x.c (x_color_instance_hash):
* fontcolor-tty.c (tty_color_instance_hash):
* fontcolor-msw.c (mswindows_color_instance_hash):
* fontcolor-gtk.c (gtk_color_instance_hash):
* fns.c (bit_vector_hash):
* floatfns.c (float_hash):
* faces.c (face_hash):
* extents.c (extent_hash):
* events.c (event_hash):
* data.c (weak_list_hash, weak_box_hash):
* chartab.c (char_table_entry_hash, char_table_hash):
* bytecode.c (compiled_function_hash):
* alloc.c (vector_hash):
Change the various object hash methods to take a new EQUALP
parameter, hashing appropriately for #'equalp if it is true.
| author | Aidan Kehoe <kehoea@parhasard.net> |
|---|---|
| date | Mon, 05 Apr 2010 13:03:35 +0100 |
| parents | 6c6d78781d59 |
| children | b5611afbcc76 |
| rev | line source |
|---|---|
| 428 | 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. | |
| 5125 | 5 Copyright (C) 1995, 1996, 2001, 2002, 2004, 2005, 2010 Ben Wing. |
| 428 | 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 | |
| 814 | 24 /* This file has been Mule-ized. */ |
| 428 | 25 |
| 26 /* This file has been split into process.c and process-unix.c by | |
| 27 Kirill M. Katsnelson <kkm@kis.ru>, so please bash him and not | |
| 814 | 28 the original author(s). |
| 29 | |
| 30 Non-synch-subprocess stuff (mostly process environment) moved from | |
| 853 | 31 callproc.c, 4-3-02, Ben Wing. |
| 32 | |
| 33 callproc.c deleted entirely 5-23-02, Ben Wing. Good riddance! | |
| 34 */ | |
| 428 | 35 |
| 36 #include <config.h> | |
| 37 | |
| 38 #include "lisp.h" | |
| 39 | |
| 40 #include "buffer.h" | |
| 41 #include "commands.h" | |
| 800 | 42 #include "device.h" |
| 428 | 43 #include "events.h" |
| 800 | 44 #include "file-coding.h" |
| 428 | 45 #include "frame.h" |
| 46 #include "hash.h" | |
| 47 #include "insdel.h" | |
| 48 #include "lstream.h" | |
| 49 #include "opaque.h" | |
| 50 #include "process.h" | |
| 51 #include "procimpl.h" | |
| 816 | 52 #include "sysdep.h" |
| 428 | 53 #include "window.h" |
| 54 | |
| 55 #include "sysfile.h" | |
| 56 #include "sysproc.h" | |
| 859 | 57 #include "syssignal.h" |
| 428 | 58 #include "systime.h" |
| 59 #include "systty.h" | |
| 60 #include "syswait.h" | |
| 61 | |
| 2367 | 62 #ifdef WIN32_NATIVE |
| 63 #include "syswindows.h" | |
| 64 #endif | |
| 65 | |
| 863 | 66 Lisp_Object Qprocessp, Qprocess_live_p, Qprocess_readable_p; |
| 428 | 67 |
| 68 /* Process methods */ | |
| 69 struct process_methods the_process_methods; | |
| 70 | |
| 71 /* a process object is a network connection when its pid field a cons | |
| 72 (name of name of port we are connected to . foreign host name) */ | |
| 73 | |
| 74 /* Valid values of process->status_symbol */ | |
| 75 Lisp_Object Qrun, Qstop; | |
| 76 /* Qrun => Qopen, Qexit => Qclosed for "network connection" processes */ | |
| 77 Lisp_Object Qopen, Qclosed; | |
| 78 /* Protocol families */ | |
| 79 Lisp_Object Qtcp, Qudp; | |
| 80 | |
| 81 #ifdef HAVE_MULTICAST | |
| 82 Lisp_Object Qmulticast; /* Will be used for occasional warnings */ | |
| 83 #endif | |
| 84 | |
| 85 /* t means use pty, nil means use a pipe, | |
| 86 maybe other values to come. */ | |
| 87 Lisp_Object Vprocess_connection_type; | |
| 88 | |
| 89 /* Read comments to DEFVAR of this */ | |
| 90 int windowed_process_io; | |
| 91 | |
| 92 #ifdef PROCESS_IO_BLOCKING | |
| 93 /* List of port numbers or port names to set a blocking I/O mode. | |
| 94 Nil means set a non-blocking I/O mode [default]. */ | |
| 95 Lisp_Object network_stream_blocking_port_list; | |
| 96 #endif /* PROCESS_IO_BLOCKING */ | |
| 97 | |
| 98 /* Number of events of change of status of a process. */ | |
| 99 volatile int process_tick; | |
| 100 | |
| 101 /* Number of events for which the user or sentinel has been notified. */ | |
| 102 static int update_tick; | |
| 103 | |
| 104 /* Nonzero means delete a process right away if it exits. */ | |
| 105 int delete_exited_processes; | |
| 106 | |
| 853 | 107 /* Hash table which maps USIDs as returned by create_io_streams_cb to |
| 428 | 108 process objects. Processes are not GC-protected through this! */ |
| 109 struct hash_table *usid_to_process; | |
| 110 | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
111 /* Read-only to Lisp. See DEFUN Fprocess_list. */ |
| 428 | 112 Lisp_Object Vprocess_list; |
| 113 | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
114 /* Lisp variables; see docstrings below. */ |
| 442 | 115 Lisp_Object Vnull_device; |
| 771 | 116 Lisp_Object Vdefault_process_coding_system; |
| 853 | 117 Lisp_Object Vdefault_network_coding_system; |
| 563 | 118 Lisp_Object Qprocess_error; |
| 119 Lisp_Object Qnetwork_error; | |
| 771 | 120 Fixnum debug_process_io; |
| 814 | 121 Lisp_Object Vshell_file_name; |
| 122 Lisp_Object Vprocess_environment; | |
| 123 | |
| 124 /* Make sure egetenv() not called too soon */ | |
| 125 int env_initted; | |
| 126 | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
127 /* Internal Lisp variable. */ |
| 814 | 128 Lisp_Object Vlisp_EXEC_SUFFIXES; |
| 129 | |
| 428 | 130 |
| 131 | |
| 1204 | 132 static const struct memory_description process_description [] = { |
| 133 #define MARKED_SLOT(x) { XD_LISP_OBJECT, offsetof (Lisp_Process, x) }, | |
| 134 #include "process-slots.h" | |
| 934 | 135 { XD_END } |
| 136 }; | |
| 137 | |
| 428 | 138 static Lisp_Object |
| 444 | 139 mark_process (Lisp_Object object) |
| 428 | 140 { |
| 444 | 141 Lisp_Process *process = XPROCESS (object); |
| 1204 | 142 #define MARKED_SLOT(x) mark_object (process->x); |
| 143 #include "process-slots.h" | |
| 144 return Qnil; | |
| 428 | 145 } |
| 146 | |
| 147 static void | |
| 4846 | 148 print_process (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
| 428 | 149 { |
| 4846 | 150 Lisp_Process *process = XPROCESS (obj); |
| 428 | 151 |
| 152 if (print_readably) | |
|
5142
f965e31a35f0
reduce lcrecord headers to 2 words, rename printing_unreadable_object
Ben Wing <ben@xemacs.org>
parents:
5127
diff
changeset
|
153 printing_unreadable_lisp_object (obj, XSTRING_DATA (process->name)); |
| 428 | 154 |
| 155 if (!escapeflag) | |
| 156 { | |
| 444 | 157 print_internal (process->name, printcharfun, 0); |
| 428 | 158 } |
| 159 else | |
| 160 { | |
| 4846 | 161 int netp = network_connection_p (obj); |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
162 write_ascstring (printcharfun, |
| 826 | 163 netp ? GETTEXT ("#<network connection ") : |
| 164 GETTEXT ("#<process ")); | |
| 444 | 165 print_internal (process->name, printcharfun, 1); |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
166 write_ascstring (printcharfun, (netp ? " " : " pid ")); |
| 444 | 167 print_internal (process->pid, printcharfun, 1); |
| 800 | 168 write_fmt_string_lisp (printcharfun, " state:%S", 1, process->status_symbol); |
| 444 | 169 MAYBE_PROCMETH (print_process_data, (process, printcharfun)); |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
170 write_ascstring (printcharfun, ">"); |
| 428 | 171 } |
| 172 } | |
| 173 | |
| 174 #ifdef HAVE_WINDOW_SYSTEM | |
| 440 | 175 extern void debug_process_finalization (Lisp_Process *p); |
| 428 | 176 #endif /* HAVE_WINDOW_SYSTEM */ |
| 177 | |
| 178 static void | |
|
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
179 finalize_process (Lisp_Object obj) |
| 428 | 180 { |
| 181 /* #### this probably needs to be tied into the tty event loop */ | |
| 182 /* #### when there is one */ | |
|
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
183 Lisp_Process *p = XPROCESS (obj); |
| 428 | 184 #ifdef HAVE_WINDOW_SYSTEM |
|
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
185 debug_process_finalization (p); |
| 428 | 186 #endif /* HAVE_WINDOW_SYSTEM */ |
| 187 | |
| 188 if (p->process_data) | |
| 189 { | |
|
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
190 MAYBE_PROCMETH (finalize_process_data, (p)); |
| 5125 | 191 xfree (p->process_data); |
|
5169
6c6d78781d59
cleanup of code related to xfree(), better KKCC backtrace capabilities, document XD_INLINE_LISP_OBJECT_BLOCK_PTR, fix some memory leaks, other code cleanup
Ben Wing <ben@xemacs.org>
parents:
5142
diff
changeset
|
192 p->process_data = 0; |
| 428 | 193 } |
| 194 } | |
| 195 | |
|
5118
e0db3c197671
merge up to latest default branch, doesn't compile yet
Ben Wing <ben@xemacs.org>
diff
changeset
|
196 DEFINE_NODUMP_LISP_OBJECT ("process", process, |
|
5124
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
197 mark_process, print_process, finalize_process, |
|
623d57b7fbe8
separate regular and disksave finalization, print method fixes.
Ben Wing <ben@xemacs.org>
parents:
5118
diff
changeset
|
198 0, 0, process_description, Lisp_Process); |
| 428 | 199 |
| 200 /************************************************************************/ | |
| 201 /* basic process accessors */ | |
| 202 /************************************************************************/ | |
| 203 | |
| 771 | 204 /* This function returns low-level streams, connected directly to the child |
| 205 process, rather than en/decoding streams */ | |
| 428 | 206 void |
| 853 | 207 get_process_streams (Lisp_Process *p, Lisp_Object *instr, Lisp_Object *outstr, |
| 208 Lisp_Object *errstr) | |
| 428 | 209 { |
| 210 assert (p); | |
| 853 | 211 assert (NILP (p->pipe_instream) || LSTREAMP (p->pipe_instream)); |
| 212 assert (NILP (p->pipe_outstream) || LSTREAMP (p->pipe_outstream)); | |
| 213 assert (NILP (p->pipe_errstream) || LSTREAMP (p->pipe_errstream)); | |
| 428 | 214 *instr = p->pipe_instream; |
| 215 *outstr = p->pipe_outstream; | |
| 853 | 216 *errstr = p->pipe_errstream; |
| 428 | 217 } |
| 218 | |
| 853 | 219 /* Given a USID referring to either a process's instream or errstream, |
| 220 return the associated process. */ | |
| 440 | 221 Lisp_Process * |
| 428 | 222 get_process_from_usid (USID usid) |
| 223 { | |
| 442 | 224 const void *vval; |
| 428 | 225 |
| 226 assert (usid != USID_ERROR && usid != USID_DONTHASH); | |
| 227 | |
| 442 | 228 if (gethash ((const void*)usid, usid_to_process, &vval)) |
| 428 | 229 { |
| 444 | 230 Lisp_Object process; |
| 5013 | 231 process = GET_LISP_FROM_VOID (vval); |
| 444 | 232 return XPROCESS (process); |
| 428 | 233 } |
| 234 else | |
| 235 return 0; | |
| 236 } | |
| 237 | |
| 238 int | |
| 853 | 239 get_process_selected_p (Lisp_Process *p, int do_err) |
| 428 | 240 { |
| 853 | 241 return do_err ? p->err_selected : p->in_selected; |
| 428 | 242 } |
| 243 | |
| 244 void | |
| 853 | 245 set_process_selected_p (Lisp_Process *p, int in_selected, int err_selected) |
| 428 | 246 { |
| 853 | 247 p->in_selected = !!in_selected; |
| 248 p->err_selected = !!err_selected; | |
| 428 | 249 } |
| 250 | |
| 251 int | |
| 440 | 252 connected_via_filedesc_p (Lisp_Process *p) |
| 428 | 253 { |
| 254 return MAYBE_INT_PROCMETH (tooltalk_connection_p, (p)); | |
| 255 } | |
| 256 | |
| 257 #ifdef HAVE_SOCKETS | |
| 258 int | |
| 259 network_connection_p (Lisp_Object process) | |
| 260 { | |
| 261 return CONSP (XPROCESS (process)->pid); | |
| 262 } | |
| 263 #endif | |
| 264 | |
| 265 DEFUN ("processp", Fprocessp, 1, 1, 0, /* | |
| 266 Return t if OBJECT is a process. | |
| 267 */ | |
| 444 | 268 (object)) |
| 428 | 269 { |
| 444 | 270 return PROCESSP (object) ? Qt : Qnil; |
| 428 | 271 } |
| 272 | |
| 440 | 273 DEFUN ("process-live-p", Fprocess_live_p, 1, 1, 0, /* |
| 274 Return t if OBJECT is a process that is alive. | |
| 275 */ | |
| 444 | 276 (object)) |
| 440 | 277 { |
| 444 | 278 return PROCESSP (object) && PROCESS_LIVE_P (XPROCESS (object)) |
| 279 ? Qt : Qnil; | |
| 440 | 280 } |
| 281 | |
| 863 | 282 #if 0 |
| 283 /* This is a reasonable definition for this new primitive. Kyle sez: | |
| 284 | |
| 285 "The patch looks OK to me except for the creation and exporting of the | |
| 286 Fprocess_readable_p function. I don't think a new Lisp function | |
| 287 should be created until we know something actually needs it. If | |
| 288 we later want to give process-readable-p different semantics it | |
| 289 may be hard to do it and stay compatible with what we hastily | |
| 290 create today." | |
| 291 | |
| 292 He's right, not yet. Let's discuss the semantics on XEmacs Design | |
| 293 before enabling this. | |
| 294 */ | |
| 295 DEFUN ("process-readable-p", Fprocess_readable_p, 1, 1, 0, /* | |
| 296 Return t if OBJECT is a process from which input may be available. | |
| 297 */ | |
| 298 (object)) | |
| 299 { | |
| 300 return PROCESSP (object) && PROCESS_READABLE_P (XPROCESS (object)) | |
| 301 ? Qt : Qnil; | |
| 302 } | |
| 303 #endif | |
| 304 | |
| 428 | 305 DEFUN ("process-list", Fprocess_list, 0, 0, 0, /* |
| 306 Return a list of all processes. | |
| 307 */ | |
| 308 ()) | |
| 309 { | |
| 310 return Fcopy_sequence (Vprocess_list); | |
| 311 } | |
| 312 | |
| 313 DEFUN ("get-process", Fget_process, 1, 1, 0, /* | |
| 444 | 314 Return the process named PROCESS-NAME (a string), or nil if there is none. |
| 315 PROCESS-NAME may also be a process; if so, the value is that process. | |
| 428 | 316 */ |
| 444 | 317 (process_name)) |
| 428 | 318 { |
| 444 | 319 if (PROCESSP (process_name)) |
| 320 return process_name; | |
| 428 | 321 |
| 322 if (!gc_in_progress) | |
| 323 /* this only gets called during GC when emacs is going away as a result | |
| 324 of a signal or crash. */ | |
| 444 | 325 CHECK_STRING (process_name); |
| 428 | 326 |
| 444 | 327 { |
| 328 LIST_LOOP_2 (process, Vprocess_list) | |
| 329 if (internal_equal (process_name, XPROCESS (process)->name, 0)) | |
| 330 return process; | |
| 331 } | |
| 428 | 332 return Qnil; |
| 333 } | |
| 334 | |
| 335 DEFUN ("get-buffer-process", Fget_buffer_process, 1, 1, 0, /* | |
| 336 Return the (or, a) process associated with BUFFER. | |
| 337 BUFFER may be a buffer or the name of one. | |
| 338 */ | |
| 444 | 339 (buffer)) |
| 428 | 340 { |
| 444 | 341 if (NILP (buffer)) return Qnil; |
| 342 buffer = Fget_buffer (buffer); | |
| 343 if (NILP (buffer)) return Qnil; | |
| 428 | 344 |
| 444 | 345 { |
| 346 LIST_LOOP_2 (process, Vprocess_list) | |
| 347 if (EQ (XPROCESS (process)->buffer, buffer)) | |
| 348 return process; | |
| 349 } | |
| 428 | 350 return Qnil; |
| 351 } | |
| 352 | |
| 353 /* This is how commands for the user decode process arguments. It | |
| 354 accepts a process, a process name, a buffer, a buffer name, or nil. | |
| 355 Buffers denote the first process in the buffer, and nil denotes the | |
| 356 current buffer. */ | |
| 357 | |
| 358 static Lisp_Object | |
| 359 get_process (Lisp_Object name) | |
| 360 { | |
| 444 | 361 Lisp_Object buffer; |
| 428 | 362 |
| 363 #ifdef I18N3 | |
| 364 /* #### Look more closely into translating process names. */ | |
| 365 #endif | |
| 366 | |
| 367 /* This may be called during a GC from process_send_signal() from | |
| 2500 | 368 kill_buffer_processes() if emacs decides to ABORT(). */ |
| 428 | 369 if (PROCESSP (name)) |
| 370 return name; | |
| 444 | 371 else if (STRINGP (name)) |
| 428 | 372 { |
| 444 | 373 Lisp_Object object = Fget_process (name); |
| 374 if (PROCESSP (object)) | |
| 375 return object; | |
| 376 | |
| 377 buffer = Fget_buffer (name); | |
| 378 if (BUFFERP (buffer)) | |
| 379 goto have_buffer_object; | |
| 380 | |
| 563 | 381 invalid_argument ("Process does not exist", name); |
| 428 | 382 } |
| 383 else if (NILP (name)) | |
| 444 | 384 { |
| 385 buffer = Fcurrent_buffer (); | |
| 386 goto have_buffer_object; | |
| 387 } | |
| 388 else if (BUFFERP (name)) | |
| 389 { | |
| 390 Lisp_Object process; | |
| 391 buffer = name; | |
| 428 | 392 |
| 444 | 393 have_buffer_object: |
| 394 process = Fget_buffer_process (buffer); | |
| 395 if (PROCESSP (process)) | |
| 396 return process; | |
| 397 | |
| 563 | 398 invalid_argument ("Buffer has no process", buffer); |
| 428 | 399 } |
| 400 else | |
| 444 | 401 return get_process (Fsignal (Qwrong_type_argument, |
| 771 | 402 (list2 (build_msg_string ("process or buffer or nil"), |
| 444 | 403 name)))); |
| 428 | 404 } |
| 405 | |
| 406 DEFUN ("process-id", Fprocess_id, 1, 1, 0, /* | |
| 407 Return the process id of PROCESS. | |
| 408 This is the pid of the Unix process which PROCESS uses or talks to. | |
| 409 For a network connection, this value is a cons of | |
| 410 (foreign-network-port . foreign-host-name). | |
| 411 */ | |
| 444 | 412 (process)) |
| 428 | 413 { |
| 414 Lisp_Object pid; | |
| 444 | 415 CHECK_PROCESS (process); |
| 428 | 416 |
| 444 | 417 pid = XPROCESS (process)->pid; |
| 418 if (network_connection_p (process)) | |
| 428 | 419 /* return Qnil; */ |
| 420 return Fcons (Fcar (pid), Fcdr (pid)); | |
| 421 else | |
| 422 return pid; | |
| 423 } | |
| 424 | |
| 425 DEFUN ("process-name", Fprocess_name, 1, 1, 0, /* | |
| 426 Return the name of PROCESS, as a string. | |
| 427 This is the name of the program invoked in PROCESS, | |
| 428 possibly modified to make it unique among process names. | |
| 429 */ | |
| 444 | 430 (process)) |
| 428 | 431 { |
| 444 | 432 CHECK_PROCESS (process); |
| 433 return XPROCESS (process)->name; | |
| 428 | 434 } |
| 435 | |
| 436 DEFUN ("process-command", Fprocess_command, 1, 1, 0, /* | |
| 437 Return the command that was executed to start PROCESS. | |
| 438 This is a list of strings, the first string being the program executed | |
| 439 and the rest of the strings being the arguments given to it. | |
| 440 */ | |
| 444 | 441 (process)) |
| 428 | 442 { |
| 444 | 443 CHECK_PROCESS (process); |
| 444 return XPROCESS (process)->command; | |
| 428 | 445 } |
| 446 | |
| 447 | |
| 448 /************************************************************************/ | |
| 449 /* creating a process */ | |
| 450 /************************************************************************/ | |
| 451 | |
| 563 | 452 DOESNT_RETURN |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
453 report_process_error (const Ascbyte *reason, Lisp_Object data) |
| 563 | 454 { |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
455 report_error_with_errno (Qprocess_error, reason, data); |
| 563 | 456 } |
| 457 | |
| 458 DOESNT_RETURN | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
459 report_network_error (const Ascbyte *reason, Lisp_Object data) |
| 563 | 460 { |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
461 report_error_with_errno (Qnetwork_error, reason, data); |
| 563 | 462 } |
| 463 | |
| 428 | 464 Lisp_Object |
| 465 make_process_internal (Lisp_Object name) | |
| 466 { | |
|
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
467 Lisp_Object name1; |
| 428 | 468 int i; |
|
5127
a9c41067dd88
more cleanups, terminology clarification, lots of doc work
Ben Wing <ben@xemacs.org>
parents:
5125
diff
changeset
|
469 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (process); |
|
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
470 Lisp_Process *p = XPROCESS (obj); |
| 428 | 471 |
| 1204 | 472 #define MARKED_SLOT(x) p->x = Qnil; |
| 473 #include "process-slots.h" | |
| 474 | |
| 428 | 475 /* If name is already in use, modify it until it is unused. */ |
| 476 name1 = name; | |
| 477 for (i = 1; ; i++) | |
| 478 { | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
479 Ascbyte suffix[10]; |
| 428 | 480 Lisp_Object tem = Fget_process (name1); |
| 481 if (NILP (tem)) | |
| 482 break; | |
| 483 sprintf (suffix, "<%d>", i); | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
484 name1 = concat2 (name, build_ascstring (suffix)); |
| 428 | 485 } |
| 486 name = name1; | |
| 487 p->name = name; | |
| 488 | |
| 489 p->mark = Fmake_marker (); | |
| 853 | 490 p->stderr_mark = Fmake_marker (); |
| 428 | 491 p->status_symbol = Qrun; |
| 492 | |
| 493 MAYBE_PROCMETH (alloc_process_data, (p)); | |
| 494 | |
|
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
495 Vprocess_list = Fcons (obj, Vprocess_list); |
|
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
496 return obj; |
| 428 | 497 } |
| 498 | |
| 499 void | |
| 853 | 500 init_process_io_handles (Lisp_Process *p, void* in, void* out, void* err, |
| 501 int flags) | |
| 428 | 502 { |
| 853 | 503 USID in_usid, err_usid; |
| 771 | 504 Lisp_Object incode, outcode; |
| 505 | |
| 853 | 506 if (flags & STREAM_NETWORK_CONNECTION) |
| 507 { | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
508 if (!LISTP (Vdefault_network_coding_system) || |
| 853 | 509 NILP (incode = (find_coding_system_for_text_file |
| 510 (Fcar (Vdefault_network_coding_system), 1))) || | |
| 511 NILP (outcode = (find_coding_system_for_text_file | |
| 512 (Fcdr (Vdefault_network_coding_system), 0)))) | |
| 513 signal_error (Qinvalid_state, | |
| 514 "Bogus value for `default-network-coding-system'", | |
| 515 Vdefault_network_coding_system); | |
| 516 } | |
| 517 else | |
| 518 { | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
519 if (!LISTP (Vdefault_process_coding_system) || |
| 853 | 520 NILP (incode = (find_coding_system_for_text_file |
| 521 (Fcar (Vdefault_process_coding_system), 1))) || | |
| 522 NILP (outcode = (find_coding_system_for_text_file | |
| 523 (Fcdr (Vdefault_process_coding_system), 0)))) | |
| 524 signal_error (Qinvalid_state, | |
| 525 "Bogus value for `default-process-coding-system'", | |
| 526 Vdefault_process_coding_system); | |
| 527 } | |
| 771 | 528 |
| 784 | 529 if (!NILP (Vcoding_system_for_read) && |
| 530 NILP (incode = (find_coding_system_for_text_file | |
| 531 (Vcoding_system_for_read, 1)))) | |
| 532 signal_error (Qinvalid_state, | |
| 533 "Bogus value for `coding-system-for-read'", | |
| 534 Vcoding_system_for_read); | |
| 535 | |
| 536 if (!NILP (Vcoding_system_for_write) && | |
| 537 NILP (outcode = (find_coding_system_for_text_file | |
| 538 (Vcoding_system_for_write, 0)))) | |
| 539 signal_error (Qinvalid_state, | |
| 540 "Bogus value for `coding-system-for-write'", | |
| 541 Vcoding_system_for_write); | |
| 542 | |
| 853 | 543 event_stream_create_io_streams (in, out, err, |
| 544 &p->pipe_instream, | |
| 545 &p->pipe_outstream, | |
| 546 &p->pipe_errstream, | |
| 547 &in_usid, &err_usid, | |
| 548 flags); | |
| 428 | 549 |
| 853 | 550 if (in_usid == USID_ERROR || err_usid == USID_ERROR) |
| 563 | 551 signal_error (Qprocess_error, "Setting up communication with subprocess", |
| 853 | 552 wrap_process (p)); |
| 428 | 553 |
| 853 | 554 if (in_usid != USID_DONTHASH) |
| 428 | 555 { |
| 444 | 556 Lisp_Object process = Qnil; |
| 793 | 557 process = wrap_process (p); |
| 5013 | 558 puthash ((const void*) in_usid, STORE_LISP_IN_VOID (process), usid_to_process); |
| 428 | 559 } |
| 560 | |
| 853 | 561 if (err_usid != USID_DONTHASH) |
| 562 { | |
| 563 Lisp_Object process = Qnil; | |
| 564 process = wrap_process (p); | |
| 5013 | 565 puthash ((const void*) err_usid, STORE_LISP_IN_VOID (process), |
| 853 | 566 usid_to_process); |
| 567 } | |
| 568 | |
| 569 MAYBE_PROCMETH (init_process_io_handles, (p, in, out, err, flags)); | |
| 428 | 570 |
| 771 | 571 p->coding_instream = |
| 800 | 572 make_coding_input_stream (XLSTREAM (p->pipe_instream), incode, |
| 573 CODING_DECODE, 0); | |
| 853 | 574 if (!NILP (p->pipe_errstream)) |
| 575 p->coding_errstream = | |
| 576 make_coding_input_stream | |
| 577 (XLSTREAM (p->pipe_errstream), incode, CODING_DECODE, 0); | |
| 771 | 578 p->coding_outstream = |
| 800 | 579 make_coding_output_stream (XLSTREAM (p->pipe_outstream), outcode, |
| 580 CODING_ENCODE, 0); | |
| 428 | 581 } |
| 582 | |
| 583 static void | |
| 584 create_process (Lisp_Object process, Lisp_Object *argv, int nargv, | |
| 853 | 585 Lisp_Object program, Lisp_Object cur_dir, |
| 586 int separate_err) | |
| 428 | 587 { |
| 440 | 588 Lisp_Process *p = XPROCESS (process); |
| 428 | 589 int pid; |
| 590 | |
| 591 /* *_create_process may change status_symbol, if the process | |
| 592 is a kind of "fire-and-forget" (no I/O, unwaitable) */ | |
| 593 p->status_symbol = Qrun; | |
| 594 p->exit_code = 0; | |
| 595 | |
| 853 | 596 pid = PROCMETH (create_process, (p, argv, nargv, program, cur_dir, |
| 597 separate_err)); | |
| 428 | 598 |
| 599 p->pid = make_int (pid); | |
| 863 | 600 if (PROCESS_READABLE_P (p)) |
| 853 | 601 event_stream_select_process (p, 1, 1); |
| 428 | 602 } |
| 603 | |
| 604 /* This function is the unwind_protect form for Fstart_process_internal. If | |
| 444 | 605 PROCESS doesn't have its pid set, then we know someone has signalled |
| 428 | 606 an error and the process wasn't started successfully, so we should |
| 607 remove it from the process list. */ | |
| 444 | 608 static void remove_process (Lisp_Object process); |
| 428 | 609 static Lisp_Object |
| 444 | 610 start_process_unwind (Lisp_Object process) |
| 428 | 611 { |
| 444 | 612 /* Was PROCESS started successfully? */ |
| 613 if (EQ (XPROCESS (process)->pid, Qnil)) | |
| 614 remove_process (process); | |
| 428 | 615 return Qnil; |
| 616 } | |
| 617 | |
| 618 DEFUN ("start-process-internal", Fstart_process_internal, 3, MANY, 0, /* | |
| 853 | 619 Internal function to start a program in a subprocess. |
| 620 Lisp callers should use `start-process' instead. | |
| 621 | |
| 622 Returns the process object for it. | |
| 428 | 623 Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS |
| 624 NAME is name for process. It is modified if necessary to make it unique. | |
| 625 BUFFER is the buffer or (buffer-name) to associate with the process. | |
| 626 Process output goes at end of that buffer, unless you specify | |
| 627 an output stream or filter function to handle the output. | |
| 628 BUFFER may be also nil, meaning that this process is not associated | |
| 853 | 629 with any buffer. |
| 630 BUFFER can also have the form (REAL-BUFFER STDERR-BUFFER); in that case, | |
| 631 REAL-BUFFER says what to do with standard output, as above, | |
| 632 while STDERR-BUFFER says what to do with standard error in the child. | |
| 633 STDERR-BUFFER may be nil (discard standard error output, unless a stderr | |
| 634 filter is set). Note that if you do not use this form at process creation, | |
| 635 stdout and stderr will be mixed in the output buffer, and this cannot be | |
| 636 changed, even by setting a stderr filter. | |
| 428 | 637 Third arg is program file name. It is searched for as in the shell. |
| 638 Remaining arguments are strings to give program as arguments. | |
| 853 | 639 |
| 640 Read and write coding systems for the process are determined from | |
| 641 `coding-system-for-read' and `coding-system-for-write' (intended as | |
| 642 overriding coding systems to be *bound* by Lisp code, not set), or | |
| 643 from `default-process-coding-system' if either or both are nil. You can | |
| 644 change the coding systems later on using `set-process-coding-system', | |
| 645 `set-process-input-coding-system', or `set-process-output-coding-system'. | |
| 646 | |
| 647 See also `set-process-filter' and `set-process-stderr-filter'. | |
|
4693
80cd90837ac5
Add argument information to remaining MANY or UNEVALLED C subrs.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3025
diff
changeset
|
648 |
|
80cd90837ac5
Add argument information to remaining MANY or UNEVALLED C subrs.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3025
diff
changeset
|
649 arguments: (NAME BUFFER PROGRAM &rest PROGRAM-ARGS) |
| 428 | 650 */ |
| 651 (int nargs, Lisp_Object *args)) | |
| 652 { | |
| 653 /* This function can call lisp */ | |
| 853 | 654 Lisp_Object buffer, stderr_buffer, name, program, process, current_dir; |
| 655 int separate_stderr; | |
| 428 | 656 Lisp_Object tem; |
| 910 | 657 int i; |
| 428 | 658 int speccount = specpdl_depth (); |
| 659 struct gcpro gcpro1, gcpro2, gcpro3; | |
| 660 | |
| 661 name = args[0]; | |
| 662 buffer = args[1]; | |
| 663 program = args[2]; | |
| 664 current_dir = Qnil; | |
| 665 | |
| 666 /* Protect against various file handlers doing GCs below. */ | |
| 667 GCPRO3 (buffer, program, current_dir); | |
| 668 | |
| 853 | 669 if (CONSP (buffer)) |
| 670 { | |
| 671 if (!CONSP (XCDR (buffer))) | |
| 672 invalid_argument ("Invalid BUFFER argument to `start-process'", | |
| 673 buffer); | |
| 674 if (!NILP (XCDR (XCDR (buffer)))) | |
| 675 invalid_argument ("Invalid BUFFER argument to `start-process'", | |
| 676 buffer); | |
| 677 stderr_buffer = XCAR (XCDR (buffer)); | |
| 678 buffer = XCAR (buffer); | |
| 679 separate_stderr = 1; | |
| 680 } | |
| 681 else | |
| 682 { | |
| 683 stderr_buffer = Qnil; | |
| 684 separate_stderr = 0; | |
| 685 } | |
| 686 | |
| 428 | 687 if (!NILP (buffer)) |
| 688 buffer = Fget_buffer_create (buffer); | |
| 853 | 689 if (!NILP (stderr_buffer)) |
| 690 stderr_buffer = Fget_buffer_create (stderr_buffer); | |
| 428 | 691 |
| 692 CHECK_STRING (name); | |
| 693 CHECK_STRING (program); | |
| 910 | 694 for (i = 3; i < nargs; ++i) |
| 695 CHECK_STRING (args[i]); | |
| 428 | 696 |
| 697 /* Make sure that the child will be able to chdir to the current | |
| 502 | 698 buffer's current directory, or its unhandled equivalent. [[ We |
| 428 | 699 can't just have the child check for an error when it does the |
| 502 | 700 chdir, since it's in a vfork. ]] -- not any more, we don't use |
| 701 vfork. -ben | |
| 428 | 702 |
| 502 | 703 Note: These calls are spread out to insure that the return values |
| 704 of the calls (which may be newly-created strings) are properly | |
| 705 GC-protected. */ | |
| 428 | 706 current_dir = current_buffer->directory; |
| 502 | 707 /* If the current dir has no terminating slash, we'll get undesirable |
| 708 results, so put the slash back. */ | |
| 709 current_dir = Ffile_name_as_directory (current_dir); | |
| 428 | 710 current_dir = Funhandled_file_name_directory (current_dir); |
| 711 current_dir = expand_and_dir_to_file (current_dir, Qnil); | |
| 712 | |
| 713 #if 0 /* This loser breaks ange-ftp */ | |
| 714 /* dmoore - if you re-enable this code, you have to gcprotect | |
| 715 current_buffer through the above calls. */ | |
| 716 if (NILP (Ffile_accessible_directory_p (current_dir))) | |
| 563 | 717 signal_error (Qprocess_error, "Setting current directory", |
| 718 current_buffer->directory); | |
| 428 | 719 #endif /* 0 */ |
| 720 | |
| 721 /* If program file name is not absolute, search our path for it */ | |
| 826 | 722 if (!IS_DIRECTORY_SEP (string_byte (program, 0)) |
| 428 | 723 && !(XSTRING_LENGTH (program) > 1 |
| 826 | 724 && IS_DEVICE_SEP (string_byte (program, 1)))) |
| 428 | 725 { |
| 726 struct gcpro ngcpro1; | |
| 727 | |
| 728 tem = Qnil; | |
| 729 NGCPRO1 (tem); | |
| 730 locate_file (Vexec_path, program, Vlisp_EXEC_SUFFIXES, &tem, X_OK); | |
| 731 if (NILP (tem)) | |
| 563 | 732 signal_error (Qprocess_error, "Searching for program", program); |
| 428 | 733 program = Fexpand_file_name (tem, Qnil); |
| 734 NUNGCPRO; | |
| 735 } | |
| 736 else | |
| 737 { | |
| 442 | 738 /* we still need to canonicalize it and ensure it has the proper |
| 739 ending, e.g. .exe */ | |
| 740 struct gcpro ngcpro1; | |
| 741 | |
| 742 tem = Qnil; | |
| 743 NGCPRO1 (tem); | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
744 locate_file (list1 (build_ascstring ("")), program, Vlisp_EXEC_SUFFIXES, |
| 442 | 745 &tem, X_OK); |
| 746 if (NILP (tem)) | |
| 563 | 747 signal_error (Qprocess_error, "Searching for program", program); |
| 442 | 748 program = tem; |
| 749 NUNGCPRO; | |
| 428 | 750 } |
| 751 | |
| 442 | 752 if (!NILP (Ffile_directory_p (program))) |
| 753 invalid_operation ("Specified program for new process is a directory", | |
| 754 program); | |
| 755 | |
| 444 | 756 process = make_process_internal (name); |
| 428 | 757 |
| 444 | 758 XPROCESS (process)->buffer = buffer; |
| 853 | 759 XPROCESS (process)->stderr_buffer = stderr_buffer; |
| 760 XPROCESS (process)->separate_stderr = separate_stderr; | |
| 814 | 761 XPROCESS (process)->command = Flist (nargs - 2, args + 2); |
| 428 | 762 |
| 763 /* Make the process marker point into the process buffer (if any). */ | |
| 764 if (!NILP (buffer)) | |
| 444 | 765 Fset_marker (XPROCESS (process)->mark, |
| 428 | 766 make_int (BUF_ZV (XBUFFER (buffer))), buffer); |
| 853 | 767 if (!NILP (stderr_buffer)) |
| 768 Fset_marker (XPROCESS (process)->stderr_mark, | |
| 769 make_int (BUF_ZV (XBUFFER (stderr_buffer))), stderr_buffer); | |
| 428 | 770 |
| 771 /* If an error occurs and we can't start the process, we want to | |
| 772 remove it from the process list. This means that each error | |
| 773 check in create_process doesn't need to call remove_process | |
| 774 itself; it's all taken care of here. */ | |
| 444 | 775 record_unwind_protect (start_process_unwind, process); |
| 428 | 776 |
| 853 | 777 create_process (process, args + 3, nargs - 3, program, current_dir, |
| 778 separate_stderr); | |
| 428 | 779 |
| 780 UNGCPRO; | |
| 771 | 781 return unbind_to_1 (speccount, process); |
| 428 | 782 } |
| 783 | |
| 784 | |
| 785 #ifdef HAVE_SOCKETS | |
| 786 | |
| 787 | |
| 788 /* #### The network support is fairly synthetical. What we actually | |
| 789 need is a single function, which supports all datagram, stream and | |
| 790 packet stream connections, arbitrary protocol families should they | |
| 791 be supported by the target system, multicast groups, in both data | |
| 792 and control rooted/nonrooted flavors, service quality etc whatever | |
| 793 is supported by the underlying network. | |
| 794 | |
| 795 It must accept a property list describing the connection. The current | |
| 796 functions must then go to lisp and provide a suitable list for the | |
| 797 generalized connection function. | |
| 798 | |
| 799 Both UNIX and Win32 support BSD sockets, and there are many extensions | |
| 800 available (Sockets 2 spec). | |
| 801 | |
| 802 A todo is define a consistent set of properties abstracting a | |
| 803 network connection. -kkm | |
| 804 */ | |
| 805 | |
| 806 | |
| 807 /* open a TCP network connection to a given HOST/SERVICE. Treated | |
| 808 exactly like a normal process when reading and writing. Only | |
| 809 differences are in status display and process deletion. A network | |
| 810 connection has no PID; you cannot signal it. All you can do is | |
| 811 deactivate and close it via delete-process */ | |
| 812 | |
| 442 | 813 DEFUN ("open-network-stream-internal", Fopen_network_stream_internal, 4, 5, |
| 814 0, /* | |
| 428 | 815 Open a TCP connection for a service to a host. |
| 444 | 816 Return a process object to represent the connection. |
| 428 | 817 Input and output work as for subprocesses; `delete-process' closes it. |
| 818 | |
| 819 NAME is name for process. It is modified if necessary to make it unique. | |
| 820 BUFFER is the buffer (or buffer-name) to associate with the process. | |
| 821 Process output goes at end of that buffer, unless you specify | |
| 822 an output stream or filter function to handle the output. | |
| 823 BUFFER may also be nil, meaning that this process is not associated | |
| 824 with any buffer. | |
| 444 | 825 Third arg HOST (a string) is the name of the host to connect to, |
| 826 or its IP address. | |
| 827 Fourth arg SERVICE is the name of the service desired (a string), | |
| 828 or an integer specifying a port number to connect to. | |
| 3025 | 829 Optional fifth arg PROTOCOL is a network protocol. Currently only `tcp' |
| 830 (Transmission Control Protocol) and `udp' (User Datagram Protocol) are | |
| 831 supported. When omitted, `tcp' is assumed. | |
| 428 | 832 |
| 442 | 833 Output via `process-send-string' and input via buffer or filter (see |
| 428 | 834 `set-process-filter') are stream-oriented. That means UDP datagrams are |
| 835 not guaranteed to be sent and received in discrete packets. (But small | |
| 836 datagrams around 500 bytes that are not truncated by `process-send-string' | |
| 444 | 837 are usually fine.) Note further that the UDP protocol does not guard |
| 838 against lost packets. | |
| 428 | 839 */ |
| 840 (name, buffer, host, service, protocol)) | |
| 841 { | |
| 842 /* This function can GC */ | |
| 444 | 843 Lisp_Object process = Qnil; |
| 428 | 844 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, ngcpro1; |
| 845 void *inch, *outch; | |
| 846 | |
| 847 GCPRO5 (name, buffer, host, service, protocol); | |
| 848 CHECK_STRING (name); | |
| 849 | |
| 771 | 850 if (NILP (protocol)) |
| 428 | 851 protocol = Qtcp; |
| 852 else | |
| 853 CHECK_SYMBOL (protocol); | |
| 854 | |
| 855 /* Since this code is inside HAVE_SOCKETS, existence of | |
| 856 open_network_stream is mandatory */ | |
| 857 PROCMETH (open_network_stream, (name, host, service, protocol, | |
| 858 &inch, &outch)); | |
| 859 | |
| 860 if (!NILP (buffer)) | |
| 861 buffer = Fget_buffer_create (buffer); | |
| 444 | 862 process = make_process_internal (name); |
| 863 NGCPRO1 (process); | |
| 428 | 864 |
| 444 | 865 XPROCESS (process)->pid = Fcons (service, host); |
| 866 XPROCESS (process)->buffer = buffer; | |
| 771 | 867 init_process_io_handles (XPROCESS (process), (void *) inch, (void *) outch, |
| 853 | 868 (void *) -1, |
| 428 | 869 STREAM_NETWORK_CONNECTION); |
| 870 | |
| 853 | 871 event_stream_select_process (XPROCESS (process), 1, 1); |
| 428 | 872 |
| 1204 | 873 NUNGCPRO; |
| 428 | 874 UNGCPRO; |
| 444 | 875 return process; |
| 428 | 876 } |
| 877 | |
| 878 #ifdef HAVE_MULTICAST | |
| 879 | |
| 880 DEFUN ("open-multicast-group-internal", Fopen_multicast_group_internal, 5, 5, 0, /* | |
| 881 Open a multicast connection on the specified dest/port/ttl. | |
| 444 | 882 Return a process object to represent the connection. |
| 428 | 883 Input and output work as for subprocesses; `delete-process' closes it. |
| 884 | |
| 885 NAME is name for process. It is modified if necessary to make it unique. | |
| 886 BUFFER is the buffer (or buffer-name) to associate with the process. | |
| 887 Process output goes at end of that buffer, unless you specify | |
| 888 an output stream or filter function to handle the output. | |
| 889 BUFFER may also be nil, meaning that this process is not associated | |
| 890 with any buffer. | |
| 891 Third, fourth and fifth args are the multicast destination group, port and ttl. | |
| 892 dest must be an internet address between 224.0.0.0 and 239.255.255.255 | |
| 893 port is a communication port like in traditional unicast | |
| 894 ttl is the time-to-live (15 for site, 63 for region and 127 for world) | |
| 895 */ | |
| 896 (name, buffer, dest, port, ttl)) | |
| 897 { | |
| 898 /* This function can GC */ | |
| 444 | 899 Lisp_Object process = Qnil; |
| 428 | 900 struct gcpro gcpro1; |
| 901 void *inch, *outch; | |
| 902 | |
| 903 CHECK_STRING (name); | |
| 904 | |
| 905 /* Since this code is inside HAVE_MULTICAST, existence of | |
| 771 | 906 open_multicast_group is mandatory */ |
| 428 | 907 PROCMETH (open_multicast_group, (name, dest, port, ttl, |
| 908 &inch, &outch)); | |
| 909 | |
| 910 if (!NILP (buffer)) | |
| 911 buffer = Fget_buffer_create (buffer); | |
| 912 | |
| 444 | 913 process = make_process_internal (name); |
| 914 GCPRO1 (process); | |
| 428 | 915 |
| 444 | 916 XPROCESS (process)->pid = Fcons (port, dest); |
| 917 XPROCESS (process)->buffer = buffer; | |
| 853 | 918 init_process_io_handles (XPROCESS (process), (void *) inch, (void *) outch, |
| 919 (void *) -1, | |
| 428 | 920 STREAM_NETWORK_CONNECTION); |
| 921 | |
| 853 | 922 event_stream_select_process (XPROCESS (process), 1, 1); |
| 428 | 923 |
| 924 UNGCPRO; | |
| 444 | 925 return process; |
| 428 | 926 } |
| 927 #endif /* HAVE_MULTICAST */ | |
| 928 | |
| 929 #endif /* HAVE_SOCKETS */ | |
| 930 | |
| 931 Lisp_Object | |
| 932 canonicalize_host_name (Lisp_Object host) | |
| 933 { | |
| 934 return PROCMETH_OR_GIVEN (canonicalize_host_name, (host), host); | |
| 935 } | |
| 936 | |
| 937 | |
| 938 DEFUN ("set-process-window-size", Fset_process_window_size, 3, 3, 0, /* | |
| 939 Tell PROCESS that it has logical window size HEIGHT and WIDTH. | |
| 940 */ | |
| 444 | 941 (process, height, width)) |
| 428 | 942 { |
| 444 | 943 CHECK_PROCESS (process); |
| 428 | 944 CHECK_NATNUM (height); |
| 945 CHECK_NATNUM (width); | |
| 946 return | |
| 444 | 947 MAYBE_INT_PROCMETH (set_window_size, |
| 948 (XPROCESS (process), XINT (height), XINT (width))) <= 0 | |
| 428 | 949 ? Qnil : Qt; |
| 950 } | |
| 951 | |
| 952 | |
| 953 /************************************************************************/ | |
| 954 /* Process I/O */ | |
| 955 /************************************************************************/ | |
| 956 | |
| 844 | 957 /* Set up PROCESS's buffer for insertion of process data at PROCESS's |
| 958 mark. | |
| 959 | |
| 960 Sets the current buffer to PROCESS's buffer, inhibits read only, | |
| 961 remembers current point, sets point to PROCESS'S mark, widens if | |
| 962 necessary. | |
| 963 */ | |
| 964 static int | |
| 853 | 965 process_setup_for_insertion (Lisp_Object process, int read_stderr) |
| 844 | 966 { |
| 967 Lisp_Process *p = XPROCESS (process); | |
| 968 int spec = specpdl_depth (); | |
| 853 | 969 Lisp_Object buffer = read_stderr ? p->stderr_buffer : p->buffer; |
| 970 Lisp_Object mark = read_stderr ? p->stderr_mark : p->mark; | |
| 971 struct buffer *buf = XBUFFER (buffer); | |
| 844 | 972 Charbpos output_pt; |
| 973 | |
| 974 if (buf != current_buffer) | |
| 975 { | |
| 976 record_unwind_protect (save_current_buffer_restore, | |
| 977 Fcurrent_buffer ()); | |
| 978 set_buffer_internal (buf); | |
| 979 } | |
| 980 | |
| 981 record_unwind_protect (save_excursion_restore, save_excursion_save ()); | |
| 982 specbind (Qinhibit_read_only, Qt); | |
| 854 | 983 |
| 844 | 984 /* Insert new output into buffer |
| 985 at the current end-of-output marker, | |
| 986 thus preserving logical ordering of input and output. */ | |
| 853 | 987 if (XMARKER (mark)->buffer) |
| 988 output_pt = marker_position (mark); | |
| 844 | 989 else |
| 990 output_pt = BUF_ZV (buf); | |
| 991 | |
| 992 /* If the output marker is outside of the visible region, save | |
| 993 the restriction and widen. */ | |
| 994 if (! (BUF_BEGV (buf) <= output_pt && output_pt <= BUF_ZV (buf))) | |
| 995 { | |
| 996 record_unwind_protect (save_restriction_restore, | |
| 997 save_restriction_save (buf)); | |
| 998 Fwiden (wrap_buffer (buf)); | |
| 999 } | |
| 1000 | |
| 1001 BUF_SET_PT (buf, output_pt); | |
| 1002 return spec; | |
| 1003 } | |
| 1004 | |
| 428 | 1005 /* Read pending output from the process channel, |
| 1006 starting with our buffered-ahead character if we have one. | |
| 1007 Yield number of characters read. | |
| 1008 | |
| 1009 This function reads at most 1024 bytes. | |
| 1010 If you want to read all available subprocess output, | |
| 1011 you must call it repeatedly until it returns zero. */ | |
| 1012 | |
| 1013 Charcount | |
| 853 | 1014 read_process_output (Lisp_Object process, int read_stderr) |
| 428 | 1015 { |
| 1016 /* This function can GC */ | |
| 1017 Bytecount nbytes, nchars; | |
| 867 | 1018 Ibyte chars[1025]; |
| 428 | 1019 Lisp_Object outstream; |
| 444 | 1020 Lisp_Process *p = XPROCESS (process); |
| 853 | 1021 Lisp_Object filter = read_stderr ? p->stderr_filter : p->filter; |
| 1022 Lisp_Object buffer = read_stderr ? p->stderr_buffer : p->buffer; | |
| 1023 Lisp_Object mark = read_stderr ? p->stderr_mark : p->mark; | |
| 428 | 1024 |
| 1025 /* If there is a lot of output from the subprocess, the loop in | |
| 1026 execute_internal_event() might call read_process_output() more | |
| 1027 than once. If the filter that was executed from one of these | |
| 1028 calls set the filter to t, we have to stop now. Return -1 rather | |
| 1029 than 0 so execute_internal_event() doesn't close the process. | |
| 1030 Really, the loop in execute_internal_event() should check itself | |
| 1031 for a process-filter change, like in status_notify(); but the | |
| 1032 struct Lisp_Process is not exported outside of this file. */ | |
| 863 | 1033 if (!PROCESS_READABLE_P (p)) |
| 853 | 1034 { |
| 1035 errno = 0; | |
| 1036 return -1; /* already closed */ | |
| 1037 } | |
| 428 | 1038 |
| 853 | 1039 if (!NILP (filter) && (p->filter_does_read)) |
| 428 | 1040 { |
| 1041 Lisp_Object filter_result; | |
| 1042 | |
| 1043 /* Some weird FSFmacs crap here with | |
| 853 | 1044 Vdeactivate_mark and current_buffer->keymap. |
| 1045 Some FSF junk with running_asynch_code, to preserve the match | |
| 1046 data. Not necessary because we don't call process filters | |
| 1047 asynchronously (i.e. from within QUIT). */ | |
| 1048 /* Don't catch errors here; we're not in any critical code. */ | |
| 1049 filter_result = call2 (filter, process, Qnil); | |
| 428 | 1050 CHECK_INT (filter_result); |
| 1051 return XINT (filter_result); | |
| 1052 } | |
| 1053 | |
| 853 | 1054 nbytes = Lstream_read (read_stderr ? XLSTREAM (DATA_ERRSTREAM (p)) : |
| 1055 XLSTREAM (DATA_INSTREAM (p)), chars, | |
| 771 | 1056 sizeof (chars) - 1); |
| 428 | 1057 if (nbytes <= 0) return nbytes; |
| 1058 | |
| 771 | 1059 if (debug_process_io) |
| 1060 { | |
| 1061 chars[nbytes] = '\0'; | |
| 1062 stderr_out ("Read: %s\n", chars); | |
| 1063 } | |
| 1064 | |
| 1065 /* !!#### if the coding system changed as a result of reading, we | |
| 1066 need to change the output coding system accordingly. */ | |
| 428 | 1067 nchars = bytecount_to_charcount (chars, nbytes); |
| 853 | 1068 outstream = filter; |
| 428 | 1069 if (!NILP (outstream)) |
| 1070 { | |
| 853 | 1071 /* Some FSF junk with running_asynch_code, to preserve the match |
| 1072 data. Not necessary because we don't call process filters | |
| 1073 asynchronously (i.e. from within QUIT). */ | |
| 1074 /* Don't catch errors here; we're not in any critical code. */ | |
| 1075 call2 (outstream, process, make_string (chars, nbytes)); | |
| 428 | 1076 return nchars; |
| 1077 } | |
| 1078 | |
| 1079 /* If no filter, write into buffer if it isn't dead. */ | |
| 853 | 1080 if (!NILP (buffer) && BUFFER_LIVE_P (XBUFFER (buffer))) |
| 428 | 1081 { |
| 844 | 1082 struct gcpro gcpro1; |
| 853 | 1083 struct buffer *buf = XBUFFER (buffer); |
| 1084 int spec = process_setup_for_insertion (process, read_stderr); | |
| 428 | 1085 |
| 844 | 1086 GCPRO1 (process); |
| 428 | 1087 |
| 1088 #if 0 | |
| 1089 /* This screws up initial display of the window. jla */ | |
| 1090 | |
| 1091 /* Insert before markers in case we are inserting where | |
| 1092 the buffer's mark is, and the user's next command is Meta-y. */ | |
| 1093 buffer_insert_raw_string_1 (buf, -1, chars, | |
| 1094 nbytes, INSDEL_BEFORE_MARKERS); | |
| 1095 #else | |
| 1096 buffer_insert_raw_string (buf, chars, nbytes); | |
| 1097 #endif | |
| 1098 | |
| 853 | 1099 Fset_marker (mark, make_int (BUF_PT (buf)), buffer); |
| 1100 | |
| 428 | 1101 MARK_MODELINE_CHANGED; |
| 844 | 1102 unbind_to (spec); |
| 428 | 1103 UNGCPRO; |
| 1104 } | |
| 1105 return nchars; | |
| 1106 } | |
| 853 | 1107 |
| 1108 int | |
| 1109 process_has_separate_stderr (Lisp_Object process) | |
| 1110 { | |
| 1111 return XPROCESS (process)->separate_stderr; | |
| 1112 } | |
| 1113 | |
| 859 | 1114 DEFUN ("process-has-separate-stderr-p", Fprocess_has_separate_stderr_p, 1, 1, |
| 1115 0, /* | |
| 1116 Return non-nil if process has stderr separate from stdout. | |
| 1117 */ | |
| 1118 (process)) | |
| 1119 { | |
| 1120 CHECK_PROCESS (process); | |
| 1121 return process_has_separate_stderr (process) ? Qt : Qnil; | |
| 1122 } | |
| 1123 | |
| 428 | 1124 |
| 1125 /* Sending data to subprocess */ | |
| 1126 | |
| 444 | 1127 /* send some data to process PROCESS. If NONRELOCATABLE is non-NULL, it |
| 428 | 1128 specifies the address of the data. Otherwise, the data comes from the |
| 1129 object RELOCATABLE (either a string or a buffer). START and LEN | |
| 1130 specify the offset and length of the data to send. | |
| 1131 | |
| 665 | 1132 Note that START and LEN are in Charbpos's if RELOCATABLE is a buffer, |
| 428 | 1133 and in Bytecounts otherwise. */ |
| 1134 | |
| 1135 void | |
| 444 | 1136 send_process (Lisp_Object process, |
| 867 | 1137 Lisp_Object relocatable, const Ibyte *nonrelocatable, |
| 428 | 1138 int start, int len) |
| 1139 { | |
| 1140 /* This function can GC */ | |
| 1141 struct gcpro gcpro1, gcpro2; | |
| 1142 Lisp_Object lstream = Qnil; | |
| 1143 | |
| 444 | 1144 GCPRO2 (process, lstream); |
| 428 | 1145 |
| 444 | 1146 if (NILP (DATA_OUTSTREAM (XPROCESS (process)))) |
| 563 | 1147 invalid_operation ("Process not open for writing", process); |
| 428 | 1148 |
| 1149 if (nonrelocatable) | |
| 1150 lstream = | |
| 1151 make_fixed_buffer_input_stream (nonrelocatable + start, len); | |
| 1152 else if (BUFFERP (relocatable)) | |
| 1153 lstream = make_lisp_buffer_input_stream (XBUFFER (relocatable), | |
| 1154 start, start + len, 0); | |
| 1155 else | |
| 1156 lstream = make_lisp_string_input_stream (relocatable, start, len); | |
| 1157 | |
| 771 | 1158 if (debug_process_io) |
| 1159 { | |
| 1160 if (nonrelocatable) | |
| 1161 stderr_out ("Writing: %s\n", nonrelocatable); | |
| 1162 else | |
| 1163 { | |
| 1164 stderr_out ("Writing: "); | |
| 1165 print_internal (relocatable, Qexternal_debugging_output, 0); | |
| 1166 } | |
| 1167 } | |
| 1168 | |
| 444 | 1169 PROCMETH (send_process, (process, XLSTREAM (lstream))); |
| 428 | 1170 |
| 1171 UNGCPRO; | |
| 1172 Lstream_delete (XLSTREAM (lstream)); | |
| 1173 } | |
| 1174 | |
| 1175 DEFUN ("process-tty-name", Fprocess_tty_name, 1, 1, 0, /* | |
| 1176 Return the name of the terminal PROCESS uses, or nil if none. | |
| 1177 This is the terminal that the process itself reads and writes on, | |
| 1178 not the name of the pty that Emacs uses to talk with that terminal. | |
| 1179 */ | |
| 444 | 1180 (process)) |
| 428 | 1181 { |
| 444 | 1182 CHECK_PROCESS (process); |
| 1204 | 1183 return XPROCESS (process)->tty_name; |
| 428 | 1184 } |
| 1185 | |
| 1186 DEFUN ("set-process-buffer", Fset_process_buffer, 2, 2, 0, /* | |
| 1187 Set buffer associated with PROCESS to BUFFER (a buffer, or nil). | |
| 2297 | 1188 Output from PROCESS is inserted in this buffer unless PROCESS has a filter. |
| 428 | 1189 */ |
| 444 | 1190 (process, buffer)) |
| 428 | 1191 { |
| 444 | 1192 CHECK_PROCESS (process); |
| 428 | 1193 if (!NILP (buffer)) |
| 1194 CHECK_BUFFER (buffer); | |
| 444 | 1195 XPROCESS (process)->buffer = buffer; |
| 428 | 1196 return buffer; |
| 1197 } | |
| 1198 | |
| 1199 DEFUN ("process-buffer", Fprocess_buffer, 1, 1, 0, /* | |
| 1200 Return the buffer PROCESS is associated with. | |
| 2297 | 1201 Output from PROCESS is inserted in this buffer unless PROCESS has a filter. |
| 1202 Set the buffer with `set-process-buffer'. | |
| 428 | 1203 */ |
| 444 | 1204 (process)) |
| 428 | 1205 { |
| 444 | 1206 CHECK_PROCESS (process); |
| 1207 return XPROCESS (process)->buffer; | |
| 428 | 1208 } |
| 1209 | |
| 853 | 1210 DEFUN ("set-process-stderr-buffer", Fset_process_stderr_buffer, 2, 2, 0, /* |
| 2297 | 1211 Output from the stderr of PROCESS is inserted in this buffer unless |
| 1212 PROCESS has a stderr filter. | |
| 853 | 1213 Set stderr buffer associated with PROCESS to BUFFER (a buffer, or nil). |
| 1214 */ | |
| 1215 (process, buffer)) | |
| 1216 { | |
| 1217 CHECK_PROCESS (process); | |
| 1218 if (!XPROCESS (process)->separate_stderr) | |
| 1219 invalid_change ("stdout and stderr not separate", process); | |
| 1220 if (!NILP (buffer)) | |
| 1221 CHECK_BUFFER (buffer); | |
| 1222 XPROCESS (process)->stderr_buffer = buffer; | |
| 1223 return buffer; | |
| 1224 } | |
| 1225 | |
| 1226 DEFUN ("process-stderr-buffer", Fprocess_stderr_buffer, 1, 1, 0, /* | |
| 1227 Return the stderr buffer PROCESS is associated with. | |
| 2297 | 1228 Output from the stderr of PROCESS is inserted in this buffer unless PROCESS |
| 1229 has a stderr filter. Set the buffer with `set-process-stderr-buffer'. | |
| 853 | 1230 */ |
| 1231 (process)) | |
| 1232 { | |
| 1233 CHECK_PROCESS (process); | |
| 1234 if (!XPROCESS (process)->separate_stderr) | |
| 1235 invalid_change ("stdout and stderr not separate", process); | |
| 1236 return XPROCESS (process)->stderr_buffer; | |
| 1237 } | |
| 1238 | |
| 428 | 1239 DEFUN ("process-mark", Fprocess_mark, 1, 1, 0, /* |
| 1240 Return the marker for the end of the last output from PROCESS. | |
| 1241 */ | |
| 444 | 1242 (process)) |
| 428 | 1243 { |
| 444 | 1244 CHECK_PROCESS (process); |
| 1245 return XPROCESS (process)->mark; | |
| 428 | 1246 } |
| 1247 | |
| 853 | 1248 DEFUN ("process-stderr-mark", Fprocess_stderr_mark, 1, 1, 0, /* |
| 1249 Return the marker for the end of the last stderr output from PROCESS. | |
| 1250 */ | |
| 1251 (process)) | |
| 1252 { | |
| 1253 CHECK_PROCESS (process); | |
| 1254 if (!XPROCESS (process)->separate_stderr) | |
| 1255 invalid_operation ("stdout and stderr not separate", process); | |
| 1256 return XPROCESS (process)->stderr_mark; | |
| 1257 } | |
| 1258 | |
| 428 | 1259 void |
| 853 | 1260 set_process_filter (Lisp_Object process, Lisp_Object filter, |
| 1261 int filter_does_read, int set_stderr) | |
| 428 | 1262 { |
| 444 | 1263 CHECK_PROCESS (process); |
| 853 | 1264 if (set_stderr && !XPROCESS (process)->separate_stderr) |
| 1265 invalid_change ("stdout and stderr not separate", process); | |
| 863 | 1266 if (PROCESS_READABLE_P (XPROCESS (process))) |
| 853 | 1267 { |
| 1268 if (EQ (filter, Qt)) | |
| 1269 event_stream_unselect_process (XPROCESS (process), !set_stderr, | |
| 1270 set_stderr); | |
| 1271 else | |
| 1272 event_stream_select_process (XPROCESS (process), !set_stderr, | |
| 1273 set_stderr); | |
| 1274 } | |
| 428 | 1275 |
| 853 | 1276 if (set_stderr) |
| 1277 XPROCESS (process)->stderr_filter = filter; | |
| 1278 else | |
| 1279 XPROCESS (process)->filter = filter; | |
| 444 | 1280 XPROCESS (process)->filter_does_read = filter_does_read; |
| 428 | 1281 } |
| 1282 | |
| 1283 DEFUN ("set-process-filter", Fset_process_filter, 2, 2, 0, /* | |
| 1284 Give PROCESS the filter function FILTER; nil means no filter. | |
| 853 | 1285 t means stop accepting output from the process. (If process was created |
| 854 | 1286 with |
| 853 | 1287 When a process has a filter, each time it does output |
| 1288 the entire string of output is passed to the filter. | |
| 1289 The filter gets two arguments: the process and the string of output. | |
| 1290 If the process has a filter, its buffer is not used for output. | |
| 1291 */ | |
| 1292 (process, filter)) | |
| 1293 { | |
| 1294 set_process_filter (process, filter, 0, 0); | |
| 1295 return filter; | |
| 1296 } | |
| 1297 | |
| 1298 DEFUN ("set-process-stderr-filter", Fset_process_stderr_filter, 2, 2, 0, /* | |
| 1299 Give PROCESS the stderr filter function FILTER; nil means no filter. | |
| 428 | 1300 t means stop accepting output from the process. |
| 1301 When a process has a filter, each time it does output | |
| 1302 the entire string of output is passed to the filter. | |
| 1303 The filter gets two arguments: the process and the string of output. | |
| 1304 If the process has a filter, its buffer is not used for output. | |
| 1305 */ | |
| 444 | 1306 (process, filter)) |
| 428 | 1307 { |
| 853 | 1308 set_process_filter (process, filter, 0, 1); |
| 428 | 1309 return filter; |
| 1310 } | |
| 1311 | |
| 1312 DEFUN ("process-filter", Fprocess_filter, 1, 1, 0, /* | |
| 1313 Return the filter function of PROCESS; nil if none. | |
| 1314 See `set-process-filter' for more info on filter functions. | |
| 1315 */ | |
| 444 | 1316 (process)) |
| 428 | 1317 { |
| 444 | 1318 CHECK_PROCESS (process); |
| 1319 return XPROCESS (process)->filter; | |
| 428 | 1320 } |
| 1321 | |
| 853 | 1322 DEFUN ("process-stderr-filter", Fprocess_stderr_filter, 1, 1, 0, /* |
| 1323 Return the filter function of PROCESS; nil if none. | |
| 1324 See `set-process-stderr-filter' for more info on filter functions. | |
| 1325 */ | |
| 1326 (process)) | |
| 1327 { | |
| 1328 CHECK_PROCESS (process); | |
| 1329 if (!XPROCESS (process)->separate_stderr) | |
| 1330 invalid_operation ("stdout and stderr not separate", process); | |
| 1331 return XPROCESS (process)->stderr_filter; | |
| 1332 } | |
| 1333 | |
| 442 | 1334 DEFUN ("process-send-region", Fprocess_send_region, 3, 4, 0, /* |
| 1335 Send current contents of the region between START and END as input to PROCESS. | |
| 444 | 1336 PROCESS may be a process or the name of a process, or a buffer or the |
| 1337 name of a buffer, in which case the buffer's process is used. If it | |
| 1338 is nil, the current buffer's process is used. | |
| 442 | 1339 BUFFER specifies the buffer to look in; if nil, the current buffer is used. |
| 853 | 1340 If the region is more than 100 or so characters long, it may be sent in |
| 1341 several chunks. This may happen even for shorter regions. Output | |
| 444 | 1342 from processes can arrive in between chunks. |
| 428 | 1343 */ |
| 442 | 1344 (process, start, end, buffer)) |
| 428 | 1345 { |
| 1346 /* This function can GC */ | |
| 665 | 1347 Charbpos bstart, bend; |
| 442 | 1348 struct buffer *buf = decode_buffer (buffer, 0); |
| 428 | 1349 |
| 793 | 1350 buffer = wrap_buffer (buf); |
| 444 | 1351 process = get_process (process); |
| 1352 get_buffer_range_char (buf, start, end, &bstart, &bend, 0); | |
| 442 | 1353 |
| 444 | 1354 send_process (process, buffer, 0, bstart, bend - bstart); |
| 428 | 1355 return Qnil; |
| 1356 } | |
| 1357 | |
| 1358 DEFUN ("process-send-string", Fprocess_send_string, 2, 4, 0, /* | |
| 1359 Send PROCESS the contents of STRING as input. | |
| 444 | 1360 PROCESS may be a process or the name of a process, or a buffer or the |
| 1361 name of a buffer, in which case the buffer's process is used. If it | |
| 1362 is nil, the current buffer's process is used. | |
| 1363 Optional arguments START and END specify part of STRING; see `substring'. | |
| 1364 If STRING is more than 100 or so characters long, it may be sent in | |
| 1365 several chunks. This may happen even for shorter strings. Output | |
| 1366 from processes can arrive in between chunks. | |
| 428 | 1367 */ |
| 444 | 1368 (process, string, start, end)) |
| 428 | 1369 { |
| 1370 /* This function can GC */ | |
| 444 | 1371 Bytecount bstart, bend; |
| 428 | 1372 |
| 444 | 1373 process = get_process (process); |
| 428 | 1374 CHECK_STRING (string); |
| 444 | 1375 get_string_range_byte (string, start, end, &bstart, &bend, |
| 428 | 1376 GB_HISTORICAL_STRING_BEHAVIOR); |
| 1377 | |
| 444 | 1378 send_process (process, string, 0, bstart, bend - bstart); |
| 428 | 1379 return Qnil; |
| 1380 } | |
| 1381 | |
| 1382 | |
| 1383 DEFUN ("process-input-coding-system", Fprocess_input_coding_system, 1, 1, 0, /* | |
| 1384 Return PROCESS's input coding system. | |
| 1385 */ | |
| 1386 (process)) | |
| 1387 { | |
| 1388 process = get_process (process); | |
| 863 | 1389 CHECK_READABLE_PROCESS (process); |
| 771 | 1390 return (coding_stream_detected_coding_system |
| 1391 (XLSTREAM (XPROCESS (process)->coding_instream))); | |
| 428 | 1392 } |
| 1393 | |
| 1394 DEFUN ("process-output-coding-system", Fprocess_output_coding_system, 1, 1, 0, /* | |
| 1395 Return PROCESS's output coding system. | |
| 1396 */ | |
| 1397 (process)) | |
| 1398 { | |
| 1399 process = get_process (process); | |
| 440 | 1400 CHECK_LIVE_PROCESS (process); |
| 771 | 1401 return (coding_stream_coding_system |
| 1402 (XLSTREAM (XPROCESS (process)->coding_outstream))); | |
| 428 | 1403 } |
| 1404 | |
| 1405 DEFUN ("process-coding-system", Fprocess_coding_system, 1, 1, 0, /* | |
| 1406 Return a pair of coding-system for decoding and encoding of PROCESS. | |
| 1407 */ | |
| 1408 (process)) | |
| 1409 { | |
| 1410 process = get_process (process); | |
| 863 | 1411 CHECK_READABLE_PROCESS (process); |
| 771 | 1412 return Fcons (coding_stream_detected_coding_system |
| 428 | 1413 (XLSTREAM (XPROCESS (process)->coding_instream)), |
| 771 | 1414 coding_stream_coding_system |
| 428 | 1415 (XLSTREAM (XPROCESS (process)->coding_outstream))); |
| 1416 } | |
| 1417 | |
| 1418 DEFUN ("set-process-input-coding-system", Fset_process_input_coding_system, | |
| 1419 2, 2, 0, /* | |
| 1420 Set PROCESS's input coding system to CODESYS. | |
| 771 | 1421 This is used for reading data from PROCESS. |
| 428 | 1422 */ |
| 1423 (process, codesys)) | |
| 1424 { | |
| 771 | 1425 codesys = get_coding_system_for_text_file (codesys, 1); |
| 428 | 1426 process = get_process (process); |
| 863 | 1427 CHECK_READABLE_PROCESS (process); |
| 440 | 1428 |
| 771 | 1429 set_coding_stream_coding_system |
| 428 | 1430 (XLSTREAM (XPROCESS (process)->coding_instream), codesys); |
| 1431 return Qnil; | |
| 1432 } | |
| 1433 | |
| 1434 DEFUN ("set-process-output-coding-system", Fset_process_output_coding_system, | |
| 1435 2, 2, 0, /* | |
| 1436 Set PROCESS's output coding system to CODESYS. | |
| 771 | 1437 This is used for writing data to PROCESS. |
| 428 | 1438 */ |
| 1439 (process, codesys)) | |
| 1440 { | |
| 771 | 1441 codesys = get_coding_system_for_text_file (codesys, 0); |
| 428 | 1442 process = get_process (process); |
| 440 | 1443 CHECK_LIVE_PROCESS (process); |
| 1444 | |
| 771 | 1445 set_coding_stream_coding_system |
| 428 | 1446 (XLSTREAM (XPROCESS (process)->coding_outstream), codesys); |
| 1447 return Qnil; | |
| 1448 } | |
| 1449 | |
| 1450 DEFUN ("set-process-coding-system", Fset_process_coding_system, | |
| 1451 1, 3, 0, /* | |
| 1452 Set coding-systems of PROCESS to DECODING and ENCODING. | |
| 440 | 1453 DECODING will be used to decode subprocess output and ENCODING to |
| 1454 encode subprocess input. | |
| 428 | 1455 */ |
| 1456 (process, decoding, encoding)) | |
| 1457 { | |
| 1458 if (!NILP (decoding)) | |
| 1459 Fset_process_input_coding_system (process, decoding); | |
| 1460 | |
| 1461 if (!NILP (encoding)) | |
| 1462 Fset_process_output_coding_system (process, encoding); | |
| 1463 | |
| 1464 return Qnil; | |
| 1465 } | |
| 1466 | |
| 1467 | |
| 1468 /************************************************************************/ | |
| 1469 /* process status */ | |
| 1470 /************************************************************************/ | |
| 1471 | |
| 1472 static Lisp_Object | |
| 1473 exec_sentinel_unwind (Lisp_Object datum) | |
| 1474 { | |
| 853 | 1475 XPROCESS (XCAR (datum))->sentinel = XCDR (datum); |
| 1476 free_cons (datum); | |
| 428 | 1477 return Qnil; |
| 1478 } | |
| 1479 | |
| 1480 static void | |
| 444 | 1481 exec_sentinel (Lisp_Object process, Lisp_Object reason) |
| 428 | 1482 { |
| 1483 /* This function can GC */ | |
| 1484 int speccount = specpdl_depth (); | |
| 444 | 1485 Lisp_Process *p = XPROCESS (process); |
| 428 | 1486 Lisp_Object sentinel = p->sentinel; |
| 1487 | |
| 1488 if (NILP (sentinel)) | |
| 1489 return; | |
| 1490 | |
| 1491 /* Some weird FSFmacs crap here with | |
| 1492 Vdeactivate_mark and current_buffer->keymap */ | |
| 1493 | |
| 853 | 1494 /* Some FSF junk with running_asynch_code, to preserve the match |
| 1495 data. Not necessary because we don't call process filters | |
| 1496 asynchronously (i.e. from within QUIT). */ | |
| 1497 | |
| 428 | 1498 /* Zilch the sentinel while it's running, to avoid recursive invocations; |
| 853 | 1499 assure that it gets restored no matter how the sentinel exits. |
| 1500 | |
| 1501 (#### Why is this necessary? Probably another relic of asynchronous | |
| 1502 calling of process filters/sentinels.) */ | |
| 428 | 1503 p->sentinel = Qnil; |
| 853 | 1504 record_unwind_protect (exec_sentinel_unwind, |
| 1505 noseeum_cons (process, sentinel)); | |
| 1506 /* Don't catch errors here; we're not in any critical code. */ | |
| 1507 call2 (sentinel, process, reason); | |
| 771 | 1508 unbind_to (speccount); |
| 428 | 1509 } |
| 1510 | |
| 1511 DEFUN ("set-process-sentinel", Fset_process_sentinel, 2, 2, 0, /* | |
| 1512 Give PROCESS the sentinel SENTINEL; nil for none. | |
| 1513 The sentinel is called as a function when the process changes state. | |
| 1514 It gets two arguments: the process, and a string describing the change. | |
| 1515 */ | |
| 444 | 1516 (process, sentinel)) |
| 428 | 1517 { |
| 444 | 1518 CHECK_PROCESS (process); |
| 1519 XPROCESS (process)->sentinel = sentinel; | |
| 428 | 1520 return sentinel; |
| 1521 } | |
| 1522 | |
| 1523 DEFUN ("process-sentinel", Fprocess_sentinel, 1, 1, 0, /* | |
| 1524 Return the sentinel of PROCESS; nil if none. | |
| 1525 See `set-process-sentinel' for more info on sentinels. | |
| 1526 */ | |
| 444 | 1527 (process)) |
| 428 | 1528 { |
| 444 | 1529 CHECK_PROCESS (process); |
| 1530 return XPROCESS (process)->sentinel; | |
| 428 | 1531 } |
| 1532 | |
| 1533 | |
| 442 | 1534 const char * |
| 428 | 1535 signal_name (int signum) |
| 1536 { | |
| 1537 if (signum >= 0 && signum < NSIG) | |
| 442 | 1538 return (const char *) sys_siglist[signum]; |
| 428 | 1539 |
| 442 | 1540 return (const char *) GETTEXT ("unknown signal"); |
| 428 | 1541 } |
| 1542 | |
| 1543 void | |
| 1544 update_process_status (Lisp_Object p, | |
| 1545 Lisp_Object status_symbol, | |
| 1546 int exit_code, | |
| 1547 int core_dumped) | |
| 1548 { | |
| 1549 XPROCESS (p)->tick++; | |
| 1550 process_tick++; | |
| 1551 XPROCESS (p)->status_symbol = status_symbol; | |
| 1552 XPROCESS (p)->exit_code = exit_code; | |
| 1553 XPROCESS (p)->core_dumped = core_dumped; | |
| 1554 } | |
| 1555 | |
| 1556 /* Return a string describing a process status list. */ | |
| 1557 | |
| 1558 static Lisp_Object | |
| 440 | 1559 status_message (Lisp_Process *p) |
| 428 | 1560 { |
| 1561 Lisp_Object symbol = p->status_symbol; | |
| 1562 int code = p->exit_code; | |
| 1563 int coredump = p->core_dumped; | |
| 1564 Lisp_Object string, string2; | |
| 1565 | |
| 1566 if (EQ (symbol, Qsignal) || EQ (symbol, Qstop)) | |
| 1567 { | |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1568 string = build_cistring (signal_name (code)); |
| 428 | 1569 if (coredump) |
| 771 | 1570 string2 = build_msg_string (" (core dumped)\n"); |
| 428 | 1571 else |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
1572 string2 = build_ascstring ("\n"); |
| 793 | 1573 set_string_char (string, 0, |
| 867 | 1574 DOWNCASE (0, string_ichar (string, 0))); |
| 428 | 1575 return concat2 (string, string2); |
| 1576 } | |
| 1577 else if (EQ (symbol, Qexit)) | |
| 1578 { | |
| 1579 if (code == 0) | |
| 771 | 1580 return build_msg_string ("finished\n"); |
| 428 | 1581 string = Fnumber_to_string (make_int (code)); |
| 1582 if (coredump) | |
| 771 | 1583 string2 = build_msg_string (" (core dumped)\n"); |
| 428 | 1584 else |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
1585 string2 = build_ascstring ("\n"); |
| 771 | 1586 return concat2 (build_msg_string ("exited abnormally with code "), |
| 428 | 1587 concat2 (string, string2)); |
| 1588 } | |
| 1589 else | |
| 1590 return Fcopy_sequence (Fsymbol_name (symbol)); | |
| 1591 } | |
| 1592 | |
| 1593 /* Tell status_notify() to check for terminated processes. We do this | |
| 1594 because on some systems we sometimes miss SIGCHLD calls. (Not sure | |
| 853 | 1595 why.) This is also used under Mswin. */ |
| 428 | 1596 |
| 1597 void | |
| 1598 kick_status_notify (void) | |
| 1599 { | |
| 1600 process_tick++; | |
| 1601 } | |
| 1602 | |
| 1603 | |
| 1604 /* Report all recent events of a change in process status | |
| 1605 (either run the sentinel or output a message). | |
| 1606 This is done while Emacs is waiting for keyboard input. */ | |
| 1607 | |
| 1608 void | |
| 1609 status_notify (void) | |
| 1610 { | |
| 1611 /* This function can GC */ | |
| 1612 Lisp_Object tail = Qnil; | |
| 1613 Lisp_Object symbol = Qnil; | |
| 1614 Lisp_Object msg = Qnil; | |
| 1615 struct gcpro gcpro1, gcpro2, gcpro3; | |
| 1616 /* process_tick is volatile, so we have to remember it now. | |
| 444 | 1617 Otherwise, we get a race condition if SIGCHLD happens during |
| 428 | 1618 this function. |
| 1619 | |
| 1620 (Actually, this is not the case anymore. The code to | |
| 1621 update the process structures has been moved out of the | |
| 1622 SIGCHLD handler. But for the moment I'm leaving this | |
| 1623 stuff in -- it can't hurt.) */ | |
| 1624 int temp_process_tick; | |
| 1625 | |
| 1626 MAYBE_PROCMETH (reap_exited_processes, ()); | |
| 1627 | |
| 1628 temp_process_tick = process_tick; | |
| 1629 | |
| 1630 if (update_tick == temp_process_tick) | |
| 1631 return; | |
| 1632 | |
| 1633 /* We need to gcpro tail; if read_process_output calls a filter | |
| 1634 which deletes a process and removes the cons to which tail points | |
| 1635 from Vprocess_alist, and then causes a GC, tail is an unprotected | |
| 1636 reference. */ | |
| 1637 GCPRO3 (tail, symbol, msg); | |
| 1638 | |
| 1639 for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail)) | |
| 1640 { | |
| 444 | 1641 Lisp_Object process = XCAR (tail); |
| 1642 Lisp_Process *p = XPROCESS (process); | |
| 428 | 1643 /* p->tick is also volatile. Same thing as above applies. */ |
| 1644 int this_process_tick; | |
| 1645 | |
| 1646 /* #### extra check for terminated processes, in case a SIGCHLD | |
| 1647 got missed (this seems to happen sometimes, I'm not sure why). | |
| 1648 */ | |
| 1649 if (INTP (p->pid)) | |
| 1650 MAYBE_PROCMETH (update_status_if_terminated, (p)); | |
| 1651 | |
| 1652 this_process_tick = p->tick; | |
| 1653 if (this_process_tick != p->update_tick) | |
| 1654 { | |
| 1655 p->update_tick = this_process_tick; | |
| 1656 | |
| 1657 /* If process is still active, read any output that remains. */ | |
| 1658 while (!EQ (p->filter, Qt) | |
| 853 | 1659 && read_process_output (process, 0) > 0) |
| 1660 ; | |
| 1661 while (p->separate_stderr && !EQ (p->stderr_filter, Qt) | |
| 1662 && read_process_output (process, 1) > 0) | |
| 428 | 1663 ; |
| 1664 | |
| 1665 /* Get the text to use for the message. */ | |
| 1666 msg = status_message (p); | |
| 1667 | |
| 1668 /* If process is terminated, deactivate it or delete it. */ | |
| 1669 symbol = p->status_symbol; | |
| 1670 | |
| 1671 if (EQ (symbol, Qsignal) | |
| 1672 || EQ (symbol, Qexit)) | |
| 1673 { | |
| 1674 if (delete_exited_processes) | |
| 444 | 1675 remove_process (process); |
| 428 | 1676 else |
| 444 | 1677 deactivate_process (process); |
| 428 | 1678 } |
| 1679 | |
| 1680 /* Now output the message suitably. */ | |
| 1681 if (!NILP (p->sentinel)) | |
| 444 | 1682 exec_sentinel (process, msg); |
| 428 | 1683 /* Don't bother with a message in the buffer |
| 1684 when a process becomes runnable. */ | |
| 844 | 1685 else if (!EQ (symbol, Qrun) && !NILP (p->buffer) && |
| 1686 /* Avoid error if buffer is deleted | |
| 1687 (probably that's why the process is dead, too) */ | |
| 1688 BUFFER_LIVE_P (XBUFFER (p->buffer))) | |
| 428 | 1689 { |
| 844 | 1690 struct gcpro ngcpro1; |
| 853 | 1691 int spec = process_setup_for_insertion (process, 0); |
| 428 | 1692 |
| 844 | 1693 NGCPRO1 (process); |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1694 buffer_insert_ascstring (current_buffer, "\nProcess "); |
| 428 | 1695 Finsert (1, &p->name); |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1696 buffer_insert_ascstring (current_buffer, " "); |
| 428 | 1697 Finsert (1, &msg); |
| 1698 Fset_marker (p->mark, make_int (BUF_PT (current_buffer)), | |
| 1699 p->buffer); | |
| 1700 | |
| 844 | 1701 unbind_to (spec); |
| 428 | 1702 NUNGCPRO; |
| 1703 } | |
| 1704 } | |
| 1705 } /* end for */ | |
| 1706 | |
| 1707 /* in case buffers use %s in modeline-format */ | |
| 1708 MARK_MODELINE_CHANGED; | |
| 1709 redisplay (); | |
| 1710 | |
| 1711 update_tick = temp_process_tick; | |
| 1712 | |
| 1713 UNGCPRO; | |
| 1714 } | |
| 1715 | |
| 1716 DEFUN ("process-status", Fprocess_status, 1, 1, 0, /* | |
| 1717 Return the status of PROCESS. | |
| 1718 This is a symbol, one of these: | |
| 1719 | |
| 1720 run -- for a process that is running. | |
| 1721 stop -- for a process stopped but continuable. | |
| 1722 exit -- for a process that has exited. | |
| 1723 signal -- for a process that has got a fatal signal. | |
| 1724 open -- for a network stream connection that is open. | |
| 1725 closed -- for a network stream connection that is closed. | |
| 1726 nil -- if arg is a process name and no such process exists. | |
| 1727 | |
| 1728 PROCESS may be a process, a buffer, the name of a process or buffer, or | |
| 1729 nil, indicating the current buffer's process. | |
| 1730 */ | |
| 444 | 1731 (process)) |
| 428 | 1732 { |
| 1733 Lisp_Object status_symbol; | |
| 1734 | |
| 444 | 1735 if (STRINGP (process)) |
| 1736 process = Fget_process (process); | |
| 428 | 1737 else |
| 444 | 1738 process = get_process (process); |
| 428 | 1739 |
| 444 | 1740 if (NILP (process)) |
| 428 | 1741 return Qnil; |
| 1742 | |
| 444 | 1743 status_symbol = XPROCESS (process)->status_symbol; |
| 1744 if (network_connection_p (process)) | |
| 428 | 1745 { |
| 1746 if (EQ (status_symbol, Qrun)) | |
| 1747 status_symbol = Qopen; | |
| 1748 else if (EQ (status_symbol, Qexit)) | |
| 1749 status_symbol = Qclosed; | |
| 1750 } | |
| 1751 return status_symbol; | |
| 1752 } | |
| 1753 | |
| 1754 DEFUN ("process-exit-status", Fprocess_exit_status, 1, 1, 0, /* | |
| 1755 Return the exit status of PROCESS or the signal number that killed it. | |
| 1756 If PROCESS has not yet exited or died, return 0. | |
| 1757 */ | |
| 444 | 1758 (process)) |
| 428 | 1759 { |
| 444 | 1760 CHECK_PROCESS (process); |
| 1761 return make_int (XPROCESS (process)->exit_code); | |
| 428 | 1762 } |
| 1763 | |
| 1764 | |
| 1765 | |
| 442 | 1766 static int |
| 1767 decode_signal (Lisp_Object signal_) | |
| 428 | 1768 { |
| 442 | 1769 if (INTP (signal_)) |
| 1770 return XINT (signal_); | |
| 428 | 1771 else |
| 1772 { | |
| 867 | 1773 Ibyte *name; |
| 428 | 1774 |
| 442 | 1775 CHECK_SYMBOL (signal_); |
| 793 | 1776 name = XSTRING_DATA (XSYMBOL (signal_)->name); |
| 428 | 1777 |
| 793 | 1778 #define handle_signal(sym) do { \ |
| 2367 | 1779 if (!qxestrcmp_ascii ( name, #sym)) \ |
| 793 | 1780 return sym; \ |
| 442 | 1781 } while (0) |
| 428 | 1782 |
| 1783 handle_signal (SIGINT); /* ANSI */ | |
| 1784 handle_signal (SIGILL); /* ANSI */ | |
| 1785 handle_signal (SIGABRT); /* ANSI */ | |
| 1786 handle_signal (SIGFPE); /* ANSI */ | |
| 1787 handle_signal (SIGSEGV); /* ANSI */ | |
| 1788 handle_signal (SIGTERM); /* ANSI */ | |
| 1789 | |
| 1790 #ifdef SIGHUP | |
| 1791 handle_signal (SIGHUP); /* POSIX */ | |
| 1792 #endif | |
| 1793 #ifdef SIGQUIT | |
| 1794 handle_signal (SIGQUIT); /* POSIX */ | |
| 1795 #endif | |
| 1796 #ifdef SIGTRAP | |
| 1797 handle_signal (SIGTRAP); /* POSIX */ | |
| 1798 #endif | |
| 1799 #ifdef SIGKILL | |
| 1800 handle_signal (SIGKILL); /* POSIX */ | |
| 1801 #endif | |
| 1802 #ifdef SIGUSR1 | |
| 1803 handle_signal (SIGUSR1); /* POSIX */ | |
| 1804 #endif | |
| 1805 #ifdef SIGUSR2 | |
| 1806 handle_signal (SIGUSR2); /* POSIX */ | |
| 1807 #endif | |
| 1808 #ifdef SIGPIPE | |
| 1809 handle_signal (SIGPIPE); /* POSIX */ | |
| 1810 #endif | |
| 1811 #ifdef SIGALRM | |
| 1812 handle_signal (SIGALRM); /* POSIX */ | |
| 1813 #endif | |
| 1814 #ifdef SIGCHLD | |
| 1815 handle_signal (SIGCHLD); /* POSIX */ | |
| 1816 #endif | |
| 1817 #ifdef SIGCONT | |
| 1818 handle_signal (SIGCONT); /* POSIX */ | |
| 1819 #endif | |
| 1820 #ifdef SIGSTOP | |
| 1821 handle_signal (SIGSTOP); /* POSIX */ | |
| 1822 #endif | |
| 1823 #ifdef SIGTSTP | |
| 1824 handle_signal (SIGTSTP); /* POSIX */ | |
| 1825 #endif | |
| 1826 #ifdef SIGTTIN | |
| 1827 handle_signal (SIGTTIN); /* POSIX */ | |
| 1828 #endif | |
| 1829 #ifdef SIGTTOU | |
| 1830 handle_signal (SIGTTOU); /* POSIX */ | |
| 1831 #endif | |
| 1832 | |
| 1833 #ifdef SIGBUS | |
| 1834 handle_signal (SIGBUS); /* XPG5 */ | |
| 1835 #endif | |
| 1836 #ifdef SIGPOLL | |
| 1837 handle_signal (SIGPOLL); /* XPG5 */ | |
| 1838 #endif | |
| 1839 #ifdef SIGPROF | |
| 1840 handle_signal (SIGPROF); /* XPG5 */ | |
| 1841 #endif | |
| 1842 #ifdef SIGSYS | |
| 1843 handle_signal (SIGSYS); /* XPG5 */ | |
| 1844 #endif | |
| 1845 #ifdef SIGURG | |
| 1846 handle_signal (SIGURG); /* XPG5 */ | |
| 1847 #endif | |
| 1848 #ifdef SIGXCPU | |
| 1849 handle_signal (SIGXCPU); /* XPG5 */ | |
| 1850 #endif | |
| 1851 #ifdef SIGXFSZ | |
| 1852 handle_signal (SIGXFSZ); /* XPG5 */ | |
| 1853 #endif | |
| 1854 #ifdef SIGVTALRM | |
| 1855 handle_signal (SIGVTALRM); /* XPG5 */ | |
| 1856 #endif | |
| 1857 | |
| 1858 #ifdef SIGIO | |
| 1859 handle_signal (SIGIO); /* BSD 4.2 */ | |
| 1860 #endif | |
| 1861 #ifdef SIGWINCH | |
| 1862 handle_signal (SIGWINCH); /* BSD 4.3 */ | |
| 1863 #endif | |
| 1864 | |
| 1865 #ifdef SIGEMT | |
| 1866 handle_signal (SIGEMT); | |
| 1867 #endif | |
| 1868 #ifdef SIGINFO | |
| 1869 handle_signal (SIGINFO); | |
| 1870 #endif | |
| 1871 #ifdef SIGHWE | |
| 1872 handle_signal (SIGHWE); | |
| 1873 #endif | |
| 1874 #ifdef SIGPRE | |
| 1875 handle_signal (SIGPRE); | |
| 1876 #endif | |
| 1877 #ifdef SIGUME | |
| 1878 handle_signal (SIGUME); | |
| 1879 #endif | |
| 1880 #ifdef SIGDLK | |
| 1881 handle_signal (SIGDLK); | |
| 1882 #endif | |
| 1883 #ifdef SIGCPULIM | |
| 1884 handle_signal (SIGCPULIM); | |
| 1885 #endif | |
| 1886 #ifdef SIGIOT | |
| 1887 handle_signal (SIGIOT); | |
| 1888 #endif | |
| 1889 #ifdef SIGLOST | |
| 1890 handle_signal (SIGLOST); | |
| 1891 #endif | |
| 1892 #ifdef SIGSTKFLT | |
| 1893 handle_signal (SIGSTKFLT); | |
| 1894 #endif | |
| 1895 #ifdef SIGUNUSED | |
| 1896 handle_signal (SIGUNUSED); | |
| 1897 #endif | |
| 1898 #ifdef SIGDANGER | |
| 1899 handle_signal (SIGDANGER); /* AIX */ | |
| 1900 #endif | |
| 1901 #ifdef SIGMSG | |
| 1902 handle_signal (SIGMSG); | |
| 1903 #endif | |
| 1904 #ifdef SIGSOUND | |
| 1905 handle_signal (SIGSOUND); | |
| 1906 #endif | |
| 1907 #ifdef SIGRETRACT | |
| 1908 handle_signal (SIGRETRACT); | |
| 1909 #endif | |
| 1910 #ifdef SIGGRANT | |
| 1911 handle_signal (SIGGRANT); | |
| 1912 #endif | |
| 1913 #ifdef SIGPWR | |
| 1914 handle_signal (SIGPWR); | |
| 1915 #endif | |
| 1916 | |
| 1917 #undef handle_signal | |
| 1918 | |
| 563 | 1919 invalid_constant ("Undefined signal name", signal_); |
| 1204 | 1920 RETURN_NOT_REACHED (0); |
| 442 | 1921 } |
| 1922 } | |
| 1923 | |
| 1924 /* Send signal number SIGNO to PROCESS. | |
| 1925 CURRENT-GROUP non-nil means send signal to the current | |
| 1926 foreground process group of the process's controlling terminal rather | |
| 1927 than to the process's own process group. | |
| 1928 This is used for various commands in shell mode. | |
| 1929 If NOMSG is zero, insert signal-announcements into process's buffers | |
| 1930 right away. | |
| 1931 | |
| 1932 If we can, we try to signal PROCESS by sending control characters | |
| 1933 down the pty. This allows us to signal inferiors who have changed | |
| 1934 their uid, for which kill() would return an EPERM error, or to | |
| 1935 processes running on another computer through a remote login. */ | |
| 1936 | |
| 1937 static void | |
| 1938 process_send_signal (Lisp_Object process, int signo, | |
| 1939 int current_group, int nomsg) | |
| 1940 { | |
| 1941 /* This function can GC */ | |
| 444 | 1942 process = get_process (process); |
| 442 | 1943 |
| 444 | 1944 if (network_connection_p (process)) |
| 563 | 1945 invalid_operation ("Network connection is not a subprocess", process); |
| 444 | 1946 CHECK_LIVE_PROCESS (process); |
| 442 | 1947 |
| 444 | 1948 MAYBE_PROCMETH (kill_child_process, (process, signo, current_group, nomsg)); |
| 442 | 1949 } |
| 1950 | |
| 1951 DEFUN ("process-send-signal", Fprocess_send_signal, 1, 3, 0, /* | |
| 1952 Send signal SIGNAL to process PROCESS. | |
| 1953 SIGNAL may be an integer, or a symbol naming a signal, like `SIGSEGV'. | |
| 1954 PROCESS may be a process, a buffer, the name of a process or buffer, or | |
| 1955 nil, indicating the current buffer's process. | |
| 1956 Third arg CURRENT-GROUP non-nil means send signal to the current | |
| 1957 foreground process group of the process's controlling terminal rather | |
| 1958 than to the process's own process group. | |
| 1959 If the process is a shell that supports job control, this means | |
| 1960 send the signal to the current subjob rather than the shell. | |
| 1961 */ | |
| 1962 (signal_, process, current_group)) | |
| 1963 { | |
| 1964 /* This function can GC */ | |
| 1965 process_send_signal (process, decode_signal (signal_), | |
| 1966 !NILP (current_group), 0); | |
| 1967 return process; | |
| 1968 } | |
| 1969 | |
| 1970 DEFUN ("interrupt-process", Finterrupt_process, 0, 2, 0, /* | |
| 1971 Interrupt process PROCESS. | |
| 1972 See function `process-send-signal' for more details on usage. | |
| 1973 */ | |
| 1974 (process, current_group)) | |
| 1975 { | |
| 1976 /* This function can GC */ | |
| 1977 process_send_signal (process, SIGINT, !NILP (current_group), 0); | |
| 1978 return process; | |
| 1979 } | |
| 1980 | |
| 1981 DEFUN ("kill-process", Fkill_process, 0, 2, 0, /* | |
| 1982 Kill process PROCESS. | |
| 1983 See function `process-send-signal' for more details on usage. | |
| 1984 */ | |
| 1985 (process, current_group)) | |
| 1986 { | |
| 1987 /* This function can GC */ | |
| 1988 #ifdef SIGKILL | |
| 1989 process_send_signal (process, SIGKILL, !NILP (current_group), 0); | |
| 1990 #else | |
| 563 | 1991 signal_error (Qunimplemented, |
| 1992 "kill-process: Not supported on this system", | |
| 1993 Qunbound); | |
| 442 | 1994 #endif |
| 1995 return process; | |
| 1996 } | |
| 1997 | |
| 1998 DEFUN ("quit-process", Fquit_process, 0, 2, 0, /* | |
| 1999 Send QUIT signal to process PROCESS. | |
| 2000 See function `process-send-signal' for more details on usage. | |
| 2001 */ | |
| 2002 (process, current_group)) | |
| 2003 { | |
| 2004 /* This function can GC */ | |
| 2005 #ifdef SIGQUIT | |
| 2006 process_send_signal (process, SIGQUIT, !NILP (current_group), 0); | |
| 2007 #else | |
| 563 | 2008 signal_error (Qunimplemented, |
| 2009 "quit-process: Not supported on this system", | |
| 2010 Qunbound); | |
| 442 | 2011 #endif |
| 2012 return process; | |
| 2013 } | |
| 2014 | |
| 2015 DEFUN ("stop-process", Fstop_process, 0, 2, 0, /* | |
| 2016 Stop process PROCESS. | |
| 2017 See function `process-send-signal' for more details on usage. | |
| 2018 */ | |
| 2019 (process, current_group)) | |
| 2020 { | |
| 2021 /* This function can GC */ | |
| 2022 #ifdef SIGTSTP | |
| 2023 process_send_signal (process, SIGTSTP, !NILP (current_group), 0); | |
| 2024 #else | |
| 563 | 2025 signal_error (Qunimplemented, |
| 2026 "stop-process: Not supported on this system", | |
| 2027 Qunbound); | |
| 442 | 2028 #endif |
| 2029 return process; | |
| 2030 } | |
| 2031 | |
| 2032 DEFUN ("continue-process", Fcontinue_process, 0, 2, 0, /* | |
| 2033 Continue process PROCESS. | |
| 2034 See function `process-send-signal' for more details on usage. | |
| 2035 */ | |
| 2036 (process, current_group)) | |
| 2037 { | |
| 2038 /* This function can GC */ | |
| 2039 #ifdef SIGCONT | |
| 2040 process_send_signal (process, SIGCONT, !NILP (current_group), 0); | |
| 2041 #else | |
| 563 | 2042 signal_error (Qunimplemented, |
| 2043 "continue-process: Not supported on this system", | |
| 2044 Qunbound); | |
| 442 | 2045 #endif |
| 2046 return process; | |
| 2047 } | |
| 2048 | |
| 2049 DEFUN ("signal-process", Fsignal_process, 2, 2, | |
| 2050 "nProcess number: \nnSignal code: ", /* | |
| 2051 Send the process with process id PID the signal with code SIGNAL. | |
| 2052 PID must be an integer. The process need not be a child of this Emacs. | |
| 2053 SIGNAL may be an integer, or a symbol naming a signal, like `SIGSEGV'. | |
| 2054 */ | |
| 2055 (pid, signal_)) | |
| 2056 { | |
| 2057 CHECK_INT (pid); | |
| 2058 | |
| 428 | 2059 return make_int (PROCMETH_OR_GIVEN (kill_process_by_pid, |
| 442 | 2060 (XINT (pid), decode_signal (signal_)), |
| 2061 -1)); | |
| 428 | 2062 } |
| 2063 | |
| 2064 DEFUN ("process-send-eof", Fprocess_send_eof, 0, 1, 0, /* | |
| 2065 Make PROCESS see end-of-file in its input. | |
| 2066 PROCESS may be a process, a buffer, the name of a process or buffer, or | |
| 2067 nil, indicating the current buffer's process. | |
| 2068 If PROCESS is a network connection, or is a process communicating | |
| 2069 through a pipe (as opposed to a pty), then you cannot send any more | |
| 2070 text to PROCESS after you call this function. | |
| 2071 */ | |
| 2072 (process)) | |
| 2073 { | |
| 2074 /* This function can GC */ | |
| 444 | 2075 process = get_process (process); |
| 428 | 2076 |
| 2077 /* Make sure the process is really alive. */ | |
| 444 | 2078 if (! EQ (XPROCESS (process)->status_symbol, Qrun)) |
| 563 | 2079 invalid_operation ("Process not running", process); |
| 428 | 2080 |
| 444 | 2081 if (!MAYBE_INT_PROCMETH (process_send_eof, (process))) |
| 428 | 2082 { |
| 444 | 2083 if (!NILP (DATA_OUTSTREAM (XPROCESS (process)))) |
| 428 | 2084 { |
| 853 | 2085 USID humpty, dumpty; |
| 444 | 2086 Lstream_close (XLSTREAM (DATA_OUTSTREAM (XPROCESS (process)))); |
| 853 | 2087 event_stream_delete_io_streams (Qnil, |
| 2088 XPROCESS (process)->pipe_outstream, | |
| 2089 Qnil, &humpty, &dumpty); | |
| 444 | 2090 XPROCESS (process)->pipe_outstream = Qnil; |
| 2091 XPROCESS (process)->coding_outstream = Qnil; | |
| 428 | 2092 } |
| 2093 } | |
| 2094 | |
| 2095 return process; | |
| 2096 } | |
| 2097 | |
| 2098 | |
| 2099 /************************************************************************/ | |
| 2100 /* deleting a process */ | |
| 2101 /************************************************************************/ | |
| 2102 | |
| 2103 void | |
| 444 | 2104 deactivate_process (Lisp_Object process) |
| 428 | 2105 { |
| 444 | 2106 Lisp_Process *p = XPROCESS (process); |
| 853 | 2107 USID in_usid, err_usid; |
| 428 | 2108 |
| 2109 /* It's possible that we got as far in the process-creation | |
| 2110 process as creating the descriptors but didn't get so | |
| 2111 far as selecting the process for input. In this | |
| 2112 case, p->pid is nil: p->pid is set at the same time that | |
| 2113 the process is selected for input. */ | |
| 2114 /* #### The comment does not look correct. event_stream_unselect_process | |
| 853 | 2115 is guarded by process->*_selected, so this is not a problem. - kkm*/ |
| 428 | 2116 /* Must call this before setting the streams to nil */ |
| 853 | 2117 event_stream_unselect_process (p, 1, 1); |
| 428 | 2118 |
| 2119 if (!NILP (DATA_OUTSTREAM (p))) | |
| 2120 Lstream_close (XLSTREAM (DATA_OUTSTREAM (p))); | |
| 2121 if (!NILP (DATA_INSTREAM (p))) | |
| 2122 Lstream_close (XLSTREAM (DATA_INSTREAM (p))); | |
| 853 | 2123 if (!NILP (DATA_ERRSTREAM (p))) |
| 2124 Lstream_close (XLSTREAM (DATA_ERRSTREAM (p))); | |
| 428 | 2125 |
| 2126 /* Provide minimal implementation for deactivate_process | |
| 2127 if there's no process-specific one */ | |
| 2128 if (HAS_PROCMETH_P (deactivate_process)) | |
| 853 | 2129 PROCMETH (deactivate_process, (p, &in_usid, &err_usid)); |
| 428 | 2130 else |
| 853 | 2131 event_stream_delete_io_streams (p->pipe_instream, |
| 2132 p->pipe_outstream, | |
| 2133 p->pipe_errstream, | |
| 2134 &in_usid, &err_usid); | |
| 428 | 2135 |
| 853 | 2136 if (in_usid != USID_DONTHASH) |
| 2367 | 2137 remhash ((const void *) in_usid, usid_to_process); |
| 853 | 2138 if (err_usid != USID_DONTHASH) |
| 2367 | 2139 remhash ((const void *) err_usid, usid_to_process); |
| 428 | 2140 |
| 2141 p->pipe_instream = Qnil; | |
| 2142 p->pipe_outstream = Qnil; | |
| 853 | 2143 p->pipe_errstream = Qnil; |
| 428 | 2144 p->coding_instream = Qnil; |
| 2145 p->coding_outstream = Qnil; | |
| 853 | 2146 p->coding_errstream = Qnil; |
| 428 | 2147 } |
| 2148 | |
| 2149 static void | |
| 444 | 2150 remove_process (Lisp_Object process) |
| 428 | 2151 { |
| 444 | 2152 Vprocess_list = delq_no_quit (process, Vprocess_list); |
| 428 | 2153 |
| 444 | 2154 deactivate_process (process); |
| 428 | 2155 } |
| 2156 | |
| 2157 DEFUN ("delete-process", Fdelete_process, 1, 1, 0, /* | |
| 2158 Delete PROCESS: kill it and forget about it immediately. | |
| 2159 PROCESS may be a process or the name of one, or a buffer name. | |
| 2160 */ | |
| 444 | 2161 (process)) |
| 428 | 2162 { |
| 2163 /* This function can GC */ | |
| 440 | 2164 Lisp_Process *p; |
| 444 | 2165 process = get_process (process); |
| 2166 p = XPROCESS (process); | |
| 2167 if (network_connection_p (process)) | |
| 428 | 2168 { |
| 2169 p->status_symbol = Qexit; | |
| 2170 p->exit_code = 0; | |
| 2171 p->core_dumped = 0; | |
| 2172 p->tick++; | |
| 2173 process_tick++; | |
| 2174 } | |
| 440 | 2175 else if (PROCESS_LIVE_P (p)) |
| 428 | 2176 { |
| 444 | 2177 Fkill_process (process, Qnil); |
| 428 | 2178 /* Do this now, since remove_process will make sigchld_handler do nothing. */ |
| 2179 p->status_symbol = Qsignal; | |
| 2180 p->exit_code = SIGKILL; | |
| 2181 p->core_dumped = 0; | |
| 2182 p->tick++; | |
| 2183 process_tick++; | |
| 2184 status_notify (); | |
| 2185 } | |
| 444 | 2186 remove_process (process); |
| 428 | 2187 return Qnil; |
| 2188 } | |
| 2189 | |
| 2190 /* Kill all processes associated with `buffer'. | |
| 2191 If `buffer' is nil, kill all processes */ | |
| 2192 | |
| 2193 void | |
| 2194 kill_buffer_processes (Lisp_Object buffer) | |
| 2195 { | |
| 444 | 2196 LIST_LOOP_2 (process, Vprocess_list) |
| 2197 if ((NILP (buffer) || EQ (XPROCESS (process)->buffer, buffer))) | |
| 2198 { | |
| 2199 if (network_connection_p (process)) | |
| 2200 Fdelete_process (process); | |
| 2201 else if (PROCESS_LIVE_P (XPROCESS (process))) | |
| 2202 process_send_signal (process, SIGHUP, 0, 1); | |
| 2203 } | |
| 428 | 2204 } |
| 2205 | |
| 2206 DEFUN ("process-kill-without-query", Fprocess_kill_without_query, 1, 2, 0, /* | |
| 2207 Say no query needed if PROCESS is running when Emacs is exited. | |
| 2208 Optional second argument if non-nil says to require a query. | |
| 2209 Value is t if a query was formerly required. | |
| 2210 */ | |
| 444 | 2211 (process, require_query_p)) |
| 428 | 2212 { |
| 2213 int tem; | |
| 2214 | |
| 444 | 2215 CHECK_PROCESS (process); |
| 2216 tem = XPROCESS (process)->kill_without_query; | |
| 2217 XPROCESS (process)->kill_without_query = NILP (require_query_p); | |
| 428 | 2218 |
| 2219 return tem ? Qnil : Qt; | |
| 2220 } | |
| 2221 | |
| 2222 DEFUN ("process-kill-without-query-p", Fprocess_kill_without_query_p, 1, 1, 0, /* | |
| 444 | 2223 Return t if PROCESS will be killed without query when emacs is exited. |
| 428 | 2224 */ |
| 444 | 2225 (process)) |
| 428 | 2226 { |
| 444 | 2227 CHECK_PROCESS (process); |
| 2228 return XPROCESS (process)->kill_without_query ? Qt : Qnil; | |
| 428 | 2229 } |
| 2230 | |
| 2231 | |
| 2232 #if 0 | |
| 2233 | |
| 826 | 2234 DEFUN ("process-connection", Fprocess_connection, 0, 1, 0, /* |
| 428 | 2235 Return the connection type of `PROCESS'. This can be nil (pipe), |
| 2236 t or pty (pty) or stream (socket connection). | |
| 2237 */ | |
| 2238 (process)) | |
| 2239 { | |
| 2240 return XPROCESS (process)->type; | |
| 2241 } | |
| 2242 | |
| 2243 #endif /* 0 */ | |
| 2244 | |
| 814 | 2245 |
| 2246 static int | |
| 867 | 2247 getenv_internal (const Ibyte *var, |
| 814 | 2248 Bytecount varlen, |
| 867 | 2249 Ibyte **value, |
| 814 | 2250 Bytecount *valuelen) |
| 2251 { | |
| 2252 Lisp_Object scan; | |
| 2253 | |
| 2254 assert (env_initted); | |
| 2255 | |
| 2256 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | |
| 2257 { | |
| 2258 Lisp_Object entry = XCAR (scan); | |
| 2259 | |
| 2260 if (STRINGP (entry) | |
| 2261 && XSTRING_LENGTH (entry) > varlen | |
| 826 | 2262 && string_byte (entry, varlen) == '=' |
| 814 | 2263 #ifdef WIN32_NATIVE |
| 2264 /* NT environment variables are case insensitive. */ | |
| 2265 && ! memicmp (XSTRING_DATA (entry), var, varlen) | |
| 2266 #else /* not WIN32_NATIVE */ | |
| 2267 && ! memcmp (XSTRING_DATA (entry), var, varlen) | |
| 2268 #endif /* not WIN32_NATIVE */ | |
| 2269 ) | |
| 2270 { | |
| 2271 *value = XSTRING_DATA (entry) + (varlen + 1); | |
| 2272 *valuelen = XSTRING_LENGTH (entry) - (varlen + 1); | |
| 2273 return 1; | |
| 2274 } | |
| 2275 } | |
| 2276 | |
| 2277 return 0; | |
| 2278 } | |
| 2279 | |
| 2280 static void | |
| 867 | 2281 putenv_internal (const Ibyte *var, |
| 814 | 2282 Bytecount varlen, |
| 867 | 2283 const Ibyte *value, |
| 814 | 2284 Bytecount valuelen) |
| 2285 { | |
| 2286 Lisp_Object scan; | |
| 2287 | |
| 2288 assert (env_initted); | |
| 2289 | |
| 2290 for (scan = Vprocess_environment; CONSP (scan); scan = XCDR (scan)) | |
| 2291 { | |
| 2292 Lisp_Object entry = XCAR (scan); | |
| 2293 | |
| 2294 if (STRINGP (entry) | |
| 2295 && XSTRING_LENGTH (entry) > varlen | |
| 826 | 2296 && string_byte (entry, varlen) == '=' |
| 814 | 2297 #ifdef WIN32_NATIVE |
| 2298 /* NT environment variables are case insensitive. */ | |
| 2299 && ! memicmp (XSTRING_DATA (entry), var, varlen) | |
| 2300 #else /* not WIN32_NATIVE */ | |
| 2301 && ! memcmp (XSTRING_DATA (entry), var, varlen) | |
| 2302 #endif /* not WIN32_NATIVE */ | |
| 2303 ) | |
| 2304 { | |
| 2305 XCAR (scan) = concat3 (make_string (var, varlen), | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
2306 build_ascstring ("="), |
| 814 | 2307 make_string (value, valuelen)); |
| 2308 return; | |
| 2309 } | |
| 2310 } | |
| 2311 | |
| 2312 Vprocess_environment = Fcons (concat3 (make_string (var, varlen), | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
2313 build_ascstring ("="), |
| 814 | 2314 make_string (value, valuelen)), |
| 2315 Vprocess_environment); | |
| 2316 } | |
| 2317 | |
| 2318 /* NOTE: | |
| 2319 | |
| 2320 FSF has this as a Lisp function, as follows. Generally moving things | |
| 2321 out of C and into Lisp is a good idea, but in this case the Lisp | |
| 2322 function is used so early in the startup sequence that it would be ugly | |
| 2323 to rearrange the early dumped code to accommodate this. | |
| 854 | 2324 |
| 814 | 2325 (defun getenv (variable) |
| 2326 "Get the value of environment variable VARIABLE. | |
| 2327 VARIABLE should be a string. Value is nil if VARIABLE is undefined in | |
| 2328 the environment. Otherwise, value is a string. | |
| 2329 | |
| 2330 This function consults the variable `process-environment' | |
| 2331 for its value." | |
| 2332 (interactive (list (read-envvar-name "Get environment variable: " t))) | |
| 2333 (let ((value (getenv-internal variable))) | |
| 2334 (when (interactive-p) | |
| 2335 (message "%s" (if value value "Not set"))) | |
| 2336 value)) | |
| 2337 */ | |
| 2338 | |
| 2339 DEFUN ("getenv", Fgetenv, 1, 2, "sEnvironment variable: \np", /* | |
| 2340 Return the value of environment variable VAR, as a string. | |
| 2341 VAR is a string, the name of the variable. | |
| 2342 When invoked interactively, prints the value in the echo area. | |
| 2343 */ | |
| 2344 (var, interactivep)) | |
| 2345 { | |
| 4932 | 2346 Ibyte *value = NULL; |
| 814 | 2347 Bytecount valuelen; |
| 2348 Lisp_Object v = Qnil; | |
| 2349 struct gcpro gcpro1; | |
| 2350 | |
| 2351 CHECK_STRING (var); | |
| 2352 GCPRO1 (v); | |
| 2353 if (getenv_internal (XSTRING_DATA (var), XSTRING_LENGTH (var), | |
| 2354 &value, &valuelen)) | |
| 2355 v = make_string (value, valuelen); | |
| 2356 if (!NILP (interactivep)) | |
| 2357 { | |
| 2358 if (NILP (v)) | |
| 2359 message ("%s not defined in environment", XSTRING_DATA (var)); | |
| 2360 else | |
| 2361 /* #### Should use Fprin1_to_string or Fprin1 to handle string | |
| 2362 containing quotes correctly. */ | |
| 2363 message ("\"%s\"", value); | |
| 2364 } | |
| 2365 RETURN_UNGCPRO (v); | |
| 2366 } | |
| 2367 | |
| 2368 /* A version of getenv that consults Vprocess_environment, easily | |
| 2369 callable from C. | |
| 2370 | |
| 2371 (At init time, Vprocess_environment is initialized from the | |
| 2372 environment, stored in the global variable environ. [Note that | |
| 2373 at startup time, `environ' should be the same as the envp parameter | |
| 2374 passed to main(); however, later calls to putenv() may change | |
| 2375 `environ', making the envp parameter inaccurate.] Calls to getenv() | |
| 2376 and putenv() consult and modify `environ'. However, once | |
| 2377 Vprocess_environment is initted, XEmacs C code should *NEVER* call | |
| 2378 getenv() or putenv() directly, because (1) Lisp code that modifies | |
| 2379 the environment only modifies Vprocess_environment, not `environ'; | |
| 2380 and (2) Vprocess_environment is in internal format but `environ' | |
| 2381 is in some external format, and getenv()/putenv() are not Mule- | |
| 2382 encapsulated. | |
| 2383 | |
| 2384 WARNING: This value points into Lisp string data and thus will become | |
| 2385 invalid after a GC. */ | |
| 2386 | |
| 867 | 2387 Ibyte * |
| 2388 egetenv (const CIbyte *var) | |
| 814 | 2389 { |
| 2390 /* This cannot GC -- 7-28-00 ben */ | |
| 867 | 2391 Ibyte *value; |
| 814 | 2392 Bytecount valuelen; |
| 2393 | |
| 867 | 2394 if (getenv_internal ((const Ibyte *) var, strlen (var), &value, &valuelen)) |
| 814 | 2395 return value; |
| 2396 else | |
| 2397 return 0; | |
| 2398 } | |
| 2399 | |
| 2400 void | |
| 867 | 2401 eputenv (const CIbyte *var, const CIbyte *value) |
| 814 | 2402 { |
| 867 | 2403 putenv_internal ((Ibyte *) var, strlen (var), (Ibyte *) value, |
| 814 | 2404 strlen (value)); |
| 2405 } | |
| 2406 | |
| 2407 | |
| 2408 /* This is not named init_process in order to avoid a conflict with NS 3.3 */ | |
| 2409 void | |
| 2410 init_xemacs_process (void) | |
| 2411 { | |
| 2412 /* This function can GC */ | |
| 2413 | |
| 2414 MAYBE_PROCMETH (init_process, ()); | |
| 2415 | |
| 2416 Vprocess_list = Qnil; | |
| 2417 | |
| 2418 if (usid_to_process) | |
| 2419 clrhash (usid_to_process); | |
| 2420 else | |
| 2421 usid_to_process = make_hash_table (32); | |
| 854 | 2422 |
| 814 | 2423 { |
| 2424 /* jwz: always initialize Vprocess_environment, so that egetenv() | |
| 2425 works in temacs. */ | |
| 2367 | 2426 Extbyte **envp; |
| 814 | 2427 Vprocess_environment = Qnil; |
| 2367 | 2428 #ifdef WIN32_NATIVE |
| 2429 _wgetenv (L""); /* force initialization of _wenviron */ | |
| 2430 for (envp = (Extbyte **) _wenviron; envp && *envp; envp++) | |
| 2431 Vprocess_environment = | |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2432 Fcons (build_extstring (*envp, Qmswindows_unicode), |
| 2367 | 2433 Vprocess_environment); |
| 2434 #else | |
| 814 | 2435 for (envp = environ; envp && *envp; envp++) |
| 2436 Vprocess_environment = | |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2437 Fcons (build_extstring (*envp, Qenvironment_variable_encoding), |
|
4834
b3ea9c582280
Use new cygwin_conv_path API with Cygwin 1.7 for converting names between Win32 and POSIX, UTF-8-aware, with attendant changes elsewhere
Ben Wing <ben@xemacs.org>
parents:
4759
diff
changeset
|
2438 Vprocess_environment); |
| 2367 | 2439 #endif |
| 814 | 2440 /* This gets set back to 0 in disksave_object_finalization() */ |
| 2441 env_initted = 1; | |
| 2442 } | |
| 2443 | |
| 2444 { | |
| 2445 /* Initialize shell-file-name from environment variables or best guess. */ | |
| 2446 #ifdef WIN32_NATIVE | |
| 867 | 2447 const Ibyte *shell = egetenv ("SHELL"); |
| 814 | 2448 if (!shell) shell = egetenv ("COMSPEC"); |
| 2449 /* Should never happen! */ | |
| 2450 if (!shell) shell = | |
| 867 | 2451 (Ibyte *) (GetVersion () & 0x80000000 ? "command" : "cmd"); |
| 814 | 2452 #else /* not WIN32_NATIVE */ |
| 867 | 2453 const Ibyte *shell = egetenv ("SHELL"); |
| 2454 if (!shell) shell = (Ibyte *) "/bin/sh"; | |
| 814 | 2455 #endif |
| 2456 | |
| 2457 #if 0 /* defined (WIN32_NATIVE) */ | |
| 2458 /* BAD BAD BAD. We do not wanting to be passing an XEmacs-created | |
| 2459 SHELL var down to some inferior Cygwin process, which might get | |
| 2460 screwed up. | |
| 854 | 2461 |
| 814 | 2462 There are a few broken apps (eterm/term.el, eterm/tshell.el, |
| 2463 os-utils/terminal.el, texinfo/tex-mode.el) where this will | |
| 2464 cause problems. Those broken apps don't look at | |
| 2465 shell-file-name, instead just at explicit-shell-file-name, | |
| 2466 ESHELL and SHELL. They are apparently attempting to borrow | |
| 2467 what `M-x shell' uses, but that latter also looks at | |
| 2468 shell-file-name. What we want is for all of these apps to look | |
| 2469 at shell-file-name, so that the user can change the value of | |
| 2470 shell-file-name and everything will work out hunky-dorey. | |
| 2471 */ | |
| 854 | 2472 |
| 814 | 2473 if (!egetenv ("SHELL")) |
| 2474 { | |
| 2367 | 2475 Ibyte *faux_var = alloca_ibytes (7 + qxestrlen (shell)); |
| 814 | 2476 qxesprintf (faux_var, "SHELL=%s", shell); |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2477 Vprocess_environment = Fcons (build_istring (faux_var), |
| 814 | 2478 Vprocess_environment); |
| 2479 } | |
| 2480 #endif /* 0 */ | |
| 2481 | |
|
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
2482 Vshell_file_name = build_istring (shell); |
| 814 | 2483 } |
| 2484 } | |
| 2485 | |
| 428 | 2486 void |
| 2487 syms_of_process (void) | |
| 2488 { | |
|
5117
3742ea8250b5
Checking in final CVS version of workspace 'ben-lisp-object'
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
2489 INIT_LISP_OBJECT (process); |
| 442 | 2490 |
| 563 | 2491 DEFSYMBOL (Qprocessp); |
| 2492 DEFSYMBOL (Qprocess_live_p); | |
| 2493 DEFSYMBOL (Qrun); | |
| 2494 DEFSYMBOL (Qstop); | |
| 2495 DEFSYMBOL (Qopen); | |
| 2496 DEFSYMBOL (Qclosed); | |
| 863 | 2497 #if 0 |
| 2498 /* see comment at Fprocess_readable_p */ | |
| 2499 DEFSYMBOL (&Qprocess_readable_p); | |
| 2500 #endif | |
| 563 | 2501 DEFSYMBOL (Qtcp); |
| 2502 DEFSYMBOL (Qudp); | |
| 428 | 2503 |
| 2504 #ifdef HAVE_MULTICAST | |
| 563 | 2505 DEFSYMBOL (Qmulticast); /* Used for occasional warnings */ |
| 428 | 2506 #endif |
| 2507 | |
| 563 | 2508 DEFERROR_STANDARD (Qprocess_error, Qio_error); |
| 2509 DEFERROR_STANDARD (Qnetwork_error, Qio_error); | |
| 2510 | |
| 428 | 2511 DEFSUBR (Fprocessp); |
| 440 | 2512 DEFSUBR (Fprocess_live_p); |
| 863 | 2513 #if 0 |
| 2514 /* see comment at Fprocess_readable_p */ | |
| 2515 DEFSUBR (Fprocess_readable_p); | |
| 2516 #endif | |
| 428 | 2517 DEFSUBR (Fget_process); |
| 2518 DEFSUBR (Fget_buffer_process); | |
| 2519 DEFSUBR (Fdelete_process); | |
| 2520 DEFSUBR (Fprocess_status); | |
| 2521 DEFSUBR (Fprocess_exit_status); | |
| 2522 DEFSUBR (Fprocess_id); | |
| 2523 DEFSUBR (Fprocess_name); | |
| 2524 DEFSUBR (Fprocess_tty_name); | |
| 2525 DEFSUBR (Fprocess_command); | |
| 859 | 2526 DEFSUBR (Fprocess_has_separate_stderr_p); |
| 428 | 2527 DEFSUBR (Fset_process_buffer); |
| 853 | 2528 DEFSUBR (Fset_process_stderr_buffer); |
| 428 | 2529 DEFSUBR (Fprocess_buffer); |
| 2530 DEFSUBR (Fprocess_mark); | |
| 853 | 2531 DEFSUBR (Fprocess_stderr_buffer); |
| 2532 DEFSUBR (Fprocess_stderr_mark); | |
| 428 | 2533 DEFSUBR (Fset_process_filter); |
| 2534 DEFSUBR (Fprocess_filter); | |
| 853 | 2535 DEFSUBR (Fset_process_stderr_filter); |
| 2536 DEFSUBR (Fprocess_stderr_filter); | |
| 428 | 2537 DEFSUBR (Fset_process_window_size); |
| 2538 DEFSUBR (Fset_process_sentinel); | |
| 2539 DEFSUBR (Fprocess_sentinel); | |
| 2540 DEFSUBR (Fprocess_kill_without_query); | |
| 2541 DEFSUBR (Fprocess_kill_without_query_p); | |
| 2542 DEFSUBR (Fprocess_list); | |
| 2543 DEFSUBR (Fstart_process_internal); | |
| 2544 #ifdef HAVE_SOCKETS | |
| 2545 DEFSUBR (Fopen_network_stream_internal); | |
| 2546 #ifdef HAVE_MULTICAST | |
| 2547 DEFSUBR (Fopen_multicast_group_internal); | |
| 2548 #endif /* HAVE_MULTICAST */ | |
| 2549 #endif /* HAVE_SOCKETS */ | |
| 2550 DEFSUBR (Fprocess_send_region); | |
| 2551 DEFSUBR (Fprocess_send_string); | |
| 442 | 2552 DEFSUBR (Fprocess_send_signal); |
| 428 | 2553 DEFSUBR (Finterrupt_process); |
| 2554 DEFSUBR (Fkill_process); | |
| 2555 DEFSUBR (Fquit_process); | |
| 2556 DEFSUBR (Fstop_process); | |
| 2557 DEFSUBR (Fcontinue_process); | |
| 2558 DEFSUBR (Fprocess_send_eof); | |
| 2559 DEFSUBR (Fsignal_process); | |
| 2560 /* DEFSUBR (Fprocess_connection); */ | |
| 2561 DEFSUBR (Fprocess_input_coding_system); | |
| 2562 DEFSUBR (Fprocess_output_coding_system); | |
| 2563 DEFSUBR (Fset_process_input_coding_system); | |
| 2564 DEFSUBR (Fset_process_output_coding_system); | |
| 2565 DEFSUBR (Fprocess_coding_system); | |
| 2566 DEFSUBR (Fset_process_coding_system); | |
| 814 | 2567 DEFSUBR (Fgetenv); |
| 428 | 2568 } |
| 2569 | |
| 2570 void | |
| 2571 vars_of_process (void) | |
| 2572 { | |
| 2573 Fprovide (intern ("subprocesses")); | |
| 2574 #ifdef HAVE_SOCKETS | |
| 2575 Fprovide (intern ("network-streams")); | |
| 2576 #ifdef HAVE_MULTICAST | |
| 2577 Fprovide (intern ("multicast")); | |
| 2578 #endif /* HAVE_MULTICAST */ | |
| 2579 #endif /* HAVE_SOCKETS */ | |
| 2580 staticpro (&Vprocess_list); | |
| 2581 | |
| 2582 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes /* | |
| 2583 *Non-nil means delete processes immediately when they exit. | |
| 2584 nil means don't delete them until `list-processes' is run. | |
| 2585 */ ); | |
| 2586 | |
| 2587 delete_exited_processes = 1; | |
| 2588 | |
| 442 | 2589 DEFVAR_CONST_LISP ("null-device", &Vnull_device /* |
| 2590 Name of the null device, which differs from system to system. | |
| 2591 The null device is a filename that acts as a sink for arbitrary amounts of | |
| 2592 data, which is discarded, or as a source for a zero-length file. | |
| 2593 It is available on all the systems that we currently support, but with | |
| 2594 different names (typically either `/dev/null' or `nul'). | |
| 2595 | |
| 2596 Note that there is also a /dev/zero on most modern Unix versions (including | |
| 2597 Cygwin), which acts like /dev/null when used as a sink, but as a source | |
| 2598 it sends a non-ending stream of zero bytes. It's used most often along | |
| 2599 with memory-mapping. We don't provide a Lisp variable for this because | |
| 2600 the operations needing this are lower level than what ELisp programs | |
| 2601 typically do, and in any case no equivalent exists under native MS Windows. | |
| 2602 */ ); | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
2603 Vnull_device = build_ascstring (NULL_DEVICE); |
| 442 | 2604 |
| 428 | 2605 DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type /* |
| 2606 Control type of device used to communicate with subprocesses. | |
| 2607 Values are nil to use a pipe, or t or `pty' to use a pty. | |
| 2608 The value has no effect if the system has no ptys or if all ptys are busy: | |
| 2609 then a pipe is used in any case. | |
| 2610 The value takes effect when `start-process' is called. | |
| 2611 */ ); | |
| 2612 Vprocess_connection_type = Qt; | |
| 2613 | |
| 2614 DEFVAR_BOOL ("windowed-process-io", &windowed_process_io /* | |
| 2615 Enables input/output on standard handles of a windowed process. | |
| 2616 When this variable is nil (the default), XEmacs does not attempt to read | |
| 2617 standard output handle of a windowed process. Instead, the process is | |
| 2618 immediately marked as exited immediately upon successful launching. This is | |
| 2619 done because normal windowed processes do not use standard I/O, as they are | |
| 2620 not connected to any console. | |
| 2621 | |
| 2622 When launching a specially crafted windowed process, which expects to be | |
| 2623 launched by XEmacs, or by other program which pipes its standard input and | |
| 2624 output, this variable must be set to non-nil, in which case XEmacs will | |
| 2625 treat this process just like a console process. | |
| 2626 | |
| 2627 NOTE: You should never set this variable, only bind it. | |
| 2628 | |
| 2629 Only Windows processes can be "windowed" or "console". This variable has no | |
| 2630 effect on UNIX processes, because all UNIX processes are "console". | |
| 2631 */ ); | |
| 2632 windowed_process_io = 0; | |
| 2633 | |
| 771 | 2634 DEFVAR_INT ("debug-process-io", &debug_process_io /* |
| 2635 If non-zero, display data sent to or received from a process. | |
| 2636 */ ); | |
| 2637 debug_process_io = 0; | |
| 2638 | |
| 2639 DEFVAR_LISP ("default-process-coding-system", | |
| 2640 &Vdefault_process_coding_system /* | |
| 2641 Cons of coding systems used for process I/O by default. | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
2642 May also be nil, interpreted as (nil . nil). |
| 771 | 2643 The car part is used for reading (decoding) data from a process, and |
| 2644 the cdr part is used for writing (encoding) data to a process. | |
| 2645 */ ); | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
2646 /* Better, system-dependent defaults are set in code-init.el. */ |
| 771 | 2647 Vdefault_process_coding_system = Fcons (Qundecided, Qnil); |
| 2648 | |
| 853 | 2649 DEFVAR_LISP ("default-network-coding-system", |
| 2650 &Vdefault_network_coding_system /* | |
| 2651 Cons of coding systems used for network I/O by default. | |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
2652 May also be nil, interpreted as (nil . nil). |
| 853 | 2653 The car part is used for reading (decoding) data from a process, and |
| 2654 the cdr part is used for writing (encoding) data to a process. | |
| 2655 */ ); | |
| 2656 Vdefault_network_coding_system = Fcons (Qundecided, Qnil); | |
| 2657 | |
| 428 | 2658 #ifdef PROCESS_IO_BLOCKING |
| 2659 DEFVAR_LISP ("network-stream-blocking-port-list", &network_stream_blocking_port_list /* | |
| 2660 List of port numbers or port names to set a blocking I/O mode with connection. | |
| 862 | 2661 Nil value means to set a default (non-blocking) I/O mode. |
| 428 | 2662 The value takes effect when `open-network-stream-internal' is called. |
| 2663 */ ); | |
| 2664 network_stream_blocking_port_list = Qnil; | |
| 2665 #endif /* PROCESS_IO_BLOCKING */ | |
| 814 | 2666 |
| 2667 /* This function can GC */ | |
| 2668 DEFVAR_LISP ("shell-file-name", &Vshell_file_name /* | |
| 2669 *File name to load inferior shells from. | |
| 2670 Initialized from the SHELL environment variable. | |
| 2671 */ ); | |
| 428 | 2672 |
|
4729
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
2673 /* ben? thinks the format of this variable is "semi-bogus". |
|
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
2674 sjt doesn't agree, since it captures a restriction that is |
|
428d7c571110
Fix issue145: accept nil in default-process-coding-system.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4693
diff
changeset
|
2675 present in POSIX shells, after all. */ |
| 814 | 2676 DEFVAR_LISP ("process-environment", &Vprocess_environment /* |
| 2677 List of environment variables for subprocesses to inherit. | |
| 2678 Each element should be a string of the form ENVVARNAME=VALUE. | |
| 2679 The environment which Emacs inherits is placed in this variable | |
| 2680 when Emacs starts. | |
| 2681 */ ); | |
| 2682 | |
|
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
2683 Vlisp_EXEC_SUFFIXES = build_ascstring (EXEC_SUFFIXES); |
| 814 | 2684 staticpro (&Vlisp_EXEC_SUFFIXES); |
| 2685 } |
