/* Asynchronous subprocess control for GNU Emacs.
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 98, 1999,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
+ 1996, 1998, 1999, 2001, 2002, 2003, 2004,
+ 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
#include <sys/wait.h>
#endif
+#include "lisp.h"
#include "systime.h"
#include "systty.h"
-#include "lisp.h"
#include "window.h"
#include "buffer.h"
#include "charset.h"
#include "syswait.h"
-extern void set_waiting_for_input P_ ((EMACS_TIME *));
+extern char *get_operating_system_release ();
#ifndef USE_CRT_DLL
extern int errno;
#define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5)
#define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7)
-/* Number of processes which might be delayed. */
+/* Number of processes which have a non-zero read_output_delay,
+ and therefore might be delayed for adaptive read buffering. */
static int process_output_delay_count;
-/* Non-zero if any process has non-nil process_output_skip. */
+/* Non-zero if any process has non-nil read_output_skip. */
static int process_output_skip;
/* Non-nil means to delay reading process output to improve buffering.
A value of t means that delay is reset after each send, any other
- non-nil value does not reset the delay. */
+ non-nil value does not reset the delay. A value of nil disables
+ adaptive read buffering completely. */
static Lisp_Object Vprocess_adaptive_read_buffering;
#else
#define process_output_delay_count 0
#include "sysselect.h"
-extern int keyboard_bit_set P_ ((SELECT_TYPE *));
+static int keyboard_bit_set P_ ((SELECT_TYPE *));
+static void deactivate_process P_ ((Lisp_Object));
+static void status_notify P_ ((struct Lisp_Process *));
+static int read_process_output P_ ((Lisp_Object, int));
/* If we support a window system, turn on the code to poll periodically
to detect C-g. It isn't actually used when doing interrupt input. */
static SELECT_TYPE non_process_wait_mask;
+#ifdef NON_BLOCKING_CONNECT
/* Mask of bits indicating the descriptors that we wait for connect to
complete on. Once they complete, they are removed from this mask
and added to the input_wait_mask and non_keyboard_wait_mask. */
/* Number of bits set in connect_wait_mask. */
static int num_pending_connects;
+#define IF_NON_BLOCKING_CONNECT(s) s
+#else
+#define IF_NON_BLOCKING_CONNECT(s)
+#endif
+
/* The largest descriptor currently in use for a process object. */
static int max_process_desc;
/* Maximum number of bytes to send to a pty without an eof. */
static int pty_max_bytes;
-extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
-
#ifdef HAVE_PTYS
#ifdef HAVE_PTY_H
#include <pty.h>
/* Compute the Lisp form of the process status, p->status, from
the numeric status that was returned by `wait'. */
-Lisp_Object status_convert ();
+static Lisp_Object status_convert ();
-void
+static void
update_status (p)
struct Lisp_Process *p;
{
/* Convert a process status word in Unix format to
the list that we use internally. */
-Lisp_Object
+static Lisp_Object
status_convert (w)
WAITTYPE w;
{
/* Given a status-list, extract the three pieces of information
and store them individually through the three pointers. */
-void
+static void
decode_status (l, symbol, code, coredump)
Lisp_Object l;
Lisp_Object *symbol;
The file name of the terminal corresponding to the pty
is left in the variable pty_name. */
-int
+static int
allocate_pty ()
{
register int c, i;
}
#endif /* HAVE_PTYS */
\f
-Lisp_Object
+static Lisp_Object
make_process (name)
Lisp_Object name;
{
return val;
}
-void
+static void
remove_process (proc)
register Lisp_Object proc;
{
(process)
register Lisp_Object process;
{
+ register struct Lisp_Process *p;
+
process = get_process (process);
- XPROCESS (process)->raw_status_low = Qnil;
- XPROCESS (process)->raw_status_high = Qnil;
- if (NETCONN_P (process))
+ p = XPROCESS (process);
+
+ p->raw_status_low = Qnil;
+ p->raw_status_high = Qnil;
+ if (NETCONN1_P (p))
{
- XPROCESS (process)->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
- XSETINT (XPROCESS (process)->tick, ++process_tick);
- status_notify ();
+ p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
+ XSETINT (p->tick, ++process_tick);
+ status_notify (p);
}
- else if (XINT (XPROCESS (process)->infd) >= 0)
+ else if (XINT (p->infd) >= 0)
{
Fkill_process (process, Qnil);
/* Do this now, since remove_process will make sigchld_handler do nothing. */
- XPROCESS (process)->status
+ p->status
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
- XSETINT (XPROCESS (process)->tick, ++process_tick);
- status_notify ();
+ XSETINT (p->tick, ++process_tick);
+ status_notify (p);
}
remove_process (process);
return Qnil;
}
#endif
\f
-Lisp_Object
+static Lisp_Object
list_processes_1 (query_only)
Lisp_Object query_only;
{
XSETFASTINT (minspace, 1);
set_buffer_internal (XBUFFER (Vstandard_output));
- Fbuffer_disable_undo (Vstandard_output);
+ current_buffer->undo_list = Qt;
current_buffer->truncate_lines = Qt;
XPROCESS (proc)->childp = Qt;
XPROCESS (proc)->plist = Qnil;
- XPROCESS (proc)->command_channel_p = Qnil;
XPROCESS (proc)->buffer = buffer;
XPROCESS (proc)->sentinel = Qnil;
XPROCESS (proc)->filter = Qnil;
return Qnil;
}
-void
+static void
create_process_1 (timer)
struct atimer *timer;
{
#endif
if (forkin < 0)
report_file_error ("Opening pty", Qnil);
+#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
+ /* In the case that vfork is defined as fork, the parent process
+ (Emacs) may send some data before the child process completes
+ tty options setup. So we setup tty before forking. */
+ child_setup_tty (forkout);
+#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
#else
forkin = forkout = -1;
#endif /* not USG, or USG_SUBTTY_WORKS */
#endif /* SIGCHLD */
#endif /* !POSIX_SIGNALS */
+#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
if (pty_flag)
child_setup_tty (xforkout);
+#endif /* not RTU and not UNIPLUS and not DONT_REOPEN_PTY */
#ifdef WINDOWSNT
pid = child_setup (xforkin, xforkout, xforkout,
new_argv, 1, current_dir);
\f
/* A version of request_sigio suitable for a record_unwind_protect. */
-Lisp_Object
+static Lisp_Object
unwind_request_sigio (dummy)
Lisp_Object dummy;
{
In Emacs, network connections are represented by process objects, so
input and output work as for subprocesses and `delete-process' closes
a network connection. However, a network process has no process id,
-it cannot be signalled, and the status codes are different from normal
+it cannot be signaled, and the status codes are different from normal
processes.
Arguments are specified as keyword/argument pairs. The following
int xerrno = 0;
int s = -1, outch, inch;
struct gcpro gcpro1;
- int retry = 0;
int count = SPECPDL_INDEX ();
int count1;
Lisp_Object QCaddress; /* one of QClocal or QCremote */
{
int optn, optbits;
+ retry_connect:
+
s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
if (s < 0)
{
break;
}
- retry_connect:
-
immediate_quit = 1;
QUIT;
immediate_quit = 0;
- if (xerrno == EINTR)
- goto retry_connect;
- if (xerrno == EADDRINUSE && retry < 20)
- {
- /* A delay here is needed on some FreeBSD systems,
- and it is harmless, since this retrying takes time anyway
- and should be infrequent. */
- Fsleep_for (make_number (1), Qnil);
- retry++;
- goto retry_connect;
- }
-
/* Discard the unwind protect closing S. */
specpdl_ptr = specpdl + count1;
emacs_close (s);
s = -1;
+
+ if (xerrno == EINTR)
+ goto retry_connect;
}
if (s >= 0)
chan_process[inchannel] = Qnil;
FD_CLR (inchannel, &input_wait_mask);
FD_CLR (inchannel, &non_keyboard_wait_mask);
+#ifdef NON_BLOCKING_CONNECT
if (FD_ISSET (inchannel, &connect_wait_mask))
{
FD_CLR (inchannel, &connect_wait_mask);
if (--num_pending_connects < 0)
abort ();
}
+#endif
if (inchannel == max_process_desc)
{
int i;
}
\f
DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
- 0, 3, 0,
+ 0, 4, 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
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.
+If optional fourth arg JUST-THIS-ONE is non-nil, only accept output
+from PROCESS, suspending reading output from other processes.
+If JUST-THIS-ONE is an integer, don't run any timers either.
Return non-nil iff we received any output before the timeout expired. */)
- (process, timeout, timeout_msecs)
- register Lisp_Object process, timeout, timeout_msecs;
+ (process, timeout, timeout_msecs, just_this_one)
+ register Lisp_Object process, timeout, timeout_msecs, just_this_one;
{
int seconds;
int useconds;
if (! NILP (process))
CHECK_PROCESS (process);
+ else
+ just_this_one = Qnil;
if (! NILP (timeout_msecs))
{
else
seconds = NILP (process) ? -1 : 0;
- if (NILP (process))
- XSETFASTINT (process, 0);
-
return
- (wait_reading_process_input (seconds, useconds, process, 0)
+ (wait_reading_process_output (seconds, useconds, 0, 0,
+ Qnil,
+ !NILP (process) ? XPROCESS (process) : NULL,
+ NILP (just_this_one) ? 0 :
+ !INTEGERP (just_this_one) ? 1 : -1)
? Qt : Qnil);
}
lisp code is being evalled.
This is also used in record_asynch_buffer_change.
For that purpose, this must be 0
- when not inside wait_reading_process_input. */
+ when not inside wait_reading_process_output. */
static int waiting_for_user_input_p;
/* This is here so breakpoints can be put on it. */
static void
-wait_reading_process_input_1 ()
+wait_reading_process_output_1 ()
{
}
1 to return when input is available, or
-1 meaning caller will actually read the input, so don't throw to
the quit handler, or
- a cons cell, meaning wait until its car is non-nil
- (and gobble terminal input into the buffer if any arrives), or
- a process object, meaning wait until something arrives from that
- process. The return value is true iff we read some input from
- that process.
DO_DISPLAY != 0 means redisplay should be done to show subprocess
- output that arrives.
+ output that arrives.
+
+ If WAIT_FOR_CELL is a cons cell, wait until its car is non-nil
+ (and gobble terminal input into the buffer if any arrives).
+
+ If WAIT_PROC is specified, wait until something arrives from that
+ process. The return value is true iff we read some input from
+ that process.
- If READ_KBD is a pointer to a struct Lisp_Process, then the
- function returns true iff we received input from that process
- before the timeout elapsed.
+ If JUST_WAIT_PROC is non-nil, handle only output from WAIT_PROC
+ (suspending output from other processes). A negative value
+ means don't run any timers either.
+
+ If WAIT_PROC is specified, then the function returns true iff we
+ received input from that process before the timeout elapsed.
Otherwise, return true iff we received input from any process. */
int
-wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
- int time_limit, microsecs;
- Lisp_Object read_kbd;
- int do_display;
+wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
+ wait_for_cell, wait_proc, just_wait_proc)
+ int time_limit, microsecs, read_kbd, do_display;
+ Lisp_Object wait_for_cell;
+ struct Lisp_Process *wait_proc;
+ int just_wait_proc;
{
register int channel, nfds;
SELECT_TYPE Available;
+#ifdef NON_BLOCKING_CONNECT
SELECT_TYPE Connecting;
- int check_connect, check_delay, no_avail;
+ int check_connect;
+#endif
+ int check_delay, no_avail;
int xerrno;
Lisp_Object proc;
EMACS_TIME timeout, end_time;
int wait_channel = -1;
- struct Lisp_Process *wait_proc = 0;
int got_some_input = 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;
int saved_waiting_for_user_input_p = waiting_for_user_input_p;
FD_ZERO (&Available);
+#ifdef NON_BLOCKING_CONNECT
FD_ZERO (&Connecting);
+#endif
- /* If read_kbd is a process to watch, set wait_proc and wait_channel
- accordingly. */
- if (PROCESSP (read_kbd))
- {
- wait_proc = XPROCESS (read_kbd);
- wait_channel = XINT (wait_proc->infd);
- XSETFASTINT (read_kbd, 0);
- }
-
- /* If waiting for non-nil in a cell, record where. */
- if (CONSP (read_kbd))
- {
- wait_for_cell = read_kbd;
- XSETFASTINT (read_kbd, 0);
- }
+ /* If wait_proc is a process to watch, set wait_channel accordingly. */
+ if (wait_proc != NULL)
+ wait_channel = XINT (wait_proc->infd);
- waiting_for_user_input_p = XINT (read_kbd);
+ waiting_for_user_input_p = read_kbd;
/* Since we may need to wait several times,
compute the absolute time to return at. */
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
- if (XINT (read_kbd) >= 0)
+ if (read_kbd >= 0)
QUIT;
#ifdef SYNC_INPUT
else if (interrupt_input_pending)
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 (NILP (wait_for_cell))
+ if (NILP (wait_for_cell)
+ && just_wait_proc >= 0)
{
EMACS_TIME timer_delay;
while (!detect_input_pending ());
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd != 0
&& requeued_events_pending_p ())
break;
else if (time_limit != -1)
{
/* This is so a breakpoint can be put here. */
- wait_reading_process_input_1 ();
+ wait_reading_process_output_1 ();
}
}
It is important that we do this before checking for process
activity. If we get a SIGCHLD after the explicit checks for
process activity, timeout is the only way we will know. */
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
/* If status of something has changed, and no input is
timeout to get our attention. */
if (update_tick != process_tick && do_display)
{
- SELECT_TYPE Atemp, Ctemp;
+ SELECT_TYPE Atemp;
+#ifdef NON_BLOCKING_CONNECT
+ SELECT_TYPE Ctemp;
+#endif
Atemp = input_wait_mask;
-#ifdef MAC_OSX
- /* On Mac OS X, the SELECT system call always says input is
+#if 0
+ /* On Mac OS X 10.0, the SELECT system call always says input is
present (for reading) at stdin, even when none is. This
causes the call to SELECT below to return 1 and
status_notify not to be called. As a result output of
- subprocesses are incorrectly discarded. */
+ subprocesses are incorrectly discarded.
+ */
FD_CLR (0, &Atemp);
#endif
- Ctemp = connect_wait_mask;
+ IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
+
EMACS_SET_SECS_USECS (timeout, 0, 0);
if ((select (max (max_process_desc, max_keyboard_desc) + 1,
&Atemp,
+#ifdef NON_BLOCKING_CONNECT
(num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
+#else
+ (SELECT_TYPE *)0,
+#endif
(SELECT_TYPE *)0, &timeout)
<= 0))
{
/* It's okay for us to do this and then continue with
the loop, since timeout has already been zeroed out. */
clear_waiting_for_input ();
- status_notify ();
+ status_notify (NULL);
}
}
/* Wait till there is something to do */
- if (!NILP (wait_for_cell))
+ if (wait_proc && just_wait_proc)
+ {
+ if (XINT (wait_proc->infd) < 0) /* Terminated */
+ break;
+ FD_SET (XINT (wait_proc->infd), &Available);
+ check_delay = 0;
+ IF_NON_BLOCKING_CONNECT (check_connect = 0);
+ }
+ else if (!NILP (wait_for_cell))
{
Available = non_process_wait_mask;
- check_connect = check_delay = 0;
+ check_delay = 0;
+ IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
else
{
- if (! XINT (read_kbd))
+ if (! read_kbd)
Available = non_keyboard_wait_mask;
else
Available = input_wait_mask;
- check_connect = (num_pending_connects > 0);
+ IF_NON_BLOCKING_CONNECT (check_connect = (num_pending_connects > 0));
check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
}
{
clear_waiting_for_input ();
redisplay_preserve_echo_area (11);
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
}
no_avail = 0;
- if (XINT (read_kbd) && detect_input_pending ())
+ if (read_kbd && detect_input_pending ())
{
nfds = 0;
no_avail = 1;
}
else
{
+#ifdef NON_BLOCKING_CONNECT
if (check_connect)
Connecting = connect_wait_mask;
+#endif
#ifdef ADAPTIVE_READ_BUFFERING
+ /* Set the timeout for adaptive read buffering if any
+ process has non-nil read_output_skip and non-zero
+ read_output_delay, and we are not reading output for a
+ specific wait_channel. It is not executed if
+ Vprocess_adaptive_read_buffering is nil. */
if (process_output_skip && check_delay > 0)
{
int usecs = EMACS_USECS (timeout);
proc = chan_process[channel];
if (NILP (proc))
continue;
+ /* Find minimum non-zero read_output_delay among the
+ processes with non-nil read_output_skip. */
if (XINT (XPROCESS (proc)->read_output_delay) > 0)
{
check_delay--;
nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
&Available,
+#ifdef NON_BLOCKING_CONNECT
(check_connect ? &Connecting : (SELECT_TYPE *)0),
+#else
+ (SELECT_TYPE *)0,
+#endif
(SELECT_TYPE *)0, &timeout);
}
if (no_avail)
{
FD_ZERO (&Available);
- check_connect = 0;
+ IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
#if defined(sun) && !defined(USG5_4)
/* If we are using polling for input,
and we see input available, make it get read now.
Otherwise it might not actually get read for a second.
- And on hpux, since we turn off polling in wait_reading_process_input,
+ And on hpux, since we turn off polling in wait_reading_process_output,
it might never get read at all if we don't spend much time
- outside of wait_reading_process_input. */
- if (XINT (read_kbd) && interrupt_input
+ outside of wait_reading_process_output. */
+ if (read_kbd && interrupt_input
&& keyboard_bit_set (&Available)
&& input_polling_used ())
kill (getpid (), SIGALRM);
/* If there is any, return immediately
to give it higher priority than subprocesses */
- if (XINT (read_kbd) != 0)
+ if (read_kbd != 0)
{
int old_timers_run = timers_run;
struct buffer *old_buffer = current_buffer;
}
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd != 0
&& requeued_events_pending_p ())
break;
That would causes delays in pasting selections, for example.
(We used to do this only if wait_for_cell.) */
- if (XINT (read_kbd) == 0 && detect_input_pending ())
+ if (read_kbd == 0 && detect_input_pending ())
{
swallow_events (do_display);
#if 0 /* Exiting when read_kbd doesn't request that seems wrong, though. */
In that case, there really is no input and no SIGIO,
but select says there is input. */
- if (XINT (read_kbd) && interrupt_input
+ if (read_kbd && interrupt_input
&& keyboard_bit_set (&Available) && ! noninteractive)
kill (getpid (), SIGIO);
#endif
/* If checking input just got us a size-change event from X,
obey it now if we should. */
- if (XINT (read_kbd) || ! NILP (wait_for_cell))
+ if (read_kbd || ! NILP (wait_for_cell))
do_pending_window_change (0);
/* Check for data from a process. */
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
- if (XINT (read_kbd) >= 0)
+ if (read_kbd >= 0)
{
/* Prevent input_pending from remaining set if we quit. */
clear_input_pending ();
The characters read are decoded according to PROC's coding-system
for decoding. */
-int
+static int
read_process_output (proc, channel)
Lisp_Object proc;
register int channel;
if (DATAGRAM_CHAN_P (channel))
{
int len = datagram_address[channel].len;
- nbytes = recvfrom (channel, chars + carryover, readmax - carryover,
+ nbytes = recvfrom (channel, chars + carryover, readmax,
0, datagram_address[channel].sa, &len);
}
else
#endif
if (proc_buffered_char[channel] < 0)
{
- nbytes = emacs_read (channel, chars + carryover, readmax - carryover);
+ nbytes = emacs_read (channel, chars + carryover, readmax);
#ifdef ADAPTIVE_READ_BUFFERING
- if (!NILP (p->adaptive_read_buffering))
+ if (nbytes > 0 && !NILP (p->adaptive_read_buffering))
{
int delay = XINT (p->read_output_delay);
if (nbytes < 256)
delay += READ_OUTPUT_DELAY_INCREMENT * 2;
}
}
- else if (delay > 0 && (nbytes == readmax - carryover))
+ else if (delay > 0 && (nbytes == readmax))
{
delay -= READ_OUTPUT_DELAY_INCREMENT;
if (delay == 0)
{
chars[carryover] = proc_buffered_char[channel];
proc_buffered_char[channel] = -1;
- nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1 - carryover);
+ nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1);
if (nbytes < 0)
nbytes = 1;
else
{
Lisp_Object tem;
/* Don't clobber the CURRENT match data, either! */
- tem = Fmatch_data (Qnil, Qnil);
- restore_match_data ();
- record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
- Fset_match_data (tem);
+ tem = Fmatch_data (Qnil, Qnil, Qnil);
+ restore_search_regs ();
+ record_unwind_save_match_data ();
+ Fset_match_data (tem, Qt);
}
/* For speed, if a search happens within this code,
read_process_output_error_handler);
/* If we saved the match data nonrecursively, restore it now. */
- restore_match_data ();
+ restore_search_regs ();
running_asynch_code = outer_running_asynch_code;
/* Handling the process output should not deactivate the mark. */
SIGTYPE
send_process_trap ()
{
+ SIGNAL_THREAD_CHECK (SIGPIPE);
#ifdef BSD4_1
sigrelse (SIGPIPE);
sigrelse (SIGALRM);
#endif /* BSD4_1 */
+ sigunblock (sigmask (SIGPIPE));
longjmp (send_process_frame, 1);
}
This function can evaluate Lisp code and can garbage collect. */
-void
+static void
send_process (proc, buf, len, object)
volatile Lisp_Object proc;
unsigned char *volatile buf;
int rv;
struct coding_system *coding;
struct gcpro gcpro1;
+ SIGTYPE (*volatile old_sigpipe) ();
GCPRO1 (object);
object = p->encoding_buf;
encode_coding (coding, (char *) buf, SDATA (object),
len, SBYTES (object));
+ coding_free_composition_data (coding);
len = coding->produced;
buf = SDATA (object);
}
while (len > 0)
{
int this = len;
- SIGTYPE (*old_sigpipe)();
/* Decide how much data we can send in one batch.
Long lines need to be split into multiple batches. */
0, datagram_address[outfd].sa,
datagram_address[outfd].len);
if (rv < 0 && errno == EMSGSIZE)
- report_file_error ("sending datagram", Fcons (proc, Qnil));
+ {
+ signal (SIGPIPE, old_sigpipe);
+ report_file_error ("sending datagram",
+ Fcons (proc, Qnil));
+ }
}
else
#endif
that may allow the program
to finish doing output and read more. */
{
- Lisp_Object zero;
int offset = 0;
#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
else if (STRINGP (object))
offset = buf - SDATA (object);
- XSETFASTINT (zero, 0);
#ifdef EMACS_HAS_USECS
- wait_reading_process_input (0, 20000, zero, 0);
+ wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0);
#else
- wait_reading_process_input (1, 0, zero, 0);
+ wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
#endif
if (BUFFERP (object))
#endif /* not VMS */
else
{
+ signal (SIGPIPE, old_sigpipe);
#ifndef VMS
proc = process_sent_to;
p = XPROCESS (proc);
work. If the system has it, use it. */
#ifdef HAVE_TERMIOS
struct termios t;
+ cc_t *sig_char = NULL;
+
+ tcgetattr (XINT (p->infd), &t);
switch (signo)
{
case SIGINT:
- tcgetattr (XINT (p->infd), &t);
- send_process (proc, &t.c_cc[VINTR], 1, Qnil);
- return;
+ sig_char = &t.c_cc[VINTR];
+ break;
case SIGQUIT:
- tcgetattr (XINT (p->infd), &t);
- send_process (proc, &t.c_cc[VQUIT], 1, Qnil);
- return;
+ sig_char = &t.c_cc[VQUIT];
+ break;
case SIGTSTP:
- tcgetattr (XINT (p->infd), &t);
#if defined (VSWTCH) && !defined (PREFER_VSUSP)
- send_process (proc, &t.c_cc[VSWTCH], 1, Qnil);
+ sig_char = &t.c_cc[VSWTCH];
#else
- send_process (proc, &t.c_cc[VSUSP], 1, Qnil);
+ sig_char = &t.c_cc[VSUSP];
#endif
- return;
+ break;
}
+ if (sig_char && *sig_char != CDISABLE)
+ {
+ send_process (proc, sig_char, 1, Qnil);
+ return;
+ }
+ /* If we can't send the signal with a character,
+ fall through and send it another way. */
#else /* ! HAVE_TERMIOS */
/* On Berkeley descendants, the following IOCTL's retrieve the
you'd better be using one of the alternatives above! */
#endif /* ! defined (TCGETA) */
#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
-#endif /* ! defined HAVE_TERMIOS */
+ /* In this case, the code above should alway returns. */
abort ();
- /* The code above always returns from the function. */
+#endif /* ! defined HAVE_TERMIOS */
+
+ /* The code above may fall through if it can't
+ handle the signal. */
#endif /* defined (SIGNALS_VIA_CHARACTERS) */
#ifdef TIOCGPGRP
p->status = Qrun;
XSETINT (p->tick, ++process_tick);
if (!nomsg)
- status_notify ();
+ status_notify (NULL);
break;
#endif /* ! defined (SIGCONT) */
case SIGINT:
}
#endif
#ifndef SIGTSTP
- error ("no SIGTSTP support");
+ error ("No SIGTSTP support");
#else
process_send_signal (process, SIGTSTP, current_group, 0);
#endif
#ifdef SIGCONT
process_send_signal (process, SIGCONT, current_group, 0);
#else
- error ("no SIGCONT support");
+ error ("No SIGCONT support");
#endif
return process;
}
register struct Lisp_Process *p;
extern EMACS_TIME *input_available_clear_time;
+ SIGNAL_THREAD_CHECK (signo);
+
#ifdef BSD4_1
extern int sigheld;
sigheld |= sigbit (SIGCHLD);
FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
}
- /* Tell wait_reading_process_input that it needs to wake up and
+ /* Tell wait_reading_process_output that it needs to wake up and
look around. */
if (input_available_clear_time)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
else if (WIFSIGNALED (w))
synch_process_termsig = WTERMSIG (w);
- /* Tell wait_reading_process_input that it needs to wake up and
+ /* Tell wait_reading_process_output that it needs to wake up and
look around. */
if (input_available_clear_time)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
if (outer_running_asynch_code)
{
Lisp_Object tem;
- tem = Fmatch_data (Qnil, Qnil);
- restore_match_data ();
- record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
- Fset_match_data (tem);
+ tem = Fmatch_data (Qnil, Qnil, Qnil);
+ restore_search_regs ();
+ record_unwind_save_match_data ();
+ Fset_match_data (tem, Qt);
}
/* For speed, if a search happens within this code,
exec_sentinel_error_handler);
/* If we saved the match data nonrecursively, restore it now. */
- restore_match_data ();
+ restore_search_regs ();
running_asynch_code = outer_running_asynch_code;
Vdeactivate_mark = odeactivate;
This is usually done while Emacs is waiting for keyboard input
but can be done at other times. */
-void
-status_notify ()
+static void
+status_notify (deleting_process)
+ struct Lisp_Process *deleting_process;
{
register Lisp_Object proc, buffer;
Lisp_Object tail, msg;
&& ! EQ (p->status, Qlisten)
&& ! EQ (p->command, Qt) /* Network process not stopped. */
&& XINT (p->infd) >= 0
+ && p != deleting_process
&& read_process_output (proc, XINT (p->infd)) > 0);
buffer = p->buffer;
/* Return nonzero if *MASK has a bit set
that corresponds to one of the keyboard input descriptors. */
-int
+static int
keyboard_bit_set (mask)
SELECT_TYPE *mask;
{
FD_ZERO (&non_process_wait_mask);
max_process_desc = 0;
+#ifdef NON_BLOCKING_CONNECT
+ FD_ZERO (&connect_wait_mask);
+ num_pending_connects = 0;
+#endif
+
#ifdef ADAPTIVE_READ_BUFFERING
process_output_delay_count = 0;
process_output_skip = 0;
Fprovide (intern ("make-network-process"), subfeatures);
}
#endif /* HAVE_SOCKETS */
+
+#if defined (DARWIN) || defined (MAC_OSX)
+ /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
+ processes. As such, we only change the default value. */
+ if (initialized)
+ {
+ char *release = get_operating_system_release();
+ if (!release || !release[0] || (release[0] < MIN_PTY_KERNEL_VERSION
+ && release[1] == '.')) {
+ Vprocess_connection_type = Qnil;
+ }
+ }
+#endif
}
void
doc: /* If non-nil, improve receive buffering by delaying after short reads.
On some systems, when Emacs reads the output from a subprocess, the output data
is read in very small blocks, potentially resulting in very poor performance.
-This behaviour can be remedied to some extent by setting this variable to a
+This behavior can be remedied to some extent by setting this variable to a
non-nil value, as it will automatically delay reading from such processes, to
allowing them to produce more output before Emacs tries to read it.
If the value is t, the delay is reset after each write to the process; any other
1 to return when input is available, or
-1 means caller will actually read the input, so don't throw to
the quit handler.
- a cons cell, meaning wait until its car is non-nil
- (and gobble terminal input into the buffer if any arrives), or
- We know that read_kbd will never be a Lisp_Process, since
- `subprocesses' isn't defined.
+
+ see full version for other parameters. We know that wait_proc will
+ always be NULL, since `subprocesses' isn't defined.
do_display != 0 means redisplay should be done to show subprocess
output that arrives.
Return true iff we received input from any process. */
int
-wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
- int time_limit, microsecs;
- Lisp_Object read_kbd;
- int do_display;
+wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
+ wait_for_cell, wait_proc, just_wait_proc)
+ int time_limit, microsecs, read_kbd, do_display;
+ Lisp_Object wait_for_cell;
+ struct Lisp_Process *wait_proc;
+ int just_wait_proc;
{
register int nfds;
EMACS_TIME end_time, timeout;
SELECT_TYPE waitchannels;
int xerrno;
- /* 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;
-
- wait_for_cell = Qnil;
-
- /* If waiting for non-nil in a cell, record where. */
- if (CONSP (read_kbd))
- {
- wait_for_cell = read_kbd;
- XSETFASTINT (read_kbd, 0);
- }
/* What does time_limit really mean? */
if (time_limit || microsecs)
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
Otherwise, do pending quit if requested. */
- if (XINT (read_kbd) >= 0)
+ if (read_kbd >= 0)
QUIT;
/* Exit now if the cell we're waiting for became non-nil. */
while (!detect_input_pending ());
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd != 0
&& requeued_events_pending_p ())
break;
/* Cause C-g and alarm signals to take immediate action,
and cause input available signals to zero out timeout. */
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
/* Wait till there is something to do. */
- if (! XINT (read_kbd) && NILP (wait_for_cell))
+ if (! read_kbd && NILP (wait_for_cell))
FD_ZERO (&waitchannels);
else
FD_SET (0, &waitchannels);
{
clear_waiting_for_input ();
redisplay_preserve_echo_area (15);
- if (XINT (read_kbd) < 0)
+ if (read_kbd < 0)
set_waiting_for_input (&timeout);
}
- if (XINT (read_kbd) && detect_input_pending ())
+ if (read_kbd && detect_input_pending ())
{
nfds = 0;
FD_ZERO (&waitchannels);
kill (getpid (), SIGIO);
#endif
#ifdef SIGIO
- if (XINT (read_kbd) && interrupt_input && (waitchannels & 1))
+ if (read_kbd && interrupt_input && (waitchannels & 1))
kill (getpid (), SIGIO);
#endif
/* Check for keyboard input */
- if ((XINT (read_kbd) != 0)
+ if (read_kbd
&& detect_input_pending_run_timers (do_display))
{
swallow_events (do_display);
}
/* If there is unread keyboard input, also return. */
- if (XINT (read_kbd) != 0
+ if (read_kbd
&& requeued_events_pending_p ())
break;