X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/dd97db06184ed309989a6c8d876cde653707e705..fbb70ad9e6e00f3f146b50d3bf433a6ec6ce26c9:/src/process.c diff --git a/src/process.c b/src/process.c index 1394b6b8b3..56d3a67e8d 100644 --- a/src/process.c +++ b/src/process.c @@ -1,5 +1,5 @@ /* Asynchronous subprocess control for GNU Emacs. - Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 98, 1999 + Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 98, 1999, 2001 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -111,8 +111,6 @@ Boston, MA 02111-1307, USA. */ #include "composite.h" #include "atimer.h" -#define max(a, b) ((a) > (b) ? (a) : (b)) - Lisp_Object Qprocessp; Lisp_Object Qrun, Qstop, Qsignal, Qopen, Qclosed; Lisp_Object Qlast_nonmenu_event; @@ -434,17 +432,12 @@ Lisp_Object make_process (name) Lisp_Object name; { - struct Lisp_Vector *vec; register Lisp_Object val, tem, name1; register struct Lisp_Process *p; char suffix[10]; register int i; - vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct Lisp_Process)); - for (i = 0; i < VECSIZE (struct Lisp_Process); i++) - vec->contents[i] = Qnil; - vec->size = VECSIZE (struct Lisp_Process); - p = (struct Lisp_Process *)vec; + p = allocate_process (); XSETINT (p->infd, -1); XSETINT (p->outfd, -1); @@ -486,28 +479,28 @@ remove_process (proc) } DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0, - "Return t if OBJECT is a process.") - (object) + doc: /* Return t if OBJECT is a process. */) + (object) Lisp_Object object; { return PROCESSP (object) ? Qt : Qnil; } DEFUN ("get-process", Fget_process, Sget_process, 1, 1, 0, - "Return the process named NAME, or nil if there is none.") - (name) + doc: /* Return the process named NAME, or nil if there is none. */) + (name) register Lisp_Object name; { if (PROCESSP (name)) return name; - CHECK_STRING (name, 0); + CHECK_STRING (name); return Fcdr (Fassoc (name, Vprocess_alist)); } DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, - "Return the (or a) process associated with BUFFER.\n\ -BUFFER may be a buffer or the name of one.") - (buffer) + doc: /* Return the (or a) process associated with BUFFER. +BUFFER may be a buffer or the name of one. */) + (buffer) register Lisp_Object buffer; { register Lisp_Object buf, tail, proc; @@ -558,17 +551,17 @@ get_process (name) } else { - CHECK_PROCESS (obj, 0); + CHECK_PROCESS (obj); proc = obj; } return proc; } DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, - "Delete PROCESS: kill it and forget about it immediately.\n\ -PROCESS may be a process, a buffer, the name of a process or buffer, or\n\ -nil, indicating the current buffer's process.") - (process) + doc: /* Delete PROCESS: kill it and forget about it immediately. +PROCESS may be a process, a buffer, the name of a process or buffer, or +nil, indicating the current buffer's process. */) + (process) register Lisp_Object process; { process = get_process (process); @@ -593,18 +586,18 @@ nil, indicating the current buffer's process.") } DEFUN ("process-status", Fprocess_status, Sprocess_status, 1, 1, 0, - "Return the status of PROCESS.\n\ -The returned value is one of the following symbols:\n\ -run -- for a process that is running.\n\ -stop -- for a process stopped but continuable.\n\ -exit -- for a process that has exited.\n\ -signal -- for a process that has got a fatal signal.\n\ -open -- for a network stream connection that is open.\n\ -closed -- for a network stream connection that is closed.\n\ -nil -- if arg is a process name and no such process exists.\n\ -PROCESS may be a process, a buffer, the name of a process, or\n\ -nil, indicating the current buffer's process.") - (process) + doc: /* Return the status of PROCESS. +The returned value is one of the following symbols: +run -- for a process that is running. +stop -- for a process stopped but continuable. +exit -- for a process that has exited. +signal -- for a process that has got a fatal signal. +open -- for a network stream connection that is open. +closed -- for a network stream connection that is closed. +nil -- if arg is a process name and no such process exists. +PROCESS may be a process, a buffer, the name of a process, or +nil, indicating the current buffer's process. */) + (process) register Lisp_Object process; { register struct Lisp_Process *p; @@ -636,12 +629,12 @@ nil, indicating the current buffer's process.") DEFUN ("process-exit-status", Fprocess_exit_status, Sprocess_exit_status, 1, 1, 0, - "Return the exit status of PROCESS or the signal number that killed it.\n\ -If PROCESS has not yet exited or died, return 0.") - (process) + doc: /* Return the exit status of PROCESS or the signal number that killed it. +If PROCESS has not yet exited or died, return 0. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); if (!NILP (XPROCESS (process)->raw_status_low)) update_status (XPROCESS (process)); if (CONSP (XPROCESS (process)->status)) @@ -650,211 +643,229 @@ If PROCESS has not yet exited or died, return 0.") } DEFUN ("process-id", Fprocess_id, Sprocess_id, 1, 1, 0, - "Return the process id of PROCESS.\n\ -This is the pid of the Unix process which PROCESS uses or talks to.\n\ -For a network connection, this value is nil.") - (process) + doc: /* Return the process id of PROCESS. +This is the pid of the Unix process which PROCESS uses or talks to. +For a network connection, this value is nil. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->pid; } DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0, - "Return the name of PROCESS, as a string.\n\ -This is the name of the program invoked in PROCESS,\n\ -possibly modified to make it unique among process names.") - (process) + doc: /* Return the name of PROCESS, as a string. +This is the name of the program invoked in PROCESS, +possibly modified to make it unique among process names. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->name; } DEFUN ("process-command", Fprocess_command, Sprocess_command, 1, 1, 0, - "Return the command that was executed to start PROCESS.\n\ -This is a list of strings, the first string being the program executed\n\ -and the rest of the strings being the arguments given to it.\n\ -For a non-child channel, this is nil.") - (process) + doc: /* Return the command that was executed to start PROCESS. +This is a list of strings, the first string being the program executed +and the rest of the strings being the arguments given to it. +For a non-child channel, this is nil. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->command; } DEFUN ("process-tty-name", Fprocess_tty_name, Sprocess_tty_name, 1, 1, 0, - "Return the name of the terminal PROCESS uses, or nil if none.\n\ -This is the terminal that the process itself reads and writes on,\n\ -not the name of the pty that Emacs uses to talk with that terminal.") - (process) + doc: /* Return the name of the terminal PROCESS uses, or nil if none. +This is the terminal that the process itself reads and writes on, +not the name of the pty that Emacs uses to talk with that terminal. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->tty_name; } DEFUN ("set-process-buffer", Fset_process_buffer, Sset_process_buffer, - 2, 2, 0, - "Set buffer associated with PROCESS to BUFFER (a buffer, or nil).") - (process, buffer) + 2, 2, 0, + doc: /* Set buffer associated with PROCESS to BUFFER (a buffer, or nil). */) + (process, buffer) register Lisp_Object process, buffer; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); if (!NILP (buffer)) - CHECK_BUFFER (buffer, 1); + CHECK_BUFFER (buffer); XPROCESS (process)->buffer = buffer; return buffer; } DEFUN ("process-buffer", Fprocess_buffer, Sprocess_buffer, - 1, 1, 0, - "Return the buffer PROCESS is associated with.\n\ -Output from PROCESS is inserted in this buffer unless PROCESS has a filter.") - (process) + 1, 1, 0, + doc: /* Return the buffer PROCESS is associated with. +Output from PROCESS is inserted in this buffer unless PROCESS has a filter. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->buffer; } DEFUN ("process-mark", Fprocess_mark, Sprocess_mark, - 1, 1, 0, - "Return the marker for the end of the last output from PROCESS.") - (process) + 1, 1, 0, + doc: /* Return the marker for the end of the last output from PROCESS. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->mark; } DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, - 2, 2, 0, - "Give PROCESS the filter function FILTER; nil means no filter.\n\ -t means stop accepting output from the process.\n\ -When a process has a filter, each time it does output\n\ -the entire string of output is passed to the filter.\n\ -The filter gets two arguments: the process and the string of output.\n\ -If the process has a filter, its buffer is not used for output.") - (process, filter) + 2, 2, 0, + doc: /* Give PROCESS the filter function FILTER; nil means no filter. +t means stop accepting output from the process. +When a process has a filter, each time it does output +the entire string of output is passed to the filter. +The filter gets two arguments: the process and the string of output. +If the process has a filter, its buffer is not used for output. */) + (process, filter) register Lisp_Object process, filter; { - CHECK_PROCESS (process, 0); - if (EQ (filter, Qt)) - { - FD_CLR (XINT (XPROCESS (process)->infd), &input_wait_mask); - FD_CLR (XINT (XPROCESS (process)->infd), &non_keyboard_wait_mask); - } - else if (EQ (XPROCESS (process)->filter, Qt)) + struct Lisp_Process *p; + + CHECK_PROCESS (process); + p = XPROCESS (process); + + /* Don't signal an error if the process' input file descriptor + is closed. This could make debugging Lisp more difficult, + for example when doing something like + + (setq process (start-process ...)) + (debug) + (set-process-filter process ...) */ + + if (XINT (p->infd) >= 0) { - FD_SET (XINT (XPROCESS (process)->infd), &input_wait_mask); - FD_SET (XINT (XPROCESS (process)->infd), &non_keyboard_wait_mask); + if (EQ (filter, Qt)) + { + FD_CLR (XINT (p->infd), &input_wait_mask); + FD_CLR (XINT (p->infd), &non_keyboard_wait_mask); + } + else if (EQ (XPROCESS (process)->filter, Qt)) + { + FD_SET (XINT (p->infd), &input_wait_mask); + FD_SET (XINT (p->infd), &non_keyboard_wait_mask); + } } - XPROCESS (process)->filter = filter; + + p->filter = filter; return filter; } DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, - 1, 1, 0, - "Returns the filter function of PROCESS; nil if none.\n\ -See `set-process-filter' for more info on filter functions.") - (process) + 1, 1, 0, + doc: /* Returns the filter function of PROCESS; nil if none. +See `set-process-filter' for more info on filter functions. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->filter; } DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel, - 2, 2, 0, - "Give PROCESS the sentinel SENTINEL; nil for none.\n\ -The sentinel is called as a function when the process changes state.\n\ -It gets two arguments: the process, and a string describing the change.") - (process, sentinel) + 2, 2, 0, + doc: /* Give PROCESS the sentinel SENTINEL; nil for none. +The sentinel is called as a function when the process changes state. +It gets two arguments: the process, and a string describing the change. */) + (process, sentinel) register Lisp_Object process, sentinel; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); XPROCESS (process)->sentinel = sentinel; return sentinel; } DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel, - 1, 1, 0, - "Return the sentinel of PROCESS; nil if none.\n\ -See `set-process-sentinel' for more info on sentinels.") - (process) + 1, 1, 0, + doc: /* Return the sentinel of PROCESS; nil if none. +See `set-process-sentinel' for more info on sentinels. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->sentinel; } DEFUN ("set-process-window-size", Fset_process_window_size, - Sset_process_window_size, 3, 3, 0, - "Tell PROCESS that it has logical window size HEIGHT and WIDTH.") - (process, height, width) + Sset_process_window_size, 3, 3, 0, + doc: /* Tell PROCESS that it has logical window size HEIGHT and WIDTH. */) + (process, height, width) register Lisp_Object process, height, width; { - CHECK_PROCESS (process, 0); - CHECK_NATNUM (height, 0); - CHECK_NATNUM (width, 0); - if (set_window_size (XINT (XPROCESS (process)->infd), - XINT (height), XINT (width)) <= 0) + CHECK_PROCESS (process); + CHECK_NATNUM (height); + CHECK_NATNUM (width); + + if (XINT (XPROCESS (process)->infd) < 0 + || set_window_size (XINT (XPROCESS (process)->infd), + XINT (height), XINT (width)) <= 0) return Qnil; else return Qt; } DEFUN ("set-process-inherit-coding-system-flag", - Fset_process_inherit_coding_system_flag, - Sset_process_inherit_coding_system_flag, 2, 2, 0, - "Determine whether buffer of PROCESS will inherit coding-system.\n\ -If the second argument FLAG is non-nil, then the variable\n\ -`buffer-file-coding-system' of the buffer associated with PROCESS\n\ -will be bound to the value of the coding system used to decode\n\ -the process output.\n\ -\n\ -This is useful when the coding system specified for the process buffer\n\ -leaves either the character code conversion or the end-of-line conversion\n\ -unspecified, or if the coding system used to decode the process output\n\ -is more appropriate for saving the process buffer.\n\ -\n\ -Binding the variable `inherit-process-coding-system' to non-nil before\n\ -starting the process is an alternative way of setting the inherit flag\n\ -for the process which will run.") - (process, flag) + Fset_process_inherit_coding_system_flag, + Sset_process_inherit_coding_system_flag, 2, 2, 0, + doc: /* Determine whether buffer of PROCESS will inherit coding-system. +If the second argument FLAG is non-nil, then the variable +`buffer-file-coding-system' of the buffer associated with PROCESS +will be bound to the value of the coding system used to decode +the process output. + +This is useful when the coding system specified for the process buffer +leaves either the character code conversion or the end-of-line conversion +unspecified, or if the coding system used to decode the process output +is more appropriate for saving the process buffer. + +Binding the variable `inherit-process-coding-system' to non-nil before +starting the process is an alternative way of setting the inherit flag +for the process which will run. */) + (process, flag) register Lisp_Object process, flag; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); XPROCESS (process)->inherit_coding_system_flag = flag; return flag; } DEFUN ("process-inherit-coding-system-flag", - Fprocess_inherit_coding_system_flag, Sprocess_inherit_coding_system_flag, - 1, 1, 0, - "Return the value of inherit-coding-system flag for PROCESS.\n\ -If this flag is t, `buffer-file-coding-system' of the buffer\n\ -associated with PROCESS will inherit the coding system used to decode\n\ -the process output.") - (process) + Fprocess_inherit_coding_system_flag, Sprocess_inherit_coding_system_flag, + 1, 1, 0, + doc: /* Return the value of inherit-coding-system flag for PROCESS. +If this flag is t, `buffer-file-coding-system' of the buffer +associated with PROCESS will inherit the coding system used to decode +the process output. */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->inherit_coding_system_flag; } DEFUN ("process-kill-without-query", Fprocess_kill_without_query, - Sprocess_kill_without_query, 1, 2, 0, - "Say no query needed if PROCESS is running when Emacs is exited.\n\ -Optional second argument if non-nil says to require a query.\n\ -Value is t if a query was formerly required.") - (process, value) + Sprocess_kill_without_query, 1, 2, 0, + doc: /* Say no query needed if PROCESS is running when Emacs is exited. +Optional second argument if non-nil says to require a query. +Value is t if a query was formerly required. */) + (process, value) register Lisp_Object process, value; { Lisp_Object tem; - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); tem = XPROCESS (process)->kill_without_query; XPROCESS (process)->kill_without_query = Fnull (value); @@ -862,23 +873,23 @@ Value is t if a query was formerly required.") } DEFUN ("process-contact", Fprocess_contact, Sprocess_contact, - 1, 1, 0, - "Return the contact info of PROCESS; t for a real child.\n\ -For a net connection, the value is a cons cell of the form (HOST SERVICE).") - (process) + 1, 1, 0, + doc: /* Return the contact info of PROCESS; t for a real child. +For a net connection, the value is a cons cell of the form (HOST SERVICE). */) + (process) register Lisp_Object process; { - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); return XPROCESS (process)->childp; } #if 0 /* Turned off because we don't currently record this info in the process. Perhaps add it. */ DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0, - "Return the connection type of PROCESS.\n\ -The value is nil for a pipe, t or `pty' for a pty, or `stream' for\n\ -a socket connection.") - (process) + doc: /* Return the connection type of PROCESS. +The value is nil for a pipe, t or `pty' for a pty, or `stream' for +a socket connection. */) + (process) Lisp_Object process; { return XPROCESS (process)->type; @@ -1002,10 +1013,10 @@ Proc Status Buffer Tty Command\n\ } DEFUN ("list-processes", Flist_processes, Slist_processes, 0, 0, "", - "Display a list of all processes.\n\ -Any process listed as exited or signaled is actually eliminated\n\ -after the listing is made.") - () + doc: /* Display a list of all processes. +Any process listed as exited or signaled is actually eliminated +after the listing is made. */) + () { internal_with_output_to_temp_buffer ("*Process List*", list_processes_1, Qnil); @@ -1013,8 +1024,8 @@ after the listing is made.") } DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, - "Return a list of all processes.") - () + doc: /* Return a list of all processes. */) + () { return Fmapcar (Qcdr, Vprocess_alist); } @@ -1024,16 +1035,17 @@ DEFUN ("process-list", Fprocess_list, Sprocess_list, 0, 0, 0, static Lisp_Object start_process_unwind (); DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0, - "Start a program in a subprocess. Return the process object for it.\n\ -NAME is name for process. It is modified if necessary to make it unique.\n\ -BUFFER is the buffer or (buffer-name) to associate with the process.\n\ - Process output goes at end of that buffer, unless you specify\n\ - an output stream or filter function to handle the output.\n\ - BUFFER may be also nil, meaning that this process is not associated\n\ - with any buffer.\n\ -Third arg is program file name. It is searched for in PATH.\n\ -Remaining arguments are strings to give program as arguments.") - (nargs, args) + doc: /* Start a program in a subprocess. Return the process object for it. +NAME is name for process. It is modified if necessary to make it unique. +BUFFER is the buffer or (buffer-name) to associate with the process. + Process output goes at end of that buffer, unless you specify + an output stream or filter function to handle the output. + BUFFER may be also nil, meaning that this process is not associated + with any buffer. +Third arg is program file name. It is searched for in PATH. +Remaining arguments are strings to give program as arguments. +usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) + (nargs, args) int nargs; register Lisp_Object *args; { @@ -1078,11 +1090,11 @@ Remaining arguments are strings to give program as arguments.") } name = args[0]; - CHECK_STRING (name, 0); + CHECK_STRING (name); program = args[2]; - CHECK_STRING (program, 2); + CHECK_STRING (program); proc = make_process (name); /* If an error occurs and we can't start the process, we want to @@ -1157,7 +1169,7 @@ Remaining arguments are strings to give program as arguments.") for (i = 3; i < nargs; i++) { tem = args[i]; - CHECK_STRING (tem, i); + CHECK_STRING (tem); len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */ } new_argv = (unsigned char *) alloca (len); @@ -1165,7 +1177,7 @@ Remaining arguments are strings to give program as arguments.") for (i = 3; i < nargs; i++) { tem = args[i]; - CHECK_STRING (tem, i); + CHECK_STRING (tem); strcat (new_argv, " "); strcat (new_argv, XSTRING (tem)->data); } @@ -1183,7 +1195,7 @@ Remaining arguments are strings to give program as arguments.") tem = Qnil; GCPRO4 (name, program, buffer, current_dir); - openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1); + openp (Vexec_path, program, Vexec_suffixes, &tem, 1); UNGCPRO; if (NILP (tem)) report_file_error ("Searching for program", Fcons (program, Qnil)); @@ -1208,7 +1220,7 @@ Remaining arguments are strings to give program as arguments.") for (i = 3; i < nargs; i++) { tem = args[i]; - CHECK_STRING (tem, i); + CHECK_STRING (tem); if (STRING_MULTIBYTE (tem)) tem = (code_convert_string_norecord (tem, XPROCESS (proc)->encode_coding_system, 1)); @@ -1306,7 +1318,6 @@ create_process (process, new_argv, current_dir) #ifndef USE_CRT_DLL extern char **environ; #endif - Lisp_Object buffer = XPROCESS (process)->buffer; inchannel = outchannel = -1; @@ -1417,7 +1428,7 @@ create_process (process, new_argv, current_dir) #ifdef SIGCHLD sigaddset (&blocked, SIGCHLD); #endif -#ifdef HAVE_VFORK +#ifdef HAVE_WORKING_VFORK /* On many hosts (e.g. Solaris 2.4), if a vforked child calls `signal', this sets the parent's signal handlers as well as the child's. So delay all interrupts whose handlers the child might munge, @@ -1427,7 +1438,7 @@ create_process (process, new_argv, current_dir) #ifdef AIX sigaddset (&blocked, SIGHUP ); sigaction (SIGHUP , 0, &sighup_action ); #endif -#endif /* HAVE_VFORK */ +#endif /* HAVE_WORKING_VFORK */ sigprocmask (SIG_BLOCK, &blocked, &procmask); #else /* !POSIX_SIGNALS */ #ifdef SIGCHLD @@ -1685,14 +1696,14 @@ create_process (process, new_argv, current_dir) /* Restore the signal state whether vfork succeeded or not. (We will signal an error, below, if it failed.) */ #ifdef POSIX_SIGNALS -#ifdef HAVE_VFORK +#ifdef HAVE_WORKING_VFORK /* Restore the parent's signal handlers. */ sigaction (SIGINT, &sigint_action, 0); sigaction (SIGQUIT, &sigquit_action, 0); #ifdef AIX sigaction (SIGHUP, &sighup_action, 0); #endif -#endif /* HAVE_VFORK */ +#endif /* HAVE_WORKING_VFORK */ /* Stop blocking signals in the parent. */ sigprocmask (SIG_SETMASK, &procmask, 0); #else /* !POSIX_SIGNALS */ @@ -1731,20 +1742,20 @@ create_process (process, new_argv, current_dir) DEFUN ("open-network-stream", Fopen_network_stream, Sopen_network_stream, 4, 4, 0, - "Open a TCP connection for a service to a host.\n\ -Returns a subprocess-object to represent the connection.\n\ -Input and output work as for subprocesses; `delete-process' closes it.\n\ -Args are NAME BUFFER HOST SERVICE.\n\ -NAME is name for process. It is modified if necessary to make it unique.\n\ -BUFFER is the buffer (or buffer-name) to associate with the process.\n\ - Process output goes at end of that buffer, unless you specify\n\ - an output stream or filter function to handle the output.\n\ - BUFFER may be also nil, meaning that this process is not associated\n\ - with any buffer\n\ -Third arg is name of the host to connect to, or its IP address.\n\ -Fourth arg SERVICE is name of the service desired, or an integer\n\ - specifying a port number to connect to.") - (name, buffer, host, service) + doc: /* Open a TCP connection for a service to a host. +Returns a subprocess-object to represent the connection. +Input and output work as for subprocesses; `delete-process' closes it. +Args are NAME BUFFER HOST SERVICE. +NAME is name for process. It is modified if necessary to make it unique. +BUFFER is the buffer (or buffer-name) to associate with the process. + Process output goes at end of that buffer, unless you specify + an output stream or filter function to handle the output. + BUFFER may be also nil, meaning that this process is not associated + with any buffer +Third arg is name of the host to connect to, or its IP address. +Fourth arg SERVICE is name of the service desired, or an integer +specifying a port number to connect to. */) + (name, buffer, host, service) Lisp_Object name, buffer, host, service; { Lisp_Object proc; @@ -1773,8 +1784,8 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ #endif GCPRO4 (name, buffer, host, service); - CHECK_STRING (name, 0); - CHECK_STRING (host, 0); + CHECK_STRING (name); + CHECK_STRING (host); #ifdef HAVE_GETADDRINFO /* SERVICE can either be a string or int. @@ -1786,7 +1797,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ } else { - CHECK_STRING (service, 0); + CHECK_STRING (service); portstring = XSTRING (service)->data; } #else /* HAVE_GETADDRINFO */ @@ -1794,7 +1805,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\ port = htons ((unsigned short) XINT (service)); else { - CHECK_STRING (service, 0); + CHECK_STRING (service); svc_info = getservbyname (XSTRING (service)->data, "tcp"); if (svc_info == 0) error ("Unknown service \"%s\"", XSTRING (service)->data); @@ -2223,27 +2234,27 @@ close_process_descs () } DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output, - 0, 3, 0, - "Allow any pending output from subprocesses to be read by Emacs.\n\ -It is read into the process' buffers or given to their filter functions.\n\ -Non-nil arg PROCESS means do not return until some output has been received\n\ -from PROCESS.\n\ -Non-nil second arg TIMEOUT and third arg TIMEOUT-MSECS are number of\n\ -seconds and microseconds to wait; return after that much time whether\n\ -or not there is input.\n\ -Return non-nil iff we received any output before the timeout expired.") - (process, timeout, timeout_msecs) + 0, 3, 0, + doc: /* Allow any pending output from subprocesses to be read by Emacs. +It is read into the process' buffers or given to their filter functions. +Non-nil arg PROCESS means do not return until some output has been received +from PROCESS. +Non-nil second arg TIMEOUT and third arg TIMEOUT-MSECS are number of +seconds and microseconds to wait; return after that much time whether +or not there is input. +Return non-nil iff we received any output before the timeout expired. */) + (process, timeout, timeout_msecs) register Lisp_Object process, timeout, timeout_msecs; { int seconds; int useconds; if (! NILP (process)) - CHECK_PROCESS (process, 0); + CHECK_PROCESS (process); if (! NILP (timeout_msecs)) { - CHECK_NUMBER (timeout_msecs, 2); + CHECK_NUMBER (timeout_msecs); useconds = XINT (timeout_msecs); if (!INTEGERP (timeout)) XSETINT (timeout, 0); @@ -2269,7 +2280,7 @@ Return non-nil iff we received any output before the timeout expired.") if (! NILP (timeout)) { - CHECK_NUMBER (timeout, 1); + CHECK_NUMBER (timeout); seconds = XINT (timeout); if (seconds < 0 || (seconds == 0 && useconds == 0)) seconds = -1; @@ -2354,7 +2365,9 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) int wait_channel = -1; struct Lisp_Process *wait_proc = 0; int got_some_input = 0; - Lisp_Object *wait_for_cell = 0; + /* Either nil or a cons cell, the car of which is of interest and + may be changed outside of this routine. */ + Lisp_Object wait_for_cell = Qnil; FD_ZERO (&Available); @@ -2370,7 +2383,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) /* If waiting for non-nil in a cell, record where. */ if (CONSP (read_kbd)) { - wait_for_cell = &XCAR (read_kbd); + wait_for_cell = read_kbd; XSETFASTINT (read_kbd, 0); } @@ -2404,7 +2417,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) QUIT; /* Exit now if the cell we're waiting for became non-nil. */ - if (wait_for_cell && ! NILP (*wait_for_cell)) + if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) break; /* Compute time from now till when time limit is up */ @@ -2433,21 +2446,32 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) But not if wait_for_cell; in those cases, the wait is supposed to be short, and those callers cannot handle running arbitrary Lisp code here. */ - if (! wait_for_cell) + if (NILP (wait_for_cell)) { EMACS_TIME timer_delay; - int old_timers_run; - retry: - old_timers_run = timers_run; - timer_delay = timer_check (1); - if (timers_run != old_timers_run && do_display) + do { - redisplay_preserve_echo_area (); - /* We must retry, since a timer may have requeued itself - and that could alter the time_delay. */ - goto retry; + int old_timers_run = timers_run; + struct buffer *old_buffer = current_buffer; + + timer_delay = timer_check (1); + + /* If a timer has run, this might have changed buffers + an alike. Make read_key_sequence aware of that. */ + if (timers_run != old_timers_run + && old_buffer != current_buffer + && waiting_for_user_input_p == -1) + record_asynch_buffer_change (); + + if (timers_run != old_timers_run && do_display) + /* We must retry, since a timer may have requeued itself + and that could alter the time_delay. */ + redisplay_preserve_echo_area (9); + else + break; } + while (!detect_input_pending ()); /* If there is unread keyboard input, also return. */ if (XINT (read_kbd) != 0 @@ -2536,14 +2560,14 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) #endif } if (total_nread > 0 && do_display) - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (10); break; } /* Wait till there is something to do */ - if (wait_for_cell) + if (!NILP (wait_for_cell)) Available = non_process_wait_mask; else if (! XINT (read_kbd)) Available = non_keyboard_wait_mask; @@ -2558,7 +2582,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) if (frame_garbaged && do_display) { clear_waiting_for_input (); - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (11); if (XINT (read_kbd) < 0) set_waiting_for_input (&timeout); } @@ -2653,14 +2677,30 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) /* If there is any, return immediately to give it higher priority than subprocesses */ - if (XINT (read_kbd) != 0 - && detect_input_pending_run_timers (do_display)) + if (XINT (read_kbd) != 0) { - swallow_events (do_display); + int old_timers_run = timers_run; + struct buffer *old_buffer = current_buffer; + int leave = 0; + if (detect_input_pending_run_timers (do_display)) - break; - } + { + swallow_events (do_display); + if (detect_input_pending_run_timers (do_display)) + leave = 1; + } + + /* If a timer has run, this might have changed buffers + an alike. Make read_key_sequence aware of that. */ + if (timers_run != old_timers_run + && waiting_for_user_input_p == -1 + && old_buffer != current_buffer) + record_asynch_buffer_change (); + if (leave) + break; + } + /* If there is unread keyboard input, also return. */ if (XINT (read_kbd) != 0 && requeued_events_pending_p ()) @@ -2683,7 +2723,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) } /* Exit now if the cell we're waiting for became non-nil. */ - if (wait_for_cell && ! NILP (*wait_for_cell)) + if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) break; #ifdef SIGIO @@ -2702,7 +2742,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) /* If checking input just got us a size-change event from X, obey it now if we should. */ - if (XINT (read_kbd) || wait_for_cell) + if (XINT (read_kbd) || ! NILP (wait_for_cell)) do_pending_window_change (0); /* Check for data from a process. */ @@ -2741,7 +2781,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) FD_ZERO (&Available); if (do_display) - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (12); } #ifdef EWOULDBLOCK else if (nread == -1 && errno == EWOULDBLOCK) @@ -3119,8 +3159,6 @@ read_process_output (proc, channel) /* Insert before markers in case we are inserting where the buffer's mark is, and the user's next command is Meta-y. */ insert_from_string_before_markers (text, 0, 0, nchars, nbytes, 0); - signal_after_change (before, 0, PT - before); - update_compositions (before, PT, CHECK_BORDER); /* Make sure the process marker's position is valid when the process buffer is changed in the signal_after_change above. @@ -3170,9 +3208,9 @@ read_process_output (proc, channel) DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p, 0, 0, 0, - "Returns non-nil if emacs is waiting for input from the user.\n\ -This is intended for use by asynchronous process output filters and sentinels.") - () + doc: /* Returns non-nil if emacs is waiting for input from the user. +This is intended for use by asynchronous process output filters and sentinels. */) + () { return (waiting_for_user_input_p ? Qt : Qnil); } @@ -3238,15 +3276,17 @@ send_process (proc, buf, len, object) && !NILP (XBUFFER (object)->enable_multibyte_characters)) || EQ (object, Qt)) { - coding->src_multibyte = 1; if (!EQ (coding->symbol, XPROCESS (proc)->encode_coding_system)) /* The coding system for encoding was changed to raw-text because we sent a unibyte text previously. Now we are sending a multibyte text, thus we must encode it by the original coding system specified for the current process. */ - setup_coding_system (XPROCESS (proc)->encode_coding_system, - coding); + setup_coding_system (XPROCESS (proc)->encode_coding_system, coding); + /* src_multibyte should be set to 1 _after_ a call to + setup_coding_system, since it resets src_multibyte to + zero. */ + coding->src_multibyte = 1; } else { @@ -3286,8 +3326,13 @@ send_process (proc, buf, len, object) to = string_byte_to_char (object, from_byte + len); } - if (from_byte >= 0 && coding->composing != COMPOSITION_DISABLED) - coding_save_composition (coding, from, to, object); + if (coding->composing != COMPOSITION_DISABLED) + { + if (from_byte >= 0) + coding_save_composition (coding, from, to, object); + else + coding->composing = COMPOSITION_DISABLED; + } if (STRING_BYTES (XSTRING (XPROCESS (proc)->encoding_buf)) < require) XPROCESS (proc)->encoding_buf = make_uninit_string (require); @@ -3343,8 +3388,8 @@ send_process (proc, buf, len, object) Long lines need to be split into multiple batches. */ if (!NILP (XPROCESS (proc)->pty_flag)) { - /* Starting this at zero is always correct when not the first iteration - because the previous iteration ended by sending C-d. + /* Starting this at zero is always correct when not the first + iteration because the previous iteration ended by sending C-d. It may not be correct for the first iteration if a partial line was sent in a separate send_process call. If that proves worth handling, we need to save linepos @@ -3478,15 +3523,15 @@ send_process (proc, buf, len, object) } DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region, - 3, 3, 0, - "Send current contents of region as input to PROCESS.\n\ -PROCESS may be a process, a buffer, the name of a process or buffer, or\n\ -nil, indicating the current buffer's process.\n\ -Called from program, takes three arguments, PROCESS, START and END.\n\ -If the region is more than 500 characters long,\n\ -it is sent in several bunches. This may happen even for shorter regions.\n\ -Output from processes can arrive in between bunches.") - (process, start, end) + 3, 3, 0, + doc: /* Send current contents of region as input to PROCESS. +PROCESS may be a process, a buffer, the name of a process or buffer, or +nil, indicating the current buffer's process. +Called from program, takes three arguments, PROCESS, START and END. +If the region is more than 500 characters long, +it is sent in several bunches. This may happen even for shorter regions. +Output from processes can arrive in between bunches. */) + (process, start, end) Lisp_Object process, start, end; { Lisp_Object proc; @@ -3507,18 +3552,18 @@ Output from processes can arrive in between bunches.") } DEFUN ("process-send-string", Fprocess_send_string, Sprocess_send_string, - 2, 2, 0, - "Send PROCESS the contents of STRING as input.\n\ -PROCESS may be a process, a buffer, the name of a process or buffer, or\n\ -nil, indicating the current buffer's process.\n\ -If STRING is more than 500 characters long,\n\ -it is sent in several bunches. This may happen even for shorter strings.\n\ -Output from processes can arrive in between bunches.") - (process, string) + 2, 2, 0, + doc: /* Send PROCESS the contents of STRING as input. +PROCESS may be a process, a buffer, the name of a process or buffer, or +nil, indicating the current buffer's process. +If STRING is more than 500 characters long, +it is sent in several bunches. This may happen even for shorter strings. +Output from processes can arrive in between bunches. */) + (process, string) Lisp_Object process, string; { Lisp_Object proc; - CHECK_STRING (string, 1); + CHECK_STRING (string); proc = get_process (process); send_process (proc, XSTRING (string)->data, STRING_BYTES (XSTRING (string)), string); @@ -3527,10 +3572,10 @@ Output from processes can arrive in between bunches.") DEFUN ("process-running-child-p", Fprocess_running_child_p, Sprocess_running_child_p, 0, 1, 0, - "Return t if PROCESS has given the terminal to a child.\n\ -If the operating system does not make it possible to find out,\n\ -return t unconditionally.") - (process) + doc: /* Return t if PROCESS has given the terminal to a child. +If the operating system does not make it possible to find out, +return t unconditionally. */) + (process) Lisp_Object process; { /* Initialize in case ioctl doesn't exist or gives an error, @@ -3787,18 +3832,18 @@ process_send_signal (process, signo, current_group, nomsg) } DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0, - "Interrupt process PROCESS.\n\ -PROCESS may be a process, a buffer, or the name of a process or buffer.\n\ -nil or no arg means current buffer's process.\n\ -Second arg CURRENT-GROUP non-nil means send signal to\n\ -the current process-group of the process's controlling terminal\n\ -rather than to the process's own process group.\n\ -If the process is a shell, this means interrupt current subjob\n\ -rather than the shell.\n\ -\n\ -If CURRENT-GROUP is `lambda', and if the shell owns the terminal,\n\ -don't send the signal.") - (process, current_group) + doc: /* Interrupt process PROCESS. +PROCESS may be a process, a buffer, or the name of a process or buffer. +nil or no arg means current buffer's process. +Second arg CURRENT-GROUP non-nil means send signal to +the current process-group of the process's controlling terminal +rather than to the process's own process group. +If the process is a shell, this means interrupt current subjob +rather than the shell. + +If CURRENT-GROUP is `lambda', and if the shell owns the terminal, +don't send the signal. */) + (process, current_group) Lisp_Object process, current_group; { process_send_signal (process, SIGINT, current_group, 0); @@ -3806,9 +3851,9 @@ don't send the signal.") } DEFUN ("kill-process", Fkill_process, Skill_process, 0, 2, 0, - "Kill process PROCESS. May be process or name of one.\n\ -See function `interrupt-process' for more details on usage.") - (process, current_group) + doc: /* Kill process PROCESS. May be process or name of one. +See function `interrupt-process' for more details on usage. */) + (process, current_group) Lisp_Object process, current_group; { process_send_signal (process, SIGKILL, current_group, 0); @@ -3816,9 +3861,9 @@ See function `interrupt-process' for more details on usage.") } DEFUN ("quit-process", Fquit_process, Squit_process, 0, 2, 0, - "Send QUIT signal to process PROCESS. May be process or name of one.\n\ -See function `interrupt-process' for more details on usage.") - (process, current_group) + doc: /* Send QUIT signal to process PROCESS. May be process or name of one. +See function `interrupt-process' for more details on usage. */) + (process, current_group) Lisp_Object process, current_group; { process_send_signal (process, SIGQUIT, current_group, 0); @@ -3826,9 +3871,9 @@ See function `interrupt-process' for more details on usage.") } DEFUN ("stop-process", Fstop_process, Sstop_process, 0, 2, 0, - "Stop process PROCESS. May be process or name of one.\n\ -See function `interrupt-process' for more details on usage.") - (process, current_group) + doc: /* Stop process PROCESS. May be process or name of one. +See function `interrupt-process' for more details on usage. */) + (process, current_group) Lisp_Object process, current_group; { #ifndef SIGTSTP @@ -3840,9 +3885,9 @@ See function `interrupt-process' for more details on usage.") } DEFUN ("continue-process", Fcontinue_process, Scontinue_process, 0, 2, 0, - "Continue process PROCESS. May be process or name of one.\n\ -See function `interrupt-process' for more details on usage.") - (process, current_group) + doc: /* Continue process PROCESS. May be process or name of one. +See function `interrupt-process' for more details on usage. */) + (process, current_group) Lisp_Object process, current_group; { #ifdef SIGCONT @@ -3854,14 +3899,14 @@ See function `interrupt-process' for more details on usage.") } DEFUN ("signal-process", Fsignal_process, Ssignal_process, - 2, 2, "nProcess number: \nnSignal code: ", - "Send the process with process id PID the signal with code SIGCODE.\n\ -PID must be an integer. The process need not be a child of this Emacs.\n\ -SIGCODE may be an integer, or a symbol whose name is a signal name.") - (pid, sigcode) + 2, 2, "nProcess number: \nnSignal code: ", + doc: /* Send the process with process id PID the signal with code SIGCODE. +PID must be an integer. The process need not be a child of this Emacs. +SIGCODE may be an integer, or a symbol whose name is a signal name. */) + (pid, sigcode) Lisp_Object pid, sigcode; { - CHECK_NUMBER (pid, 0); + CHECK_NUMBER (pid); #define handle_signal(NAME, VALUE) \ else if (!strcmp (name, NAME)) \ @@ -3873,7 +3918,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.") { unsigned char *name; - CHECK_SYMBOL (sigcode, 1); + CHECK_SYMBOL (sigcode); name = XSYMBOL (sigcode)->name->data; if (0) @@ -3978,14 +4023,14 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.") } DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0, - "Make PROCESS see end-of-file in its input.\n\ -EOF comes after any text already sent to it.\n\ -PROCESS may be a process, a buffer, the name of a process or buffer, or\n\ -nil, indicating the current buffer's process.\n\ -If PROCESS is a network connection, or is a process communicating\n\ -through a pipe (as opposed to a pty), then you cannot send any more\n\ -text to PROCESS after you call this function.") - (process) + doc: /* Make PROCESS see end-of-file in its input. +EOF comes after any text already sent to it. +PROCESS may be a process, a buffer, the name of a process or buffer, or +nil, indicating the current buffer's process. +If PROCESS is a network connection, or is a process communicating +through a pipe (as opposed to a pty), then you cannot send any more +text to PROCESS after you call this function. */) + (process) Lisp_Object process; { Lisp_Object proc; @@ -4048,7 +4093,7 @@ text to PROCESS after you call this function.") } /* Kill all processes associated with `buffer'. - If `buffer' is nil, kill all processes */ + If `buffer' is nil, kill all processes */ void kill_buffer_processes (buffer) @@ -4070,26 +4115,27 @@ kill_buffer_processes (buffer) } } -/* On receipt of a signal that a child status has changed, - loop asking about children with changed statuses until - the system says there are no more. - All we do is change the status; - we do not run sentinels or print notifications. - That is saved for the next time keyboard input is done, - in order to avoid timing errors. */ - -/** WARNING: this can be called during garbage collection. - Therefore, it must not be fooled by the presence of mark bits in - Lisp objects. */ - -/** USG WARNING: Although it is not obvious from the documentation - in signal(2), on a USG system the SIGCLD handler MUST NOT call - signal() before executing at least one wait(), otherwise the handler - will be called again, resulting in an infinite loop. The relevant - portion of the documentation reads "SIGCLD signals will be queued - and the signal-catching function will be continually reentered until - the queue is empty". Invoking signal() causes the kernel to reexamine - the SIGCLD queue. Fred Fish, UniSoft Systems Inc. */ +/* On receipt of a signal that a child status has changed, loop asking + about children with changed statuses until the system says there + are no more. + + All we do is change the status; we do not run sentinels or print + notifications. That is saved for the next time keyboard input is + done, in order to avoid timing errors. + + ** WARNING: this can be called during garbage collection. + Therefore, it must not be fooled by the presence of mark bits in + Lisp objects. + + ** USG WARNING: Although it is not obvious from the documentation + in signal(2), on a USG system the SIGCLD handler MUST NOT call + signal() before executing at least one wait(), otherwise the + handler will be called again, resulting in an infinite loop. The + relevant portion of the documentation reads "SIGCLD signals will be + queued and the signal-catching function will be continually + reentered until the queue is empty". Invoking signal() causes the + kernel to reexamine the SIGCLD queue. Fred Fish, UniSoft Systems + Inc. */ SIGTYPE sigchld_handler (signo) @@ -4121,11 +4167,12 @@ sigchld_handler (signo) errno = 0; pid = wait3 (&w, WNOHANG | WUNTRACED, 0); } - while (pid <= 0 && errno == EINTR); + while (pid < 0 && errno == EINTR); if (pid <= 0) { - /* A real failure. We have done all our job, so return. */ + /* PID == 0 means no processes found, PID == -1 means a real + failure. We have done all our job, so return. */ /* USG systems forget handlers when they are used; must reestablish each time */ @@ -4146,11 +4193,11 @@ sigchld_handler (signo) /* Find the process that signaled us, and record its status. */ p = 0; - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) { proc = XCDR (XCAR (tail)); p = XPROCESS (proc); - if (EQ (p->childp, Qt) && XFASTINT (p->pid) == pid) + if (GC_EQ (p->childp, Qt) && XINT (p->pid) == pid) break; p = 0; } @@ -4158,11 +4205,11 @@ sigchld_handler (signo) /* Look for an asynchronous process whose pid hasn't been filled in yet. */ if (p == 0) - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) { proc = XCDR (XCAR (tail)); p = XPROCESS (proc); - if (INTEGERP (p->pid) && XINT (p->pid) == -1) + if (GC_INTEGERP (p->pid) && XINT (p->pid) == -1) break; p = 0; } @@ -4230,7 +4277,9 @@ sigchld_handler (signo) get another signal. Otherwise (on systems that have WNOHANG), loop around to use up all the processes that have something to tell us. */ -#if defined (USG) && ! (defined (HPUX) && defined (WNOHANG)) || defined (WINDOWSNT) +#if (defined WINDOWSNT \ + || (defined USG && !defined GNU_LINUX \ + && !(defined HPUX && defined WNOHANG))) #if defined (USG) && ! defined (POSIX_SIGNALS) signal (signo, sigchld_handler); #endif @@ -4453,7 +4502,7 @@ status_notify () } /* end for */ update_mode_lines++; /* in case buffers use %s in mode-line-format */ - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (13); UNGCPRO; } @@ -4461,15 +4510,15 @@ status_notify () DEFUN ("set-process-coding-system", Fset_process_coding_system, Sset_process_coding_system, 1, 3, 0, - "Set coding systems of PROCESS to DECODING and ENCODING.\n\ -DECODING will be used to decode subprocess output and ENCODING to\n\ -encode subprocess input.") - (proc, decoding, encoding) + doc: /* Set coding systems of PROCESS to DECODING and ENCODING. +DECODING will be used to decode subprocess output and ENCODING to +encode subprocess input. */) + (proc, decoding, encoding) register Lisp_Object proc, decoding, encoding; { register struct Lisp_Process *p; - CHECK_PROCESS (proc, 0); + CHECK_PROCESS (proc); p = XPROCESS (proc); if (XINT (p->infd) < 0) error ("Input file descriptor of %s closed", XSTRING (p->name)->data); @@ -4488,11 +4537,11 @@ encode subprocess input.") DEFUN ("process-coding-system", Fprocess_coding_system, Sprocess_coding_system, 1, 1, 0, - "Return a cons of coding systems for decoding and encoding of PROCESS.") - (proc) + doc: /* Return a cons of coding systems for decoding and encoding of PROCESS. */) + (proc) register Lisp_Object proc; { - CHECK_PROCESS (proc, 0); + CHECK_PROCESS (proc); return Fcons (XPROCESS (proc)->decode_coding_system, XPROCESS (proc)->encode_coding_system); } @@ -4611,17 +4660,17 @@ syms_of_process () staticpro (&Vprocess_alist); DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes, - "*Non-nil means delete processes immediately when they exit.\n\ -nil means don't delete them until `list-processes' is run."); + doc: /* *Non-nil means delete processes immediately when they exit. +nil means don't delete them until `list-processes' is run. */); delete_exited_processes = 1; DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type, - "Control type of device used to communicate with subprocesses.\n\ -Values are nil to use a pipe, or t or `pty' to use a pty.\n\ -The value has no effect if the system has no ptys or if all ptys are busy:\n\ -then a pipe is used in any case.\n\ -The value takes effect when `start-process' is called."); + doc: /* Control type of device used to communicate with subprocesses. +Values are nil to use a pipe, or t or `pty' to use a pty. +The value has no effect if the system has no ptys or if all ptys are busy: +then a pipe is used in any case. +The value takes effect when `start-process' is called. */); Vprocess_connection_type = Qt; defsubr (&Sprocessp); @@ -4721,12 +4770,14 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) EMACS_TIME end_time, timeout; SELECT_TYPE waitchannels; int xerrno; - Lisp_Object *wait_for_cell = 0; + /* Either nil or a cons cell, the car of which is of interest and + may be changed outside of this routine. */ + Lisp_Object wait_for_cell = Qnil; /* If waiting for non-nil in a cell, record where. */ if (CONSP (read_kbd)) { - wait_for_cell = &XCAR (read_kbd); + wait_for_cell = read_kbd; XSETFASTINT (read_kbd, 0); } @@ -4753,7 +4804,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) QUIT; /* Exit now if the cell we're waiting for became non-nil. */ - if (wait_for_cell && ! NILP (*wait_for_cell)) + if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) break; /* Compute time from now till when time limit is up */ @@ -4782,21 +4833,22 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) run timer events directly. (Callers that will immediately read keyboard events call timer_delay on their own.) */ - if (! wait_for_cell) + if (NILP (wait_for_cell)) { EMACS_TIME timer_delay; - int old_timers_run; - retry: - old_timers_run = timers_run; - timer_delay = timer_check (1); - if (timers_run != old_timers_run && do_display) + do { - redisplay_preserve_echo_area (); - /* We must retry, since a timer may have requeued itself - and that could alter the time delay. */ - goto retry; + int old_timers_run = timers_run; + timer_delay = timer_check (1); + if (timers_run != old_timers_run && do_display) + /* We must retry, since a timer may have requeued itself + and that could alter the time delay. */ + redisplay_preserve_echo_area (14); + else + break; } + while (!detect_input_pending ()); /* If there is unread keyboard input, also return. */ if (XINT (read_kbd) != 0 @@ -4822,7 +4874,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) /* Wait till there is something to do. */ - if (! XINT (read_kbd) && wait_for_cell == 0) + if (! XINT (read_kbd) && NILP (wait_for_cell)) FD_ZERO (&waitchannels); else FD_SET (0, &waitchannels); @@ -4832,7 +4884,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) if (frame_garbaged && do_display) { clear_waiting_for_input (); - redisplay_preserve_echo_area (); + redisplay_preserve_echo_area (15); if (XINT (read_kbd) < 0) set_waiting_for_input (&timeout); } @@ -4898,7 +4950,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) input at all when wait_for_cell, but the code has been this way since July 1994. Try changing this after version 19.31.) */ - if (wait_for_cell + if (! NILP (wait_for_cell) && detect_input_pending ()) { swallow_events (do_display); @@ -4907,7 +4959,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) } /* Exit now if the cell we're waiting for became non-nil. */ - if (wait_for_cell && ! NILP (*wait_for_cell)) + if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell))) break; } @@ -4917,23 +4969,23 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display) } +/* Don't confuse make-docfile by having two doc strings for this function. + make-docfile does not pay attention to #if, for good reason! */ DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0, - /* Don't confuse make-docfile by having two doc strings for this function. - make-docfile does not pay attention to #if, for good reason! */ - 0) - (name) + 0) + (name) register Lisp_Object name; { return Qnil; } -DEFUN ("process-inherit-coding-system-flag", - Fprocess_inherit_coding_system_flag, Sprocess_inherit_coding_system_flag, - 1, 1, 0, /* Don't confuse make-docfile by having two doc strings for this function. make-docfile does not pay attention to #if, for good reason! */ - 0) - (process) +DEFUN ("process-inherit-coding-system-flag", + Fprocess_inherit_coding_system_flag, Sprocess_inherit_coding_system_flag, + 1, 1, 0, + 0) + (process) register Lisp_Object process; { /* Ignore the argument and return the value of