/* Asynchronous subprocess control for GNU Emacs.
Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
1996, 1998, 1999, 2001, 2002, 2003, 2004,
- 2005, 2006 Free Software Foundation, Inc.
+ 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include <sys/wait.h>
#endif
-/* Disable IPv6 support for w32 until someone figures out how to do it
- properly. */
-#ifdef WINDOWSNT
-# ifdef AF_INET6
-# undef AF_INET6
-# endif
-#endif
-
#include "lisp.h"
#include "systime.h"
#include "systty.h"
#include "charset.h"
#include "coding.h"
#include "process.h"
+#include "frame.h"
#include "termhooks.h"
#include "termopts.h"
#include "commands.h"
#include "keyboard.h"
-#include "frame.h"
#include "blockinput.h"
#include "dispextern.h"
#include "composite.h"
static SELECT_TYPE input_wait_mask;
-/* Mask that excludes keyboard input descriptor (s). */
+/* Mask that excludes keyboard input descriptor(s). */
static SELECT_TYPE non_keyboard_wait_mask;
-/* Mask that excludes process input descriptor (s). */
+/* Mask that excludes process input descriptor(s). */
static SELECT_TYPE non_process_wait_mask;
+/* Mask for the gpm mouse input descriptor. */
+
+static SELECT_TYPE gpm_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
/* The largest descriptor currently in use for keyboard input. */
static int max_keyboard_desc;
+/* The largest descriptor currently in use for gpm mouse input. */
+static int max_gpm_desc;
+
/* Nonzero means delete a process right away if it exits. */
static int delete_exited_processes;
int len;
} datagram_address[MAXDESC];
#define DATAGRAM_CHAN_P(chan) (datagram_address[chan].sa != 0)
-#define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XINT (XPROCESS (proc)->infd)].sa != 0)
+#define DATAGRAM_CONN_P(proc) (PROCESSP (proc) && datagram_address[XPROCESS (proc)->infd].sa != 0)
#else
#define DATAGRAM_CHAN_P(chan) (0)
#define DATAGRAM_CONN_P(proc) (0)
p = allocate_process ();
- XSETINT (p->infd, -1);
- XSETINT (p->outfd, -1);
- XSETFASTINT (p->tick, 0);
- XSETFASTINT (p->update_tick, 0);
+ p->infd = -1;
+ p->outfd = -1;
+ p->tick = 0;
+ p->update_tick = 0;
p->pid = 0;
p->raw_status_new = 0;
p->status = Qrun;
p->mark = Fmake_marker ();
#ifdef ADAPTIVE_READ_BUFFERING
- p->adaptive_read_buffering = Qnil;
- XSETFASTINT (p->read_output_delay, 0);
- p->read_output_skip = Qnil;
+ p->adaptive_read_buffering = 0;
+ p->read_output_delay = 0;
+ p->read_output_skip = 0;
#endif
/* If name is already in use, modify it until it is unused. */
Lisp_Object process;
{
struct Lisp_Process *p = XPROCESS (process);
- int inch = XINT (p->infd);
- int outch = XINT (p->outfd);
+ int inch = p->infd;
+ int outch = p->outfd;
if (inch < 0 || outch < 0)
return;
proc_decode_coding_system[inch]);
if (! NILP (p->filter))
{
- if (NILP (p->filter_multibyte))
+ if (!p->filter_multibyte)
setup_raw_text_coding_system (proc_decode_coding_system[inch]);
}
else if (BUFFERP (p->buffer))
if (NETCONN1_P (p))
{
p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
status_notify (p);
}
- else if (XINT (p->infd) >= 0)
+ else if (p->infd >= 0)
{
#ifdef SIGCHLD
Lisp_Object symbol;
+ /* Assignment to EMACS_INT stops GCC whining about limited range
+ of data type. */
+ EMACS_INT pid = p->pid;
/* No problem storing the pid here, as it is still in Vprocess_alist. */
- deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
+ deleted_pid_list = Fcons (make_fixnum_or_float (pid),
/* GC treated elements set to nil. */
Fdelq (Qnil, deleted_pid_list));
/* If the process has already signaled, remove it from the list. */
if (CONSP (p->status))
symbol = XCAR (p->status);
if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
- Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
+ deleted_pid_list
+ = Fdelete (make_fixnum_or_float (pid), deleted_pid_list);
else
#endif
{
/* Do this now, since remove_process will make sigchld_handler do nothing. */
p->status
= Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
status_notify (p);
}
}
(process)
register Lisp_Object process;
{
+ /* Assignment to EMACS_INT stops GCC whining about limited range of
+ data type. */
+ EMACS_INT pid;
+
CHECK_PROCESS (process);
- return (XPROCESS (process)->pid
- ? make_fixnum_or_float (XPROCESS (process)->pid)
- : Qnil);
+ pid = XPROCESS (process)->pid;
+ return (pid ? make_fixnum_or_float (pid) : Qnil);
}
DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
(debug)
(set-process-filter process ...) */
- if (XINT (p->infd) >= 0)
+ if (p->infd >= 0)
{
if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
{
- FD_CLR (XINT (p->infd), &input_wait_mask);
- FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_CLR (p->infd, &input_wait_mask);
+ FD_CLR (p->infd, &non_keyboard_wait_mask);
}
else if (EQ (p->filter, Qt)
&& !EQ (p->command, Qt)) /* Network process not stopped. */
{
- FD_SET (XINT (p->infd), &input_wait_mask);
- FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_SET (p->infd, &input_wait_mask);
+ FD_SET (p->infd, &non_keyboard_wait_mask);
}
}
CHECK_NATNUM (height);
CHECK_NATNUM (width);
- if (XINT (XPROCESS (process)->infd) < 0
- || set_window_size (XINT (XPROCESS (process)->infd),
+ if (XPROCESS (process)->infd < 0
+ || set_window_size (XPROCESS (process)->infd,
XINT (height), XINT (width)) <= 0)
return Qnil;
else
register Lisp_Object process, flag;
{
CHECK_PROCESS (process);
- XPROCESS (process)->inherit_coding_system_flag = flag;
+ XPROCESS (process)->inherit_coding_system_flag = !NILP (flag);
return flag;
}
register Lisp_Object process;
{
CHECK_PROCESS (process);
- return XPROCESS (process)->inherit_coding_system_flag;
+ return XPROCESS (process)->inherit_coding_system_flag ? Qt : Qnil;
}
DEFUN ("set-process-query-on-exit-flag",
register Lisp_Object process, flag;
{
CHECK_PROCESS (process);
- XPROCESS (process)->kill_without_query = Fnull (flag);
+ XPROCESS (process)->kill_without_query = NILP (flag);
return flag;
}
register Lisp_Object process;
{
CHECK_PROCESS (process);
- return Fnull (XPROCESS (process)->kill_without_query);
+ return (XPROCESS (process)->kill_without_query ? Qnil : Qt);
}
#ifdef DATAGRAM_SOCKETS
if (VECTORP (address)) /* AF_INET or AF_INET6 */
{
register struct Lisp_Vector *p = XVECTOR (address);
- Lisp_Object args[6];
+ Lisp_Object args[10];
int nargs, i;
if (p->size == 4 || (p->size == 5 && !NILP (omit_port)))
return Qnil;
for (i = 0; i < nargs; i++)
- args[i+1] = p->contents[i];
+ {
+ EMACS_INT element = XINT (p->contents[i]);
+
+ if (element < 0 || element > 65535)
+ return Qnil;
+
+ if (nargs <= 5 /* IPv4 */
+ && i < 4 /* host, not port */
+ && element > 255)
+ return Qnil;
+
+ args[i+1] = p->contents[i];
+ }
+
return Fformat (nargs+1, args);
}
args[0] = build_string ("<Family %d>");
args[1] = Fcar (address);
return Fformat (2, args);
-
}
return Qnil;
register struct Lisp_Process *p;
char tembuf[300];
int w_proc, w_buffer, w_tty;
+ int exited = 0;
Lisp_Object i_status, i_buffer, i_tty, i_command;
w_proc = 4; /* Proc */
p = XPROCESS (proc);
if (NILP (p->childp))
continue;
- if (!NILP (query_only) && !NILP (p->kill_without_query))
+ if (!NILP (query_only) && p->kill_without_query)
continue;
if (STRINGP (p->name)
&& ( i = SCHARS (p->name), (i > w_proc)))
p = XPROCESS (proc);
if (NILP (p->childp))
continue;
- if (!NILP (query_only) && !NILP (p->kill_without_query))
+ if (!NILP (query_only) && p->kill_without_query)
continue;
Finsert (1, &p->name);
if (CONSP (p->status))
symbol = XCAR (p->status);
-
if (EQ (symbol, Qsignal))
{
Lisp_Object tem;
}
}
- if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
- remove_process (proc);
+ if (EQ (symbol, Qsignal) || EQ (symbol, Qexit) || EQ (symbol, Qclosed))
+ exited++;
Findent_to (i_buffer, minspace);
if (NILP (p->buffer))
if (NILP (port))
port = Fformat_network_address (Fplist_get (p->childp, QClocal), Qnil);
sprintf (tembuf, "(network %s server on %s)\n",
- (DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"),
+ (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
(STRINGP (port) ? (char *)SDATA (port) : "?"));
insert_string (tembuf);
}
if (NILP (host))
host = Fformat_network_address (Fplist_get (p->childp, QCremote), Qnil);
sprintf (tembuf, "(network %s connection to %s)\n",
- (DATAGRAM_CHAN_P (XINT (p->infd)) ? "datagram" : "stream"),
+ (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
(STRINGP (host) ? (char *)SDATA (host) : "?"));
insert_string (tembuf);
}
insert_string ("\n");
}
}
+ if (exited)
+ status_notify (NULL);
return Qnil;
}
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.
+
+Process output (both standard output and standard error streams) goes
+at end of BUFFER, unless you specify an output stream or filter
+function to handle the output. BUFFER may also be nil, meaning that
+this process is not associated with any buffer.
+
PROGRAM is the program file name. It is searched for in PATH.
Remaining arguments are strings to give program as arguments.
+If you want to separate standard output from standard error, invoke
+the command through a shell and redirect one of them using the shell
+syntax.
+
usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
(nargs, args)
int nargs;
XPROCESS (proc)->sentinel = Qnil;
XPROCESS (proc)->filter = Qnil;
XPROCESS (proc)->filter_multibyte
- = buffer_defaults.enable_multibyte_characters;
+ = !NILP (buffer_defaults.enable_multibyte_characters);
XPROCESS (proc)->command = Flist (nargs - 2, args + 2);
#ifdef ADAPTIVE_READ_BUFFERING
- XPROCESS (proc)->adaptive_read_buffering = Vprocess_adaptive_read_buffering;
+ XPROCESS (proc)->adaptive_read_buffering
+ = (NILP (Vprocess_adaptive_read_buffering) ? 0
+ : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2);
#endif
/* Make the process marker point into the process buffer (if any). */
#endif /* not VMS */
XPROCESS (proc)->decoding_buf = make_uninit_string (0);
- XPROCESS (proc)->decoding_carryover = make_number (0);
+ XPROCESS (proc)->decoding_carryover = 0;
XPROCESS (proc)->encoding_buf = make_uninit_string (0);
- XPROCESS (proc)->encoding_carryover = make_number (0);
XPROCESS (proc)->inherit_coding_system_flag
- = (NILP (buffer) || !inherit_process_coding_system
- ? Qnil : Qt);
+ = !(NILP (buffer) || !inherit_process_coding_system);
create_process (proc, (char **) new_argv, current_dir);
char **new_argv;
Lisp_Object current_dir;
{
- int pid, inchannel, outchannel;
+ int inchannel, outchannel;
+ pid_t pid;
int sv[2];
#ifdef POSIX_SIGNALS
sigset_t procmask;
/* Record this as an active process, with its channels.
As a result, child_setup will close Emacs's side of the pipes. */
chan_process[inchannel] = process;
- XSETINT (XPROCESS (process)->infd, inchannel);
- XSETINT (XPROCESS (process)->outfd, outchannel);
+ XPROCESS (process)->infd = inchannel;
+ XPROCESS (process)->outfd = outchannel;
/* Previously we recorded the tty descriptor used in the subprocess.
It was only used for getting the foreground tty process, so now
we just reopen the device (see emacs_get_tty_pgrp) as this is
more portable (see USG_SUBTTY_WORKS above). */
- XPROCESS (process)->pty_flag = (pty_flag ? Qt : Qnil);
+ XPROCESS (process)->pty_flag = pty_flag;
XPROCESS (process)->status = Qrun;
setup_process_coding_systems (process);
if (!DATAGRAM_CONN_P (process))
return Qnil;
- channel = XINT (XPROCESS (process)->infd);
+ channel = XPROCESS (process)->infd;
return conv_sockaddr_to_lisp (datagram_address[channel].sa,
datagram_address[channel].len);
}
if (!DATAGRAM_CONN_P (process))
return Qnil;
- channel = XINT (XPROCESS (process)->infd);
+ channel = XPROCESS (process)->infd;
len = get_lisp_to_sockaddr_size (address, &family);
if (datagram_address[channel].len != len)
if (!NETCONN1_P (p))
error ("Process is not a network process");
- s = XINT (p->infd);
+ s = p->infd;
if (s < 0)
error ("Process is not running");
/* Make QCaddress an alias for :local (server) or :remote (client). */
QCaddress = is_server ? QClocal : QCremote;
- /* :wait BOOL */
+ /* :nowait BOOL */
if (!is_server && socktype == SOCK_STREAM
&& (tem = Fplist_get (contact, QCnowait), !NILP (tem)))
{
open_socket:
+#ifdef __ultrix__
+ /* Previously this was compiled unconditionally, but that seems
+ unnecessary on modern systems, and `unrequest_sigio' was a noop
+ under X anyway. --lorentey */
/* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
when connect is interrupted. So let's not let it get interrupted.
Note we do not turn off polling, because polling is only used
record_unwind_protect (unwind_request_sigio, Qnil);
unrequest_sigio ();
}
+#endif
/* Do this in case we never enter the for-loop below. */
count1 = SPECPDL_INDEX ();
#endif
}
+ immediate_quit = 0;
+
#ifdef HAVE_GETADDRINFO
if (res != &ai)
- freeaddrinfo (res);
+ {
+ BLOCK_INPUT;
+ freeaddrinfo (res);
+ UNBLOCK_INPUT;
+ }
#endif
- immediate_quit = 0;
-
/* Discard the unwind protect for closing S, if any. */
specpdl_ptr = specpdl + count1;
p->buffer = buffer;
p->sentinel = sentinel;
p->filter = filter;
- p->filter_multibyte = buffer_defaults.enable_multibyte_characters;
+ p->filter_multibyte = !NILP (buffer_defaults.enable_multibyte_characters);
/* Override the above only if :filter-multibyte is specified. */
if (! NILP (Fplist_member (contact, QCfilter_multibyte)))
- p->filter_multibyte = Fplist_get (contact, QCfilter_multibyte);
+ p->filter_multibyte = !NILP (Fplist_get (contact, QCfilter_multibyte));
p->log = Fplist_get (contact, QClog);
if (tem = Fplist_get (contact, QCnoquery), !NILP (tem))
- p->kill_without_query = Qt;
+ p->kill_without_query = 1;
if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
p->command = Qt;
p->pid = 0;
- XSETINT (p->infd, inch);
- XSETINT (p->outfd, outch);
+ p->infd = inch;
+ p->outfd = outch;
if (is_server && socktype == SOCK_STREAM)
p->status = Qlisten;
setup_process_coding_systems (proc);
p->decoding_buf = make_uninit_string (0);
- p->decoding_carryover = make_number (0);
+ p->decoding_carryover = 0;
p->encoding_buf = make_uninit_string (0);
- p->encoding_carryover = make_number (0);
p->inherit_coding_system_flag
- = (!NILP (tem) || NILP (buffer) || !inherit_process_coding_system
- ? Qnil : Qt);
+ = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);
UNGCPRO;
return proc;
register int inchannel, outchannel;
register struct Lisp_Process *p = XPROCESS (proc);
- inchannel = XINT (p->infd);
- outchannel = XINT (p->outfd);
+ inchannel = p->infd;
+ outchannel = p->outfd;
#ifdef ADAPTIVE_READ_BUFFERING
- if (XINT (p->read_output_delay) > 0)
+ if (p->read_output_delay > 0)
{
if (--process_output_delay_count < 0)
process_output_delay_count = 0;
- XSETINT (p->read_output_delay, 0);
- p->read_output_skip = Qnil;
+ p->read_output_delay = 0;
+ p->read_output_skip = 0;
}
#endif
emacs_close (outchannel);
#endif
- XSETINT (p->infd, -1);
- XSETINT (p->outfd, -1);
+ p->infd = -1;
+ p->outfd = -1;
#ifdef DATAGRAM_SOCKETS
if (DATAGRAM_CHAN_P (inchannel))
{
process = chan_process[i];
if (!NILP (process))
{
- int in = XINT (XPROCESS (process)->infd);
- int out = XINT (XPROCESS (process)->outfd);
+ int in = XPROCESS (process)->infd;
+ int out = XPROCESS (process)->outfd;
if (in >= 0)
emacs_close (in);
if (out >= 0 && in != out)
p->filter = ps->filter;
p->command = Qnil;
p->pid = 0;
- XSETINT (p->infd, s);
- XSETINT (p->outfd, s);
+ p->infd = s;
+ p->outfd = s;
p->status = Qrun;
/* Client processes for accepted connections are not stopped initially. */
setup_process_coding_systems (proc);
p->decoding_buf = make_uninit_string (0);
- p->decoding_carryover = make_number (0);
+ p->decoding_carryover = 0;
p->encoding_buf = make_uninit_string (0);
- p->encoding_carryover = make_number (0);
p->inherit_coding_system_flag
- = (NILP (buffer) ? Qnil : ps->inherit_coding_system_flag);
+ = (NILP (buffer) ? 0 : ps->inherit_coding_system_flag);
if (!NILP (ps->log))
call3 (ps->log, server, proc,
/* If wait_proc is a process to watch, set wait_channel accordingly. */
if (wait_proc != NULL)
- wait_channel = XINT (wait_proc->infd);
+ wait_channel = wait_proc->infd;
record_unwind_protect (wait_reading_process_output_unwind,
make_number (waiting_for_user_input_p));
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,
+ if ((select (max (max (max_process_desc, max_keyboard_desc),
+ max_gpm_desc) + 1,
&Atemp,
#ifdef NON_BLOCKING_CONNECT
(num_pending_connects > 0 ? &Ctemp : (SELECT_TYPE *)0),
XSETPROCESS (proc, wait_proc);
/* Read data from the process, until we exhaust it. */
- while (XINT (wait_proc->infd) >= 0)
+ while (wait_proc->infd >= 0)
{
- nread = read_process_output (proc, XINT (wait_proc->infd));
+ nread = read_process_output (proc, wait_proc->infd);
if (nread == 0)
break;
if (wait_proc && just_wait_proc)
{
- if (XINT (wait_proc->infd) < 0) /* Terminated */
+ if (wait_proc->infd < 0) /* Terminated */
break;
- FD_SET (XINT (wait_proc->infd), &Available);
+ FD_SET (wait_proc->infd, &Available);
check_delay = 0;
IF_NON_BLOCKING_CONNECT (check_connect = 0);
}
#ifdef ADAPTIVE_READ_BUFFERING
/* Set the timeout for adaptive read buffering if any
- process has non-nil read_output_skip and non-zero
+ process has non-zero 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 (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)
+ processes with non-zero read_output_skip. */
+ if (XPROCESS (proc)->read_output_delay > 0)
{
check_delay--;
- if (NILP (XPROCESS (proc)->read_output_skip))
+ if (!XPROCESS (proc)->read_output_skip)
continue;
FD_CLR (channel, &Available);
- XPROCESS (proc)->read_output_skip = Qnil;
- if (XINT (XPROCESS (proc)->read_output_delay) < usecs)
- usecs = XINT (XPROCESS (proc)->read_output_delay);
+ XPROCESS (proc)->read_output_skip = 0;
+ if (XPROCESS (proc)->read_output_delay < usecs)
+ usecs = XPROCESS (proc)->read_output_delay;
}
}
EMACS_SET_SECS_USECS (timeout, 0, usecs);
}
#endif
- nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
+ nfds = select (max (max (max_process_desc, max_keyboard_desc),
+ max_gpm_desc) + 1,
&Available,
#ifdef NON_BLOCKING_CONNECT
(check_connect ? &Connecting : (SELECT_TYPE *)0),
subprocess termination and SIGCHLD. */
else if (nread == 0 && !NETCONN_P (proc))
;
-#endif /* O_NDELAY */
-#endif /* O_NONBLOCK */
+#endif /* O_NDELAY */
+#endif /* O_NONBLOCK */
#ifdef HAVE_PTYS
/* On some OSs with ptys, when the process on one end of
a pty exits, the other end gets an error reading with
get a SIGCHLD).
However, it has been known to happen that the SIGCHLD
- got lost. So raise the signl again just in case.
+ got lost. So raise the signal again just in case.
It can't hurt. */
else if (nread == -1 && errno == EIO)
- kill (getpid (), SIGCHLD);
-#endif /* HAVE_PTYS */
+ {
+ /* Clear the descriptor now, so we only raise the signal once. */
+ FD_CLR (channel, &input_wait_mask);
+ FD_CLR (channel, &non_keyboard_wait_mask);
+
+ kill (getpid (), SIGCHLD);
+ }
+#endif /* HAVE_PTYS */
/* If we can detect process termination, don't consider the process
gone just because its pipe is closed. */
#ifdef SIGCHLD
else
{
/* Preserve status of processes already terminated. */
- XSETINT (XPROCESS (proc)->tick, ++process_tick);
+ XPROCESS (proc)->tick = ++process_tick;
deactivate_process (proc);
if (XPROCESS (proc)->raw_status_new)
update_status (XPROCESS (proc));
#endif
if (xerrno)
{
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
p->status = Fcons (Qfailed, Fcons (make_number (xerrno), Qnil));
deactivate_process (proc);
}
exec_sentinel (proc, build_string ("open\n"));
if (!EQ (p->filter, Qt) && !EQ (p->command, Qt))
{
- FD_SET (XINT (p->infd), &input_wait_mask);
- FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_SET (p->infd, &input_wait_mask);
+ FD_SET (p->infd, &non_keyboard_wait_mask);
}
}
}
register struct Lisp_Process *p = XPROCESS (proc);
register int opoint;
struct coding_system *coding = proc_decode_coding_system[channel];
- int carryover = XINT (p->decoding_carryover);
+ int carryover = p->decoding_carryover;
int readmax = 4096;
#ifdef VMS
{
nbytes = emacs_read (channel, chars + carryover, readmax);
#ifdef ADAPTIVE_READ_BUFFERING
- if (nbytes > 0 && !NILP (p->adaptive_read_buffering))
+ if (nbytes > 0 && p->adaptive_read_buffering)
{
- int delay = XINT (p->read_output_delay);
+ int delay = p->read_output_delay;
if (nbytes < 256)
{
if (delay < READ_OUTPUT_DELAY_MAX_MAX)
if (delay == 0)
process_output_delay_count--;
}
- XSETINT (p->read_output_delay, delay);
+ p->read_output_delay = delay;
if (delay)
{
- p->read_output_skip = Qt;
+ p->read_output_skip = 1;
process_output_skip = 1;
}
}
}
#endif /* not VMS */
- XSETINT (p->decoding_carryover, 0);
+ p->decoding_carryover = 0;
/* At this point, NBYTES holds number of bytes just received
(including the one in proc_buffered_char[channel]). */
valid memory because p->outfd will be changed once EOF is
sent to the process. */
if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[XINT (p->outfd)])
+ && proc_encode_coding_system[p->outfd])
{
p->encode_coding_system = coding->symbol;
setup_coding_system (coding->symbol,
- proc_encode_coding_system[XINT (p->outfd)]);
- if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]);
+ if (proc_encode_coding_system[p->outfd]->eol_type
== CODING_EOL_UNDECIDED)
- proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]->eol_type
= system_eol_type;
}
}
carryover = nbytes - coding->consumed;
+ if (carryover < 0)
+ abort ();
+
if (SCHARS (p->decoding_buf) < carryover)
p->decoding_buf = make_uninit_string (carryover);
bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
carryover);
- XSETINT (p->decoding_carryover, carryover);
+ p->decoding_carryover = carryover;
/* Adjust the multibyteness of TEXT to that of the filter. */
- if (NILP (p->filter_multibyte) != ! STRING_MULTIBYTE (text))
+ if (!p->filter_multibyte != !STRING_MULTIBYTE (text))
text = (STRING_MULTIBYTE (text)
? Fstring_as_unibyte (text)
: Fstring_to_multibyte (text));
{
p->decode_coding_system = coding->symbol;
if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[XINT (p->outfd)])
+ && proc_encode_coding_system[p->outfd])
{
p->encode_coding_system = coding->symbol;
setup_coding_system (coding->symbol,
- proc_encode_coding_system[XINT (p->outfd)]);
- if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]);
+ if (proc_encode_coding_system[p->outfd]->eol_type
== CODING_EOL_UNDECIDED)
- proc_encode_coding_system[XINT (p->outfd)]->eol_type
+ proc_encode_coding_system[p->outfd]->eol_type
= system_eol_type;
}
}
carryover = nbytes - coding->consumed;
+ if (carryover < 0)
+ abort ();
+
if (SCHARS (p->decoding_buf) < carryover)
p->decoding_buf = make_uninit_string (carryover);
bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
carryover);
- XSETINT (p->decoding_carryover, carryover);
+ p->decoding_carryover = carryover;
+
/* Adjust the multibyteness of TEXT to that of the buffer. */
if (NILP (current_buffer->enable_multibyte_characters)
!= ! STRING_MULTIBYTE (text))
update_status (p);
if (! EQ (p->status, Qrun))
error ("Process %s not running", SDATA (p->name));
- if (XINT (p->outfd) < 0)
+ if (p->outfd < 0)
error ("Output file descriptor of %s is closed", SDATA (p->name));
- coding = proc_encode_coding_system[XINT (p->outfd)];
+ coding = proc_encode_coding_system[p->outfd];
Vlast_coding_system_used = coding->symbol;
if ((STRINGP (object) && STRING_MULTIBYTE (object))
if (pty_max_bytes == 0)
{
#if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON)
- pty_max_bytes = fpathconf (XFASTINT (p->outfd), _PC_MAX_CANON);
+ pty_max_bytes = fpathconf (p->outfd, _PC_MAX_CANON);
if (pty_max_bytes < 0)
pty_max_bytes = 250;
#else
/* Decide how much data we can send in one batch.
Long lines need to be split into multiple batches. */
- if (!NILP (p->pty_flag))
+ if (p->pty_flag)
{
/* Starting this at zero is always correct when not the first
iteration because the previous iteration ended by sending C-d.
/* Send this batch, using one or more write calls. */
while (this > 0)
{
- int outfd = XINT (p->outfd);
+ int outfd = p->outfd;
old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
#ifdef DATAGRAM_SOCKETS
if (DATAGRAM_CHAN_P (outfd))
{
rv = emacs_write (outfd, (char *) buf, this);
#ifdef ADAPTIVE_READ_BUFFERING
- if (XINT (p->read_output_delay) > 0
- && EQ (p->adaptive_read_buffering, Qt))
+ if (p->read_output_delay > 0
+ && p->adaptive_read_buffering == 1)
{
- XSETFASTINT (p->read_output_delay, 0);
+ p->read_output_delay = 0;
process_output_delay_count--;
- p->read_output_skip = Qnil;
+ p->read_output_skip = 0;
}
#endif
}
if (errno == EAGAIN)
{
int flags = FWRITE;
- ioctl (XINT (p->outfd), TIOCFLUSH, &flags);
+ ioctl (p->outfd, TIOCFLUSH, &flags);
}
#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
#endif
p->raw_status_new = 0;
p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
deactivate_process (proc);
#ifdef VMS
error ("Error writing to process %s; closed it", SDATA (p->name));
UNGCPRO;
}
+static Lisp_Object
+send_process_object_unwind (buf)
+ Lisp_Object buf;
+{
+ Lisp_Object tembuf;
+
+ if (XBUFFER (buf) == current_buffer)
+ return Qnil;
+ tembuf = Fcurrent_buffer ();
+ Fset_buffer (buf);
+ Fkill_buffer (tembuf);
+ return Qnil;
+}
+
+/* Send current contents of region between START and END to PROC.
+ If START is a string, send it instead.
+ This function can evaluate Lisp code and can garbage collect. */
+
+static void
+send_process_object (proc, start, end)
+ Lisp_Object proc, start, end;
+{
+ int count = SPECPDL_INDEX ();
+ Lisp_Object object = STRINGP (start) ? start : Fcurrent_buffer ();
+ struct buffer *given_buffer = current_buffer;
+ unsigned char *buf;
+ int len;
+
+ record_unwind_protect (send_process_object_unwind, Fcurrent_buffer ());
+
+ if (STRINGP (object) ? STRING_MULTIBYTE (object)
+ : ! NILP (XBUFFER (object)->enable_multibyte_characters))
+ {
+ struct Lisp_Process *p = XPROCESS (proc);
+ struct coding_system *coding;
+
+ if (p->raw_status_new)
+ update_status (p);
+ if (! EQ (p->status, Qrun))
+ error ("Process %s not running", SDATA (p->name));
+ if (p->outfd < 0)
+ error ("Output file descriptor of %s is closed", SDATA (p->name));
+
+ coding = proc_encode_coding_system[p->outfd];
+ if (! EQ (coding->symbol, p->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 (p->encode_coding_system, coding);
+ if (! NILP (coding->pre_write_conversion))
+ {
+ struct gcpro gcpro1, gcpro2;
+
+ GCPRO2 (proc, object);
+ call2 (coding->pre_write_conversion, start, end);
+ UNGCPRO;
+ if (given_buffer != current_buffer)
+ {
+ start = make_number (BEGV), end = make_number (ZV);
+ object = Fcurrent_buffer ();
+ }
+ }
+ }
+
+ if (BUFFERP (object))
+ {
+ EMACS_INT start_byte;
+
+ if (XINT (start) < GPT && XINT (end) > GPT)
+ move_gap (XINT (end));
+ start_byte = CHAR_TO_BYTE (XINT (start));
+ buf = BYTE_POS_ADDR (start_byte);
+ len = CHAR_TO_BYTE (XINT (end)) - start_byte;
+ }
+ else
+ {
+ buf = SDATA (object);
+ len = SBYTES (object);
+ }
+ send_process (proc, buf, len, object);
+
+ unbind_to (count, Qnil);
+}
+
DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,
3, 3, 0,
doc: /* Send current contents of region as input to PROCESS.
Lisp_Object process, start, end;
{
Lisp_Object proc;
- int start1, end1;
proc = get_process (process);
validate_region (&start, &end);
-
- if (XINT (start) < GPT && XINT (end) > GPT)
- move_gap (XINT (start));
-
- start1 = CHAR_TO_BYTE (XINT (start));
- end1 = CHAR_TO_BYTE (XINT (end));
- send_process (proc, BYTE_POS_ADDR (start1), end1 - start1,
- Fcurrent_buffer ());
-
+ send_process_object (proc, start, end);
return Qnil;
}
Lisp_Object proc;
CHECK_STRING (string);
proc = get_process (process);
- send_process (proc, SDATA (string),
- SBYTES (string), string);
+ send_process_object (proc, string, Qnil);
return Qnil;
}
\f
int gid = -1;
#ifdef TIOCGPGRP
- if (ioctl (XINT (p->infd), TIOCGPGRP, &gid) == -1 && ! NILP (p->tty_name))
+ if (ioctl (p->infd, TIOCGPGRP, &gid) == -1 && ! NILP (p->tty_name))
{
int fd;
/* Some OS:es (Solaris 8/9) does not allow TIOCGPGRP from the
if (!EQ (p->childp, Qt))
error ("Process %s is not a subprocess",
SDATA (p->name));
- if (XINT (p->infd) < 0)
+ if (p->infd < 0)
error ("Process %s is not active",
SDATA (p->name));
if (!EQ (p->childp, Qt))
error ("Process %s is not a subprocess",
SDATA (p->name));
- if (XINT (p->infd) < 0)
+ if (p->infd < 0)
error ("Process %s is not active",
SDATA (p->name));
- if (NILP (p->pty_flag))
+ if (!p->pty_flag)
current_group = Qnil;
/* If we are using pgrps, get a pgrp number and make it negative. */
struct termios t;
cc_t *sig_char = NULL;
- tcgetattr (XINT (p->infd), &t);
+ tcgetattr (p->infd, &t);
switch (signo)
{
switch (signo)
{
case SIGINT:
- ioctl (XINT (p->infd), TIOCGETC, &c);
+ ioctl (p->infd, TIOCGETC, &c);
send_process (proc, &c.t_intrc, 1, Qnil);
return;
case SIGQUIT:
- ioctl (XINT (p->infd), TIOCGETC, &c);
+ ioctl (p->infd, TIOCGETC, &c);
send_process (proc, &c.t_quitc, 1, Qnil);
return;
#ifdef SIGTSTP
case SIGTSTP:
- ioctl (XINT (p->infd), TIOCGLTC, &lc);
+ ioctl (p->infd, TIOCGLTC, &lc);
send_process (proc, &lc.t_suspc, 1, Qnil);
return;
#endif /* ! defined (SIGTSTP) */
switch (signo)
{
case SIGINT:
- ioctl (XINT (p->infd), TCGETA, &t);
+ ioctl (p->infd, TCGETA, &t);
send_process (proc, &t.c_cc[VINTR], 1, Qnil);
return;
case SIGQUIT:
- ioctl (XINT (p->infd), TCGETA, &t);
+ ioctl (p->infd, TCGETA, &t);
send_process (proc, &t.c_cc[VQUIT], 1, Qnil);
return;
#ifdef SIGTSTP
case SIGTSTP:
- ioctl (XINT (p->infd), TCGETA, &t);
+ ioctl (p->infd, TCGETA, &t);
send_process (proc, &t.c_cc[VSWTCH], 1, Qnil);
return;
#endif /* ! defined (SIGTSTP) */
case SIGCONT:
p->raw_status_new = 0;
p->status = Qrun;
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
if (!nomsg)
status_notify (NULL);
break;
sys$forcex (&(p->pid), 0, 1);
whoosh:
#endif
- flush_pending_output (XINT (p->infd));
+ flush_pending_output (p->infd);
break;
}
#ifdef TIOCSIGSEND
if (!NILP (current_group))
{
- if (ioctl (XINT (p->infd), TIOCSIGSEND, signo) == -1)
+ if (ioctl (p->infd, TIOCSIGSEND, signo) == -1)
EMACS_KILLPG (gid, signo);
}
else
p = XPROCESS (process);
if (NILP (p->command)
- && XINT (p->infd) >= 0)
+ && p->infd >= 0)
{
- FD_CLR (XINT (p->infd), &input_wait_mask);
- FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_CLR (p->infd, &input_wait_mask);
+ FD_CLR (p->infd, &non_keyboard_wait_mask);
}
p->command = Qt;
return process;
p = XPROCESS (process);
if (EQ (p->command, Qt)
- && XINT (p->infd) >= 0
+ && p->infd >= 0
&& (!EQ (p->filter, Qt) || EQ (p->status, Qlisten)))
{
- FD_SET (XINT (p->infd), &input_wait_mask);
- FD_SET (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_SET (p->infd, &input_wait_mask);
+ FD_SET (p->infd, &non_keyboard_wait_mask);
}
p->command = Qnil;
return process;
DEFUN ("signal-process", Fsignal_process, Ssignal_process,
2, 2, "sProcess (name or number): \nnSignal code: ",
doc: /* Send PROCESS the signal with code SIGCODE.
-PROCESS may also be an integer specifying the process id of the
+PROCESS may also be a number specifying the process id of the
process to signal; in this case, the process need not be a child of
this Emacs.
SIGCODE may be an integer, or a symbol whose name is a signal name. */)
if (FLOATP (process))
{
- pid = (pid_t) XFLOAT (process);
+ pid = (pid_t) XFLOAT_DATA (process);
goto got_it;
}
got_it:
-#define handle_signal(NAME, VALUE) \
- else if (!strcmp (name, NAME)) \
+#define parse_signal(NAME, VALUE) \
+ else if (!xstricmp (name, NAME)) \
XSETINT (sigcode, VALUE)
if (INTEGERP (sigcode))
CHECK_SYMBOL (sigcode);
name = SDATA (SYMBOL_NAME (sigcode));
- if (!strncmp(name, "SIG", 3))
+ if (!strncmp(name, "SIG", 3) || !strncmp(name, "sig", 3))
name += 3;
if (0)
;
+#ifdef SIGUSR1
+ parse_signal ("usr1", SIGUSR1);
+#endif
+#ifdef SIGUSR2
+ parse_signal ("usr2", SIGUSR2);
+#endif
+#ifdef SIGTERM
+ parse_signal ("term", SIGTERM);
+#endif
#ifdef SIGHUP
- handle_signal ("HUP", SIGHUP);
+ parse_signal ("hup", SIGHUP);
#endif
#ifdef SIGINT
- handle_signal ("INT", SIGINT);
+ parse_signal ("int", SIGINT);
#endif
#ifdef SIGQUIT
- handle_signal ("QUIT", SIGQUIT);
+ parse_signal ("quit", SIGQUIT);
#endif
#ifdef SIGILL
- handle_signal ("ILL", SIGILL);
+ parse_signal ("ill", SIGILL);
#endif
#ifdef SIGABRT
- handle_signal ("ABRT", SIGABRT);
+ parse_signal ("abrt", SIGABRT);
#endif
#ifdef SIGEMT
- handle_signal ("EMT", SIGEMT);
+ parse_signal ("emt", SIGEMT);
#endif
#ifdef SIGKILL
- handle_signal ("KILL", SIGKILL);
+ parse_signal ("kill", SIGKILL);
#endif
#ifdef SIGFPE
- handle_signal ("FPE", SIGFPE);
+ parse_signal ("fpe", SIGFPE);
#endif
#ifdef SIGBUS
- handle_signal ("BUS", SIGBUS);
+ parse_signal ("bus", SIGBUS);
#endif
#ifdef SIGSEGV
- handle_signal ("SEGV", SIGSEGV);
+ parse_signal ("segv", SIGSEGV);
#endif
#ifdef SIGSYS
- handle_signal ("SYS", SIGSYS);
+ parse_signal ("sys", SIGSYS);
#endif
#ifdef SIGPIPE
- handle_signal ("PIPE", SIGPIPE);
+ parse_signal ("pipe", SIGPIPE);
#endif
#ifdef SIGALRM
- handle_signal ("ALRM", SIGALRM);
-#endif
-#ifdef SIGTERM
- handle_signal ("TERM", SIGTERM);
+ parse_signal ("alrm", SIGALRM);
#endif
#ifdef SIGURG
- handle_signal ("URG", SIGURG);
+ parse_signal ("urg", SIGURG);
#endif
#ifdef SIGSTOP
- handle_signal ("STOP", SIGSTOP);
+ parse_signal ("stop", SIGSTOP);
#endif
#ifdef SIGTSTP
- handle_signal ("TSTP", SIGTSTP);
+ parse_signal ("tstp", SIGTSTP);
#endif
#ifdef SIGCONT
- handle_signal ("CONT", SIGCONT);
+ parse_signal ("cont", SIGCONT);
#endif
#ifdef SIGCHLD
- handle_signal ("CHLD", SIGCHLD);
+ parse_signal ("chld", SIGCHLD);
#endif
#ifdef SIGTTIN
- handle_signal ("TTIN", SIGTTIN);
+ parse_signal ("ttin", SIGTTIN);
#endif
#ifdef SIGTTOU
- handle_signal ("TTOU", SIGTTOU);
+ parse_signal ("ttou", SIGTTOU);
#endif
#ifdef SIGIO
- handle_signal ("IO", SIGIO);
+ parse_signal ("io", SIGIO);
#endif
#ifdef SIGXCPU
- handle_signal ("XCPU", SIGXCPU);
+ parse_signal ("xcpu", SIGXCPU);
#endif
#ifdef SIGXFSZ
- handle_signal ("XFSZ", SIGXFSZ);
+ parse_signal ("xfsz", SIGXFSZ);
#endif
#ifdef SIGVTALRM
- handle_signal ("VTALRM", SIGVTALRM);
+ parse_signal ("vtalrm", SIGVTALRM);
#endif
#ifdef SIGPROF
- handle_signal ("PROF", SIGPROF);
+ parse_signal ("prof", SIGPROF);
#endif
#ifdef SIGWINCH
- handle_signal ("WINCH", SIGWINCH);
+ parse_signal ("winch", SIGWINCH);
#endif
#ifdef SIGINFO
- handle_signal ("INFO", SIGINFO);
-#endif
-#ifdef SIGUSR1
- handle_signal ("USR1", SIGUSR1);
-#endif
-#ifdef SIGUSR2
- handle_signal ("USR2", SIGUSR2);
+ parse_signal ("info", SIGINFO);
#endif
else
error ("Undefined signal name %s", name);
}
-#undef handle_signal
+#undef parse_signal
return make_number (kill (pid, XINT (sigcode)));
}
return process;
proc = get_process (process);
- coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
+ coding = proc_encode_coding_system[XPROCESS (proc)->outfd];
/* Make sure the process is really alive. */
if (XPROCESS (proc)->raw_status_new)
#ifdef VMS
send_process (proc, "\032", 1, Qnil); /* ^z */
#else
- if (!NILP (XPROCESS (proc)->pty_flag))
+ if (XPROCESS (proc)->pty_flag)
send_process (proc, "\004", 1, Qnil);
else
{
(In some old system, shutdown to socketpair doesn't work.
Then we just can't win.) */
if (XPROCESS (proc)->pid == 0
- || XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd))
- shutdown (XINT (XPROCESS (proc)->outfd), 1);
+ || XPROCESS (proc)->outfd == XPROCESS (proc)->infd)
+ shutdown (XPROCESS (proc)->outfd, 1);
/* In case of socketpair, outfd == infd, so don't close it. */
- if (XINT (XPROCESS (proc)->outfd) != XINT (XPROCESS (proc)->infd))
- emacs_close (XINT (XPROCESS (proc)->outfd));
+ if (XPROCESS (proc)->outfd != XPROCESS (proc)->infd)
+ emacs_close (XPROCESS (proc)->outfd);
#else /* not HAVE_SHUTDOWN */
- emacs_close (XINT (XPROCESS (proc)->outfd));
+ emacs_close (XPROCESS (proc)->outfd);
#endif /* not HAVE_SHUTDOWN */
new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0);
if (new_outfd < 0)
abort ();
- old_outfd = XINT (XPROCESS (proc)->outfd);
+ old_outfd = XPROCESS (proc)->outfd;
if (!proc_encode_coding_system[new_outfd])
proc_encode_coding_system[new_outfd]
bzero (proc_encode_coding_system[old_outfd],
sizeof (struct coding_system));
- XSETINT (XPROCESS (proc)->outfd, new_outfd);
+ XPROCESS (proc)->outfd = new_outfd;
}
#endif /* VMS */
return process;
{
if (NETCONN_P (proc))
Fdelete_process (proc);
- else if (XINT (XPROCESS (proc)->infd) >= 0)
+ else if (XPROCESS (proc)->infd >= 0)
process_send_signal (proc, SIGHUP, Qnil, 1);
}
}
while (1)
{
- register int pid;
+ pid_t pid;
WAITTYPE w;
Lisp_Object tail;
#endif /* no WUNTRACED */
/* Keep trying to get a status until we get a definitive result. */
do
- {
+ {
errno = 0;
pid = wait3 (&w, WNOHANG | WUNTRACED, 0);
}
/* Find the process that signaled us, and record its status. */
/* The process can have been deleted by Fdelete_process. */
- tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list);
- if (!NILP (tail))
+ for (tail = deleted_pid_list; GC_CONSP (tail); tail = XCDR (tail))
{
- Fsetcar (tail, Qnil);
- goto sigchld_end_of_loop;
+ Lisp_Object xpid = XCAR (tail);
+ if ((GC_INTEGERP (xpid) && pid == (pid_t) XINT (xpid))
+ || (GC_FLOATP (xpid) && pid == (pid_t) XFLOAT_DATA (xpid)))
+ {
+ XSETCAR (tail, Qnil);
+ goto sigchld_end_of_loop;
+ }
}
/* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
union { int i; WAITTYPE wt; } u;
int clear_desc_flag = 0;
- XSETINT (p->tick, ++process_tick);
+ p->tick = ++process_tick;
u.wt = w;
p->raw_status = u.i;
p->raw_status_new = 1;
/* If process has terminated, stop waiting for its output. */
if ((WIFSIGNALED (w) || WIFEXITED (w))
- && XINT (p->infd) >= 0)
+ && p->infd >= 0)
clear_desc_flag = 1;
/* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */
if (clear_desc_flag)
{
- FD_CLR (XINT (p->infd), &input_wait_mask);
- FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
+ FD_CLR (p->infd, &input_wait_mask);
+ FD_CLR (p->infd, &non_keyboard_wait_mask);
}
/* Tell wait_reading_process_output that it needs to wake up and
proc = Fcdr (Fcar (tail));
p = XPROCESS (proc);
- if (XINT (p->tick) != XINT (p->update_tick))
+ if (p->tick != p->update_tick)
{
- XSETINT (p->update_tick, XINT (p->tick));
+ p->update_tick = p->tick;
/* If process is still active, read any output that remains. */
while (! EQ (p->filter, Qt)
&& ! EQ (p->status, Qconnect)
&& ! EQ (p->status, Qlisten)
&& ! EQ (p->command, Qt) /* Network process not stopped. */
- && XINT (p->infd) >= 0
+ && p->infd >= 0
&& p != deleting_process
- && read_process_output (proc, XINT (p->infd)) > 0);
+ && read_process_output (proc, p->infd) > 0);
buffer = p->buffer;
So set p->update_tick again
so that an error in the sentinel will not cause
this code to be run again. */
- XSETINT (p->update_tick, XINT (p->tick));
+ p->update_tick = p->tick;
/* Now output the message suitably. */
if (!NILP (p->sentinel))
exec_sentinel (proc, msg);
CHECK_PROCESS (process);
p = XPROCESS (process);
- if (XINT (p->infd) < 0)
+ if (p->infd < 0)
error ("Input file descriptor of %s closed", SDATA (p->name));
- if (XINT (p->outfd) < 0)
+ if (p->outfd < 0)
error ("Output file descriptor of %s closed", SDATA (p->name));
Fcheck_coding_system (decoding);
Fcheck_coding_system (encoding);
CHECK_PROCESS (process);
p = XPROCESS (process);
- p->filter_multibyte = flag;
+ p->filter_multibyte = !NILP (flag);
setup_process_coding_systems (process);
return Qnil;
CHECK_PROCESS (process);
p = XPROCESS (process);
- return (NILP (p->filter_multibyte) ? Qnil : Qt);
+ return (p->filter_multibyte ? Qt : Qnil);
}
\f
-/* The first time this is called, assume keyboard input comes from DESC
- instead of from where we used to expect it.
- Subsequent calls mean assume input keyboard can come from DESC
- in addition to other places. */
-
-static int add_keyboard_wait_descriptor_called_flag;
+/* Add DESC to the set of keyboard input descriptors. */
void
add_keyboard_wait_descriptor (desc)
int desc;
{
- if (! add_keyboard_wait_descriptor_called_flag)
- FD_CLR (0, &input_wait_mask);
- add_keyboard_wait_descriptor_called_flag = 1;
FD_SET (desc, &input_wait_mask);
FD_SET (desc, &non_process_wait_mask);
if (desc > max_keyboard_desc)
max_keyboard_desc = desc;
}
+static int add_gpm_wait_descriptor_called_flag;
+
+void
+add_gpm_wait_descriptor (desc)
+ int desc;
+{
+ if (! add_gpm_wait_descriptor_called_flag)
+ FD_CLR (0, &input_wait_mask);
+ add_gpm_wait_descriptor_called_flag = 1;
+ FD_SET (desc, &input_wait_mask);
+ FD_SET (desc, &gpm_wait_mask);
+ if (desc > max_gpm_desc)
+ max_gpm_desc = desc;
+}
+
/* From now on, do not expect DESC to give keyboard input. */
void
if (desc == max_keyboard_desc)
for (fd = 0; fd < lim; fd++)
if (FD_ISSET (fd, &input_wait_mask)
- && !FD_ISSET (fd, &non_keyboard_wait_mask))
+ && !FD_ISSET (fd, &non_keyboard_wait_mask)
+ && !FD_ISSET (fd, &gpm_wait_mask))
max_keyboard_desc = fd;
}
+void
+delete_gpm_wait_descriptor (desc)
+ int desc;
+{
+ int fd;
+ int lim = max_gpm_desc;
+
+ FD_CLR (desc, &input_wait_mask);
+ FD_CLR (desc, &non_process_wait_mask);
+
+ if (desc == max_gpm_desc)
+ for (fd = 0; fd < lim; fd++)
+ if (FD_ISSET (fd, &input_wait_mask)
+ && !FD_ISSET (fd, &non_keyboard_wait_mask)
+ && !FD_ISSET (fd, &non_process_wait_mask))
+ max_gpm_desc = fd;
+}
+
/* Return nonzero if *MASK has a bit set
that corresponds to one of the keyboard input descriptors. */
process_output_skip = 0;
#endif
+ /* Don't do this, it caused infinite select loops. The display
+ method should call add_keyboard_wait_descriptor on stdin if it
+ needs that. */
+#if 0
FD_SET (0, &input_wait_mask);
+#endif
Vprocess_alist = Qnil;
#ifdef SIGCHLD
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
doc: /* *Non-nil means delete processes immediately when they exit.
-nil means don't delete them until `list-processes' is run. */);
+A value of nil means don't delete them until `list-processes' is run. */);
delete_exited_processes = 1;