/* Work around GCC 4.7.0 bug with strict overflow checking; see
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
These lines can be removed once the GCC bug is fixed. */
-#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
# pragma GCC diagnostic ignored "-Wstrict-overflow"
#endif
Lisp_Object Quser, Qgroup, Qetime, Qpcpu, Qpmem, Qtime, Qctime;
Lisp_Object QCname, QCtype;
\f
-/* Non-zero if keyboard input is on hold, zero otherwise. */
+/* True if keyboard input is on hold, zero otherwise. */
-static int kbd_is_on_hold;
+static bool kbd_is_on_hold;
/* Nonzero means don't run process sentinels. This is used
when exiting. */
-int inhibit_sentinels;
+bool inhibit_sentinels;
#ifdef subprocesses
static Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
static Lisp_Object QCsentinel, QClog, QCoptions, QCplist;
static Lisp_Object Qlast_nonmenu_event;
+static Lisp_Object Qinternal_default_process_sentinel;
+static Lisp_Object Qinternal_default_process_filter;
#define NETCONN_P(p) (EQ (XPROCESS (p)->type, Qnetwork))
#define NETCONN1_P(p) (EQ (p->type, Qnetwork))
#define SERIALCONN_P(p) (EQ (XPROCESS (p)->type, Qserial))
#define SERIALCONN1_P(p) (EQ (p->type, Qserial))
-#ifndef HAVE_H_ERRNO
-extern int h_errno;
-#endif
-
/* Number of events of change of status of a process. */
static EMACS_INT process_tick;
/* Number of events for which the user or sentinel has been notified. */
static int process_output_delay_count;
-/* Non-zero if any process has non-nil read_output_skip. */
+/* True if any process has non-nil read_output_skip. */
-static int process_output_skip;
+static bool process_output_skip;
#else
#define process_output_delay_count 0
static void create_process (Lisp_Object, char **, Lisp_Object);
#ifdef USABLE_SIGIO
-static int keyboard_bit_set (SELECT_TYPE *);
+static bool keyboard_bit_set (SELECT_TYPE *);
#endif
static void deactivate_process (Lisp_Object);
static void status_notify (struct Lisp_Process *);
static void
pset_filter (struct Lisp_Process *p, Lisp_Object val)
{
- p->filter = val;
+ p->filter = NILP (val) ? Qinternal_default_process_filter : val;
}
static void
pset_log (struct Lisp_Process *p, Lisp_Object val)
static void
pset_sentinel (struct Lisp_Process *p, Lisp_Object val)
{
- p->sentinel = val;
+ p->sentinel = NILP (val) ? Qinternal_default_process_sentinel : val;
}
static void
pset_status (struct Lisp_Process *p, Lisp_Object val)
and store them individually through the three pointers. */
static void
-decode_status (Lisp_Object l, Lisp_Object *symbol, int *code, int *coredump)
+decode_status (Lisp_Object l, Lisp_Object *symbol, int *code, bool *coredump)
{
Lisp_Object tem;
{
Lisp_Object status = p->status;
Lisp_Object symbol;
- int code, coredump;
+ int code;
+ bool coredump;
Lisp_Object string, string2;
decode_status (status, &symbol, &code, &coredump);
}
name = name1;
pset_name (p, name);
+ pset_sentinel (p, Qinternal_default_process_sentinel);
+ pset_filter (p, Qinternal_default_process_filter);
XSETPROCESS (val, p);
Vprocess_alist = Fcons (Fcons (name, val), Vprocess_alist);
return val;
DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
2, 2, 0,
- doc: /* Give PROCESS the filter function FILTER; nil means no filter.
+ doc: /* Give PROCESS the filter function FILTER; nil means default.
A value of t means stop accepting output from the process.
-When a process has a filter, its buffer is not used for output.
+When a process has a non-default filter, its buffer is not used for output.
Instead, each time it does output, the entire string of output is
passed to the filter.
(debug)
(set-process-filter process ...) */
+ if (NILP (filter))
+ filter = Qinternal_default_process_filter;
+
if (p->infd >= 0)
{
if (EQ (filter, Qt) && !EQ (p->status, Qlisten))
DEFUN ("process-filter", Fprocess_filter, Sprocess_filter,
1, 1, 0,
- doc: /* Returns the filter function of PROCESS; nil if none.
+ doc: /* Return the filter function of PROCESS.
See `set-process-filter' for more info on filter functions. */)
(register Lisp_Object process)
{
DEFUN ("set-process-sentinel", Fset_process_sentinel, Sset_process_sentinel,
2, 2, 0,
- doc: /* Give PROCESS the sentinel SENTINEL; nil for none.
+ doc: /* Give PROCESS the sentinel SENTINEL; nil for default.
The sentinel is called as a function when the process changes state.
It gets two arguments: the process, and a string describing the change. */)
(register Lisp_Object process, Lisp_Object sentinel)
CHECK_PROCESS (process);
p = XPROCESS (process);
+ if (NILP (sentinel))
+ sentinel = Qinternal_default_process_sentinel;
+
pset_sentinel (p, sentinel);
if (NETCONN1_P (p) || SERIALCONN1_P (p))
pset_childp (p, Fplist_put (p->childp, QCsentinel, sentinel));
DEFUN ("process-sentinel", Fprocess_sentinel, Sprocess_sentinel,
1, 1, 0,
- doc: /* Return the sentinel of PROCESS; nil if none.
+ doc: /* Return the sentinel of PROCESS.
See `set-process-sentinel' for more info on sentinels. */)
(register Lisp_Object process)
{
pset_plist (XPROCESS (proc), Qnil);
pset_type (XPROCESS (proc), Qreal);
pset_buffer (XPROCESS (proc), buffer);
- pset_sentinel (XPROCESS (proc), Qnil);
- pset_filter (XPROCESS (proc), Qnil);
+ pset_sentinel (XPROCESS (proc), Qinternal_default_process_sentinel);
+ pset_filter (XPROCESS (proc), Qinternal_default_process_filter);
pset_command (XPROCESS (proc), Flist (nargs - 2, args + 2));
#ifdef HAVE_GNUTLS
sigset_t blocked;
/* Use volatile to protect variables from being clobbered by vfork. */
volatile int forkin, forkout;
- volatile int pty_flag = 0;
+ volatile bool pty_flag = 0;
volatile Lisp_Object lisp_pty_name = Qnil;
volatile Lisp_Object encoded_current_dir;
/* Back in the parent process. */
XPROCESS (process)->pid = pid;
- if (0 <= pid)
+ if (pid >= 0)
XPROCESS (process)->alive = 1;
/* Stop blocking signals in the parent. */
create_pty (Lisp_Object process)
{
int inchannel, outchannel;
- int pty_flag = 0;
+ bool pty_flag = 0;
inchannel = outchannel = -1;
channel = XPROCESS (process)->infd;
len = get_lisp_to_sockaddr_size (address, &family);
- if (datagram_address[channel].len != len)
+ if (len == 0 || datagram_address[channel].len != len)
return Qnil;
conv_lisp_to_sockaddr (family, address, datagram_address[channel].sa, len);
return address;
Lisp_Object tem;
Lisp_Object name, buffer, host, service, address;
Lisp_Object filter, sentinel;
- int is_non_blocking_client = 0;
- int is_server = 0, backlog = 5;
+ bool is_non_blocking_client = 0;
+ bool is_server = 0;
+ int backlog = 5;
int socktype;
int family = -1;
{
int rfamily, rlen;
rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
- if (rfamily == lres->ai_family && rlen == lres->ai_addrlen)
+ if (rlen != 0 && rfamily == lres->ai_family
+ && rlen == lres->ai_addrlen)
conv_lisp_to_sockaddr (rfamily, remote,
datagram_address[s].sa, rlen);
}
struct ifreq *ifreq;
void *buf = NULL;
ptrdiff_t buf_size = 512;
- int s, i;
+ int s;
Lisp_Object res;
s = socket (AF_INET, SOCK_STREAM, 0);
int len = sizeof (*ifreq);
#endif
char namebuf[sizeof (ifq->ifr_name) + 1];
- i += len;
ifreq = (struct ifreq *) ((char *) ifreq + len);
if (ifq->ifr_addr.sa_family != AF_INET)
Lisp_Object res = Qnil;
Lisp_Object elt;
int s;
- int any = 0;
+ bool any = 0;
#if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \
&& defined HAVE_GETIFADDRS && defined LLADDR)
struct ifaddrs *ifap;
{
if (INTEGERP (seconds))
{
- if (0 < XINT (seconds))
+ if (XINT (seconds) > 0)
{
secs = XINT (seconds);
nsecs = 0;
}
else if (FLOATP (seconds))
{
- if (0 < XFLOAT_DATA (seconds))
+ if (XFLOAT_DATA (seconds) > 0)
{
EMACS_TIME t = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (seconds));
secs = min (EMACS_SECS (t), WAIT_READING_MAX);
/* Accept a connection for server process SERVER on CHANNEL. */
-static int connect_counter = 0;
+static EMACS_INT connect_counter = 0;
static void
server_accept_connection (Lisp_Object server, int channel)
process name of the server process concatenated with the caller
identification. */
- if (!NILP (ps->filter) && !EQ (ps->filter, Qt))
+ if (!(EQ (ps->filter, Qinternal_default_process_filter)
+ || EQ (ps->filter, Qt)))
buffer = Qnil;
else
{
/* Setup coding system for new process based on server process.
This seems to be the proper thing to do, as the coding system
of the new process should reflect the settings at the time the
- server socket was opened; not the current settings. */
+ server socket was opened; not the current settings. */
pset_decode_coding_system (p, ps->decode_coding_system);
pset_encode_coding_system (p, ps->encode_coding_system);
(STRINGP (host) ? host : build_string ("-")),
build_string ("\n")));
- if (!NILP (p->sentinel))
- exec_sentinel (proc,
- concat3 (build_string ("open from "),
- (STRINGP (host) ? host : build_string ("-")),
- build_string ("\n")));
+ exec_sentinel (proc,
+ concat3 (build_string ("open from "),
+ (STRINGP (host) ? host : build_string ("-")),
+ build_string ("\n")));
}
/* This variable is different from waiting_for_input in keyboard.c.
process. The return value is true if we read some input from
that process.
- If JUST_WAIT_PROC is non-nil, handle only output from WAIT_PROC
+ If JUST_WAIT_PROC is nonzero, handle only output from WAIT_PROC
(suspending output from other processes). A negative value
means don't run any timers either.
received input from that process before the timeout elapsed.
Otherwise, return true if we received input from any process. */
-int
+bool
wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
bool do_display,
Lisp_Object wait_for_cell,
struct Lisp_Process *wait_proc, int just_wait_proc)
{
- register int channel, nfds;
+ int channel, nfds;
SELECT_TYPE Available;
SELECT_TYPE Writeok;
- int check_write;
- int check_delay, no_avail;
+ bool check_write;
+ int check_delay;
+ bool no_avail;
int xerrno;
Lisp_Object proc;
EMACS_TIME timeout, end_time;
int wait_channel = -1;
- int got_some_input = 0;
+ bool got_some_input = 0;
ptrdiff_t count = SPECPDL_INDEX ();
FD_ZERO (&Available);
if (time_limit == 0 && nsecs == 0 && wait_proc && !NILP (Vinhibit_quit)
&& !(CONSP (wait_proc->status)
&& EQ (XCAR (wait_proc->status), Qexit)))
- message ("Blocking call to accept-process-output with quit inhibited!!");
+ message1 ("Blocking call to accept-process-output with quit inhibited!!");
/* If wait_proc is a process to watch, set wait_channel accordingly. */
if (wait_proc != NULL)
/* Since we may need to wait several times,
compute the absolute time to return at. */
- if (time_limit || 0 < nsecs)
+ if (time_limit || nsecs > 0)
{
timeout = make_emacs_time (time_limit, nsecs);
end_time = add_emacs_time (current_emacs_time (), timeout);
while (1)
{
- int timeout_reduced_for_timers = 0;
+ bool timeout_reduced_for_timers = 0;
/* If calling from keyboard input, do not quit
since we want to return C-g as an input character.
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
+ /* Compute time from now till when time limit is up. */
+ /* Exit if already run out. */
if (nsecs < 0)
{
/* A negative timeout means
timeout = make_emacs_time (0, 0);
}
- else if (time_limit || 0 < nsecs)
+ else if (time_limit || nsecs > 0)
{
EMACS_TIME now = current_emacs_time ();
if (EMACS_TIME_LE (end_time, now))
break;
/* A negative timeout means do not wait at all. */
- if (0 <= nsecs)
+ if (nsecs >= 0)
{
if (EMACS_TIME_VALID_P (timer_delay))
{
if (nread == 0)
break;
- if (0 < nread)
+ if (nread > 0)
{
total_nread += nread;
got_some_input = 1;
}
#endif
-#if defined (USE_GTK) || defined (HAVE_GCONF) || defined (HAVE_GSETTINGS)
- nfds = xg_select
-#elif defined (HAVE_NS)
- nfds = ns_select
+#if defined (HAVE_NS)
+ nfds = ns_select
+#elif defined (HAVE_GLIB)
+ nfds = xg_select
#else
nfds = pselect
#endif
unsigned old_timers_run = timers_run;
struct buffer *old_buffer = current_buffer;
Lisp_Object old_window = selected_window;
- int leave = 0;
+ bool leave = 0;
if (detect_input_pending_run_timers (do_display))
{
}
}
#endif /* NON_BLOCKING_CONNECT */
- } /* end for each file descriptor */
- } /* end while exit conditions not met */
+ } /* End for each file descriptor. */
+ } /* End while exit conditions not met. */
unbind_to (count, Qnil);
return Qt;
}
+static void
+read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
+ ssize_t nbytes,
+ struct coding_system *coding);
+
/* Read pending output from the process channel,
starting with our buffered-ahead character if we have one.
Yield number of decoded characters read.
{
register ssize_t nbytes;
char *chars;
- register Lisp_Object outstream;
register struct Lisp_Process *p = XPROCESS (proc);
- register ptrdiff_t opoint;
struct coding_system *coding = proc_decode_coding_system[channel];
int carryover = p->decoding_carryover;
int readmax = 4096;
else
#endif
{
- int buffered = 0 <= proc_buffered_char[channel];
+ bool buffered = proc_buffered_char[channel] >= 0;
if (buffered)
{
chars[carryover] = proc_buffered_char[channel];
friends don't expect current-buffer to be changed from under them. */
record_unwind_current_buffer ();
- /* Read and dispose of the process output. */
- outstream = p->filter;
- if (!NILP (outstream))
- {
- Lisp_Object text;
- bool outer_running_asynch_code = running_asynch_code;
- int waiting = waiting_for_user_input_p;
+ read_and_dispose_of_process_output (p, chars, nbytes, coding);
+
+ /* Handling the process output should not deactivate the mark. */
+ Vdeactivate_mark = odeactivate;
+
+ unbind_to (count, Qnil);
+ return nbytes;
+}
+
+static void
+read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
+ ssize_t nbytes,
+ struct coding_system *coding)
+{
+ Lisp_Object outstream = p->filter;
+ Lisp_Object text;
+ bool outer_running_asynch_code = running_asynch_code;
+ int waiting = waiting_for_user_input_p;
- /* No need to gcpro these, because all we do with them later
- is test them for EQness, and none of them should be a string. */
+ /* No need to gcpro these, because all we do with them later
+ is test them for EQness, and none of them should be a string. */
#if 0
- Lisp_Object obuffer, okeymap;
- XSETBUFFER (obuffer, current_buffer);
- okeymap = BVAR (current_buffer, keymap);
+ Lisp_Object obuffer, okeymap;
+ XSETBUFFER (obuffer, current_buffer);
+ okeymap = BVAR (current_buffer, keymap);
#endif
- /* We inhibit quit here instead of just catching it so that
- hitting ^G when a filter happens to be running won't screw
- it up. */
- specbind (Qinhibit_quit, Qt);
- specbind (Qlast_nonmenu_event, Qt);
-
- /* In case we get recursively called,
- and we already saved the match data nonrecursively,
- save the same match data in safely recursive fashion. */
- if (outer_running_asynch_code)
- {
- Lisp_Object tem;
- /* Don't clobber the CURRENT match data, either! */
- tem = Fmatch_data (Qnil, Qnil, Qnil);
- restore_search_regs ();
- record_unwind_save_match_data ();
- Fset_match_data (tem, Qt);
- }
+ /* We inhibit quit here instead of just catching it so that
+ hitting ^G when a filter happens to be running won't screw
+ it up. */
+ specbind (Qinhibit_quit, Qt);
+ specbind (Qlast_nonmenu_event, Qt);
- /* For speed, if a search happens within this code,
- save the match data in a special nonrecursive fashion. */
- running_asynch_code = 1;
+ /* In case we get recursively called,
+ and we already saved the match data nonrecursively,
+ save the same match data in safely recursive fashion. */
+ if (outer_running_asynch_code)
+ {
+ Lisp_Object tem;
+ /* Don't clobber the CURRENT match data, either! */
+ tem = Fmatch_data (Qnil, Qnil, Qnil);
+ restore_search_regs ();
+ record_unwind_save_match_data ();
+ Fset_match_data (tem, Qt);
+ }
- decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
- text = coding->dst_object;
- Vlast_coding_system_used = CODING_ID_NAME (coding->id);
- /* A new coding system might be found. */
- if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
- {
- pset_decode_coding_system (p, Vlast_coding_system_used);
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
+ running_asynch_code = 1;
- /* Don't call setup_coding_system for
- proc_decode_coding_system[channel] here. It is done in
- detect_coding called via decode_coding above. */
+ decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
+ text = coding->dst_object;
+ Vlast_coding_system_used = CODING_ID_NAME (coding->id);
+ /* A new coding system might be found. */
+ if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
+ {
+ pset_decode_coding_system (p, Vlast_coding_system_used);
- /* If a coding system for encoding is not yet decided, we set
- it as the same as coding-system for decoding.
+ /* Don't call setup_coding_system for
+ proc_decode_coding_system[channel] here. It is done in
+ detect_coding called via decode_coding above. */
- But, before doing that we must check if
- proc_encode_coding_system[p->outfd] surely points to a
- 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[p->outfd])
- {
- pset_encode_coding_system
- (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[p->outfd]);
- }
- }
+ /* If a coding system for encoding is not yet decided, we set
+ it as the same as coding-system for decoding.
- if (coding->carryover_bytes > 0)
+ But, before doing that we must check if
+ proc_encode_coding_system[p->outfd] surely points to a
+ 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[p->outfd])
{
- if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
- pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
- memcpy (SDATA (p->decoding_buf), coding->carryover,
- coding->carryover_bytes);
- p->decoding_carryover = coding->carryover_bytes;
+ pset_encode_coding_system
+ (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
+ setup_coding_system (p->encode_coding_system,
+ proc_encode_coding_system[p->outfd]);
}
- if (SBYTES (text) > 0)
- /* FIXME: It's wrong to wrap or not based on debug-on-error, and
- sometimes it's simply wrong to wrap (e.g. when called from
- accept-process-output). */
- internal_condition_case_1 (read_process_output_call,
- Fcons (outstream,
- Fcons (proc, Fcons (text, Qnil))),
- !NILP (Vdebug_on_error) ? Qnil : Qerror,
- read_process_output_error_handler);
-
- /* If we saved the match data nonrecursively, restore it now. */
- restore_search_regs ();
- running_asynch_code = outer_running_asynch_code;
+ }
+
+ if (coding->carryover_bytes > 0)
+ {
+ if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
+ pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
+ memcpy (SDATA (p->decoding_buf), coding->carryover,
+ coding->carryover_bytes);
+ p->decoding_carryover = coding->carryover_bytes;
+ }
+ if (SBYTES (text) > 0)
+ /* FIXME: It's wrong to wrap or not based on debug-on-error, and
+ sometimes it's simply wrong to wrap (e.g. when called from
+ accept-process-output). */
+ internal_condition_case_1 (read_process_output_call,
+ Fcons (outstream,
+ Fcons (make_lisp_proc (p),
+ Fcons (text, Qnil))),
+ !NILP (Vdebug_on_error) ? Qnil : Qerror,
+ read_process_output_error_handler);
- /* Restore waiting_for_user_input_p as it was
- when we were called, in case the filter clobbered it. */
- waiting_for_user_input_p = waiting;
+ /* If we saved the match data nonrecursively, restore it now. */
+ restore_search_regs ();
+ running_asynch_code = outer_running_asynch_code;
+
+ /* Restore waiting_for_user_input_p as it was
+ when we were called, in case the filter clobbered it. */
+ waiting_for_user_input_p = waiting;
#if 0 /* Call record_asynch_buffer_change unconditionally,
because we might have changed minor modes or other things
that affect key bindings. */
- if (! EQ (Fcurrent_buffer (), obuffer)
- || ! EQ (current_buffer->keymap, okeymap))
-#endif
- /* But do it only if the caller is actually going to read events.
- Otherwise there's no need to make him wake up, and it could
- cause trouble (for example it would make sit_for return). */
- if (waiting_for_user_input_p == -1)
- record_asynch_buffer_change ();
- }
+ if (! EQ (Fcurrent_buffer (), obuffer)
+ || ! EQ (current_buffer->keymap, okeymap))
+#endif
+ /* But do it only if the caller is actually going to read events.
+ Otherwise there's no need to make him wake up, and it could
+ cause trouble (for example it would make sit_for return). */
+ if (waiting_for_user_input_p == -1)
+ record_asynch_buffer_change ();
+}
- /* If no filter, write into buffer if it isn't dead. */
- else if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+DEFUN ("internal-default-process-filter", Finternal_default_process_filter,
+ Sinternal_default_process_filter, 2, 2, 0,
+ doc: /* Function used as default process filter. */)
+ (Lisp_Object proc, Lisp_Object text)
+{
+ struct Lisp_Process *p;
+ ptrdiff_t opoint;
+
+ CHECK_PROCESS (proc);
+ p = XPROCESS (proc);
+ CHECK_STRING (text);
+
+ if (!NILP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
{
Lisp_Object old_read_only;
ptrdiff_t old_begv, old_zv;
ptrdiff_t old_begv_byte, old_zv_byte;
ptrdiff_t before, before_byte;
ptrdiff_t opoint_byte;
- Lisp_Object text;
struct buffer *b;
Fset_buffer (p->buffer);
if (! (BEGV <= PT && PT <= ZV))
Fwiden ();
- decode_coding_c_string (coding, (unsigned char *) chars, nbytes, Qt);
- text = coding->dst_object;
- Vlast_coding_system_used = CODING_ID_NAME (coding->id);
- /* A new coding system might be found. See the comment in the
- similar code in the previous `if' block. */
- if (!EQ (p->decode_coding_system, Vlast_coding_system_used))
- {
- pset_decode_coding_system (p, Vlast_coding_system_used);
- if (NILP (p->encode_coding_system)
- && proc_encode_coding_system[p->outfd])
- {
- pset_encode_coding_system
- (p, coding_inherit_eol_type (Vlast_coding_system_used, Qnil));
- setup_coding_system (p->encode_coding_system,
- proc_encode_coding_system[p->outfd]);
- }
- }
- if (coding->carryover_bytes > 0)
- {
- if (SCHARS (p->decoding_buf) < coding->carryover_bytes)
- pset_decoding_buf (p, make_uninit_string (coding->carryover_bytes));
- memcpy (SDATA (p->decoding_buf), coding->carryover,
- coding->carryover_bytes);
- p->decoding_carryover = coding->carryover_bytes;
- }
/* Adjust the multibyteness of TEXT to that of the buffer. */
if (NILP (BVAR (current_buffer, enable_multibyte_characters))
!= ! STRING_MULTIBYTE (text))
if (old_begv != BEGV || old_zv != ZV)
Fnarrow_to_region (make_number (old_begv), make_number (old_zv));
-
bset_read_only (current_buffer, old_read_only);
SET_PT_BOTH (opoint, opoint_byte);
}
- /* Handling the process output should not deactivate the mark. */
- Vdeactivate_mark = odeactivate;
-
- unbind_to (count, Qnil);
- return nbytes;
+ return Qnil;
}
\f
-/* Sending data to subprocess */
+/* Sending data to subprocess. */
/* In send_process, when a write fails temporarily,
wait_reading_process_output is called. It may execute user code,
static void
write_queue_push (struct Lisp_Process *p, Lisp_Object input_obj,
- const char *buf, ptrdiff_t len, int front)
+ const char *buf, ptrdiff_t len, bool front)
{
ptrdiff_t offset;
Lisp_Object entry, obj;
}
/* Remove the first element in the write_queue of process P, put its
- contents in OBJ, BUF and LEN, and return non-zero. If the
- write_queue is empty, return zero. */
+ contents in OBJ, BUF and LEN, and return true. If the
+ write_queue is empty, return false. */
-static int
+static bool
write_queue_pop (struct Lisp_Process *p, Lisp_Object *obj,
const char **buf, ptrdiff_t *len)
{
rv = sendto (outfd, cur_buf, cur_len,
0, datagram_address[outfd].sa,
datagram_address[outfd].len);
- if (0 <= rv)
+ if (rv >= 0)
written = rv;
else if (errno == EMSGSIZE)
report_file_error ("sending datagram", Fcons (proc, Qnil));
if (XINT (start) < GPT && XINT (end) > GPT)
move_gap_both (XINT (start), start_byte);
- send_process (proc, (char *) BYTE_POS_ADDR (start_byte),
+ send_process (proc, (char *) BYTE_POS_ADDR (start_byte),
end_byte - start_byte, Fcurrent_buffer ());
return Qnil;
If CURRENT_GROUP is lambda, that means send to the process group
that currently owns the terminal, but only if it is NOT the shell itself.
- If NOMSG is zero, insert signal-announcements into process's buffers
+ If NOMSG is false, insert signal-announcements into process's buffers
right away.
If we can, we try to signal PROCESS by sending control characters
static void
process_send_signal (Lisp_Object process, int signo, Lisp_Object current_group,
- int nomsg)
+ bool nomsg)
{
Lisp_Object proc;
- register struct Lisp_Process *p;
+ struct Lisp_Process *p;
pid_t gid;
- int no_pgrp = 0;
+ bool no_pgrp = 0;
proc = get_process (process);
p = XPROCESS (proc);
might inadvertently reap a GTK-created process that happened to
have the same process ID. */
+/* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing
+ its own SIGCHLD handling. On POSIXish systems, glib needs this to
+ keep track of its own children. The default handler does nothing. */
+static void dummy_handler (int sig) {}
+static signal_handler_t volatile lib_child_handler = dummy_handler;
+
/* Handle a SIGCHLD signal by looking for known child processes of
Emacs whose status have changed. For each one found, record its
new status.
struct Lisp_Process *p = XPROCESS (proc);
int status;
- if (p->alive && child_status_changed (p->pid, &status, WUNTRACED))
+ if (p->alive
+ && child_status_changed (p->pid, &status, WUNTRACED | WCONTINUED))
{
/* Change the status of the process that was found. */
p->tick = ++process_tick;
/* If process has terminated, stop waiting for its output. */
if (WIFSIGNALED (status) || WIFEXITED (status))
{
- int clear_desc_flag = 0;
+ bool clear_desc_flag = 0;
p->alive = 0;
if (p->infd >= 0)
clear_desc_flag = 1;
}
}
}
+
+ lib_child_handler (sig);
}
static void
}
\f
-static Lisp_Object
-exec_sentinel_unwind (Lisp_Object data)
-{
- pset_sentinel (XPROCESS (XCAR (data)), XCDR (data));
- return Qnil;
-}
-
static Lisp_Object
exec_sentinel_error_handler (Lisp_Object error_val)
{
record_unwind_current_buffer ();
sentinel = p->sentinel;
- if (NILP (sentinel))
- return;
- /* Zilch the sentinel while it's running, to avoid recursive invocations;
- assure that it gets restored no matter how the sentinel exits. */
- pset_sentinel (p, Qnil);
- record_unwind_protect (exec_sentinel_unwind, Fcons (proc, sentinel));
/* Inhibit quit so that random quits don't screw up a running filter. */
specbind (Qinhibit_quit, Qt);
specbind (Qlast_nonmenu_event, Qt); /* Why? --Stef */
static void
status_notify (struct Lisp_Process *deleting_process)
{
- register Lisp_Object proc, buffer;
+ register Lisp_Object proc;
Lisp_Object tail, msg;
struct gcpro gcpro1, gcpro2;
&& p != deleting_process
&& read_process_output (proc, p->infd) > 0);
- buffer = p->buffer;
-
/* Get the text to use for the message. */
if (p->raw_status_new)
update_status (p);
}
/* The actions above may have further incremented p->tick.
- So set p->update_tick again
- so that an error in the sentinel will not cause
- this code to be run again. */
+ So set p->update_tick again so that an error in the sentinel will
+ not cause this code to be run again. */
p->update_tick = p->tick;
/* Now output the message suitably. */
- if (!NILP (p->sentinel))
- exec_sentinel (proc, msg);
- /* Don't bother with a message in the buffer
- when a process becomes runnable. */
- else if (!EQ (symbol, Qrun) && !NILP (buffer))
- {
- Lisp_Object tem;
- struct buffer *old = current_buffer;
- ptrdiff_t opoint, opoint_byte;
- ptrdiff_t before, before_byte;
-
- /* Avoid error if buffer is deleted
- (probably that's why the process is dead, too) */
- if (!BUFFER_LIVE_P (XBUFFER (buffer)))
- continue;
- Fset_buffer (buffer);
-
- opoint = PT;
- opoint_byte = PT_BYTE;
- /* Insert new output into buffer
- at the current end-of-output marker,
- thus preserving logical ordering of input and output. */
- if (XMARKER (p->mark)->buffer)
- Fgoto_char (p->mark);
- else
- SET_PT_BOTH (ZV, ZV_BYTE);
-
- before = PT;
- before_byte = PT_BYTE;
-
- tem = BVAR (current_buffer, read_only);
- bset_read_only (current_buffer, Qnil);
- insert_string ("\nProcess ");
- { /* FIXME: temporary kludge */
- Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
- insert_string (" ");
- Finsert (1, &msg);
- bset_read_only (current_buffer, tem);
- set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
-
- if (opoint >= before)
- SET_PT_BOTH (opoint + (PT - before),
- opoint_byte + (PT_BYTE - before_byte));
- else
- SET_PT_BOTH (opoint, opoint_byte);
-
- set_buffer_internal (old);
- }
+ exec_sentinel (proc, msg);
}
} /* end for */
- update_mode_lines++; /* in case buffers use %s in mode-line-format */
+ update_mode_lines++; /* In case buffers use %s in mode-line-format. */
UNGCPRO;
}
+DEFUN ("internal-default-process-sentinel", Finternal_default_process_sentinel,
+ Sinternal_default_process_sentinel, 2, 2, 0,
+ doc: /* Function used as default sentinel for processes. */)
+ (Lisp_Object proc, Lisp_Object msg)
+{
+ Lisp_Object buffer, symbol;
+ struct Lisp_Process *p;
+ CHECK_PROCESS (proc);
+ p = XPROCESS (proc);
+ buffer = p->buffer;
+ symbol = p->status;
+ if (CONSP (symbol))
+ symbol = XCAR (symbol);
+
+ if (!EQ (symbol, Qrun) && !NILP (buffer))
+ {
+ Lisp_Object tem;
+ struct buffer *old = current_buffer;
+ ptrdiff_t opoint, opoint_byte;
+ ptrdiff_t before, before_byte;
+
+ /* Avoid error if buffer is deleted
+ (probably that's why the process is dead, too). */
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
+ return Qnil;
+ Fset_buffer (buffer);
+
+ if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
+ msg = (code_convert_string_norecord
+ (msg, Vlocale_coding_system, 1));
+
+ opoint = PT;
+ opoint_byte = PT_BYTE;
+ /* Insert new output into buffer
+ at the current end-of-output marker,
+ thus preserving logical ordering of input and output. */
+ if (XMARKER (p->mark)->buffer)
+ Fgoto_char (p->mark);
+ else
+ SET_PT_BOTH (ZV, ZV_BYTE);
+
+ before = PT;
+ before_byte = PT_BYTE;
+
+ tem = BVAR (current_buffer, read_only);
+ bset_read_only (current_buffer, Qnil);
+ insert_string ("\nProcess ");
+ { /* FIXME: temporary kludge. */
+ Lisp_Object tem2 = p->name; Finsert (1, &tem2); }
+ insert_string (" ");
+ Finsert (1, &msg);
+ bset_read_only (current_buffer, tem);
+ set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
+
+ if (opoint >= before)
+ SET_PT_BOTH (opoint + (PT - before),
+ opoint_byte + (PT_BYTE - before_byte));
+ else
+ SET_PT_BOTH (opoint, opoint_byte);
+
+ set_buffer_internal (old);
+ }
+ return Qnil;
+}
+
\f
DEFUN ("set-process-coding-system", Fset_process_coding_system,
Sset_process_coding_system, 1, 3, 0,
# ifdef USABLE_SIGIO
-/* Return nonzero if *MASK has a bit set
+/* Return true if *MASK has a bit set
that corresponds to one of the keyboard input descriptors. */
-static int
+static bool
keyboard_bit_set (fd_set *mask)
{
int fd;
Return true if we received input from any process. */
-int
+bool
wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
bool do_display,
Lisp_Object wait_for_cell,
time_limit = TYPE_MAXIMUM (time_t);
/* What does time_limit really mean? */
- if (time_limit || 0 < nsecs)
+ if (time_limit || nsecs > 0)
{
timeout = make_emacs_time (time_limit, nsecs);
end_time = add_emacs_time (current_emacs_time (), timeout);
while (1)
{
- int timeout_reduced_for_timers = 0;
+ bool timeout_reduced_for_timers = 0;
SELECT_TYPE waitchannels;
int xerrno;
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
break;
- /* Compute time from now till when time limit is up */
- /* Exit if already run out */
+ /* Compute time from now till when time limit is up. */
+ /* Exit if already run out. */
if (nsecs < 0)
{
/* A negative timeout means
gobble output available now
- but don't wait at all. */
+ but don't wait at all. */
timeout = make_emacs_time (0, 0);
}
- else if (time_limit || 0 < nsecs)
+ else if (time_limit || nsecs > 0)
{
EMACS_TIME now = current_emacs_time ();
if (EMACS_TIME_LE (end_time, now))
&& requeued_events_pending_p ())
break;
- if (EMACS_TIME_VALID_P (timer_delay) && 0 <= nsecs)
+ if (EMACS_TIME_VALID_P (timer_delay) && nsecs >= 0)
{
if (EMACS_TIME_LT (timer_delay, timeout))
{
if (!proc_decode_coding_system[inch])
proc_decode_coding_system[inch] = xmalloc (sizeof (struct coding_system));
coding_system = p->decode_coding_system;
- if (! NILP (p->filter))
- ;
- else if (BUFFERP (p->buffer))
+ if (EQ (p->filter, Qinternal_default_process_filter)
+ && BUFFERP (p->buffer))
{
if (NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
coding_system = raw_text_coding_system (coding_system);
DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p,
Swaiting_for_user_input_p, 0, 0, 0,
- doc: /* Returns non-nil if Emacs is waiting for input from the user.
+ doc: /* Return non-nil if Emacs is waiting for input from the user.
This is intended for use by asynchronous process output filters and sentinels. */)
(void)
{
kbd_is_on_hold = 0;
}
-/* Return non-zero if keyboard input is on hold, zero otherwise. */
+/* Return true if keyboard input is on hold, zero otherwise. */
-int
+bool
kbd_on_hold_p (void)
{
return kbd_is_on_hold;
return system_process_attributes (pid);
}
+#ifndef NS_IMPL_GNUSTEP
+static
+#endif
+void
+catch_child_signal (void)
+{
+ struct sigaction action, old_action;
+ emacs_sigaction_init (&action, deliver_child_signal);
+ sigaction (SIGCHLD, &action, &old_action);
+ eassert (! (old_action.sa_flags & SA_SIGINFO));
+ if (old_action.sa_handler != SIG_DFL && old_action.sa_handler != SIG_IGN
+ && old_action.sa_handler != deliver_child_signal)
+ lib_child_handler = old_action.sa_handler;
+}
+
\f
/* This is not called "init_process" because that is the name of a
Mach system call, so it would cause problems on Darwin systems. */
if (! noninteractive || initialized)
#endif
{
- struct sigaction action;
- emacs_sigaction_init (&action, deliver_child_signal);
- sigaction (SIGCHLD, &action, 0);
+#if defined HAVE_GLIB && !defined WINDOWSNT
+ /* Tickle glib's child-handling code so that it initializes its
+ private SIGCHLD handler. */
+ g_source_unref (g_child_watch_source_new (0));
+#endif
+ catch_child_signal ();
}
FD_ZERO (&input_wait_mask);
DEFSYM (Qcutime, "cutime");
DEFSYM (Qcstime, "cstime");
DEFSYM (Qctime, "ctime");
+ DEFSYM (Qinternal_default_process_sentinel,
+ "internal-default-process-sentinel");
+ DEFSYM (Qinternal_default_process_filter,
+ "internal-default-process-filter");
DEFSYM (Qpri, "pri");
DEFSYM (Qnice, "nice");
DEFSYM (Qthcount, "thcount");
defsubr (&Ssignal_process);
defsubr (&Swaiting_for_user_input_p);
defsubr (&Sprocess_type);
+ defsubr (&Sinternal_default_process_sentinel);
+ defsubr (&Sinternal_default_process_filter);
defsubr (&Sset_process_coding_system);
defsubr (&Sprocess_coding_system);
defsubr (&Sset_process_filter_multibyte);