/* Asynchronous subprocess control for GNU Emacs.
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 1998
+ Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 98, 1999
Free Software Foundation, Inc.
This file is part of GNU Emacs.
Boston, MA 02111-1307, USA. */
-#include <signal.h>
-
+#define _GNU_SOURCE /* to get strsignal declared with glibc 2 */
#include <config.h>
+#include <signal.h>
/* This file is split into two parts by the following preprocessor
conditional. The 'then' clause contains all of the support for
#endif /* NEED_NET_ERRNO_H */
#endif /* HAVE_SOCKETS */
-/* TERM is a poor-man's SLIP, used on Linux. */
+/* TERM is a poor-man's SLIP, used on GNU/Linux. */
#ifdef TERM
#include <client.h>
#endif
#include "blockinput.h"
#include "keyboard.h"
#include "dispextern.h"
+#include "composite.h"
+#include "atimer.h"
#define max(a, b) ((a) > (b) ? (a) : (b))
#include "syswait.h"
+extern void set_waiting_for_input P_ ((EMACS_TIME *));
+
extern int errno;
-extern char *strerror ();
#ifdef VMS
extern char *sys_errlist[];
#endif
extern int h_errno;
#endif
-#ifndef SYS_SIGLIST_DECLARED
-#ifndef VMS
-#ifndef BSD4_1
-#ifndef WINDOWSNT
-#ifndef LINUX
-extern char *sys_siglist[];
-#endif /* not LINUX */
-#else /* BSD4_1 */
-char *sys_siglist[] =
- {
- "bum signal!!",
- "hangup",
- "interrupt",
- "quit",
- "illegal instruction",
- "trace trap",
- "iot instruction",
- "emt instruction",
- "floating point exception",
- "kill",
- "bus error",
- "segmentation violation",
- "bad argument to system call",
- "write on a pipe with no one to read it",
- "alarm clock",
- "software termination signal from kill",
- "status signal",
- "sendable stop signal not from tty",
- "stop signal from tty",
- "continue a stopped process",
- "child status has changed",
- "background read attempted from control tty",
- "background write attempted from control tty",
- "input record available at control tty",
- "exceeded CPU time limit",
- "exceeded file size limit"
- };
-#endif /* not WINDOWSNT */
-#endif
-#endif /* VMS */
-#endif /* ! SYS_SIGLIST_DECLARED */
-
/* t means use pty, nil means use a pipe,
maybe other values to come. */
static Lisp_Object Vprocess_connection_type;
#include "sysselect.h"
+extern int keyboard_bit_set P_ ((SELECT_TYPE *));
+
/* 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. */
#ifdef HAVE_WINDOW_SYSTEM
}
else
{
- *symbol = XCONS (l)->car;
- tem = XCONS (l)->cdr;
- *code = XFASTINT (XCONS (tem)->car);
- tem = XCONS (tem)->cdr;
+ *symbol = XCAR (l);
+ tem = XCDR (l);
+ *code = XFASTINT (XCAR (tem));
+ tem = XCDR (tem);
*coredump = !NILP (tem);
}
}
if (EQ (symbol, Qsignal) || EQ (symbol, Qstop))
{
- char *signame = 0;
- if (code < NSIG)
- {
-#ifndef VMS
- /* Cast to suppress warning if the table has const char *. */
- signame = (char *) sys_siglist[code];
-#else
- signame = sys_errlist[code];
-#endif
- }
+ char *signame;
+ synchronize_system_messages_locale ();
+ signame = strsignal (code);
if (signame == 0)
signame = "unknown";
string = build_string (signame);
#else /* no PTY_OPEN */
#ifdef IRIS
/* Unusual IRIS code */
- *ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
+ *ptyv = emacs_open ("/dev/ptc", O_RDWR | O_NDELAY, 0);
if (fd < 0)
return -1;
if (fstat (fd, &stb) < 0)
else
failed_count = 0;
#ifdef O_NONBLOCK
- fd = open (pty_name, O_RDWR | O_NONBLOCK, 0);
+ fd = emacs_open (pty_name, O_RDWR | O_NONBLOCK, 0);
#else
- fd = open (pty_name, O_RDWR | O_NDELAY, 0);
+ fd = emacs_open (pty_name, O_RDWR | O_NDELAY, 0);
#endif
#endif /* not IRIS */
#endif /* no PTY_OPEN */
#ifndef UNIPLUS
if (access (pty_name, 6) != 0)
{
- close (fd);
+ emacs_close (fd);
#if !defined(IRIS) && !defined(__sgi)
continue;
#else
update_status (p);
status = p->status;
if (CONSP (status))
- status = XCONS (status)->car;
+ status = XCAR (status);
if (NETCONN_P (process))
{
if (EQ (status, Qrun))
if (!NILP (XPROCESS (process)->raw_status_low))
update_status (XPROCESS (process));
if (CONSP (XPROCESS (process)->status))
- return XCONS (XCONS (XPROCESS (process)->status)->cdr)->car;
+ return XCAR (XCDR (XPROCESS (process)->status));
return make_number (0);
}
CHECK_NATNUM (height, 0);
CHECK_NATNUM (width, 0);
if (set_window_size (XINT (XPROCESS (process)->infd),
- XINT (height), XINT(width)) <= 0)
+ XINT (height), XINT (width)) <= 0)
return Qnil;
else
return Qt;
{
register Lisp_Object tail, tem;
Lisp_Object proc, minspace, tem1;
- register struct buffer *old = current_buffer;
register struct Lisp_Process *p;
- register int state;
char tembuf[80];
XSETFASTINT (minspace, 1);
update_status (p);
symbol = p->status;
if (CONSP (p->status))
- symbol = XCONS (p->status)->car;
+ symbol = XCAR (p->status);
if (EQ (symbol, Qsignal))
if (NETCONN_P (proc))
{
sprintf (tembuf, "(network stream connection to %s)\n",
- XSTRING (XCONS (p->childp)->car)->data);
+ XSTRING (XCAR (p->childp))->data);
insert_string (tembuf);
}
else
DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
"Start a program in a subprocess. Return the process object for it.\n\
-Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\
NAME is name for process. It is modified if necessary to make it unique.\n\
BUFFER is the buffer or (buffer-name) to associate with the process.\n\
Process output goes at end of that buffer, unless you specify\n\
coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
UNGCPRO;
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->car;
+ val = XCAR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->car;
+ val = XCAR (Vdefault_process_coding_system);
}
XPROCESS (proc)->decode_coding_system = val;
UNGCPRO;
}
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->cdr;
+ val = XCDR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->cdr;
+ val = XCDR (Vdefault_process_coding_system);
}
XPROCESS (proc)->encode_coding_system = val;
}
return Qnil;
}
-
-SIGTYPE
-create_process_1 (signo)
- int signo;
+void
+create_process_1 (timer)
+ struct atimer *timer;
{
-#if defined (USG) && !defined (POSIX_SIGNALS)
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- signal (signo, create_process_1);
-#endif /* USG */
+ /* Nothing to do. */
}
+
#if 0 /* This doesn't work; see the note before sigchld_handler. */
#ifdef USG
#ifdef SIGCHLD
struct sigaction sighup_action;
#endif
#else /* !POSIX_SIGNALS */
+#if 0
#ifdef SIGCHLD
SIGTYPE (*sigchld)();
#endif
+#endif /* 0 */
#endif /* !POSIX_SIGNALS */
/* Use volatile to protect variables from being clobbered by longjmp. */
volatile int forkin, forkout;
#ifdef O_NOCTTY
/* Don't let this terminal become our controlling terminal
(in case we don't have one). */
- forkout = forkin = open (pty_name, O_RDWR | O_NOCTTY, 0);
+ forkout = forkin = emacs_open (pty_name, O_RDWR | O_NOCTTY, 0);
#else
- forkout = forkin = open (pty_name, O_RDWR, 0);
+ forkout = forkin = emacs_open (pty_name, O_RDWR, 0);
#endif
if (forkin < 0)
report_file_error ("Opening pty", Qnil);
}
#else /* not SKTPAIR */
{
- pipe (sv);
+ int tem;
+ tem = pipe (sv);
+ if (tem < 0)
+ report_file_error ("Creating pipe", Qnil);
inchannel = sv[0];
forkout = sv[1];
- pipe (sv);
+ tem = pipe (sv);
+ if (tem < 0)
+ {
+ emacs_close (inchannel);
+ emacs_close (forkout);
+ report_file_error ("Creating pipe", Qnil);
+ }
outchannel = sv[1];
forkin = sv[0];
}
setup_coding_system (XPROCESS (process)->encode_coding_system,
proc_encode_coding_system[outchannel]);
- if (!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters)
+ if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters))
|| (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)))
{
/* In unibyte mode, character code conversion should not take
tcgetattr (xforkin, &t);
t.c_lflag = LDISC1;
if (tcsetattr (xforkin, TCSANOW, &t) < 0)
- write (1, "create_process/tcsetattr LDISC1 failed\n", 39);
+ emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39);
}
#else
#if defined (NTTYDISC) && defined (TIOCSETD)
{
/* I wonder: would just ioctl (0, TIOCNOTTY, 0) work here?
I can't test it since I don't have 4.3. */
- int j = open ("/dev/tty", O_RDWR, 0);
+ int j = emacs_open ("/dev/tty", O_RDWR, 0);
ioctl (j, TIOCNOTTY, 0);
- close (j);
+ emacs_close (j);
#ifndef USG
/* In order to get a controlling terminal on some versions
of BSD, it is necessary to put the process in pgrp 0
int pgrp = getpid ();
#endif
- /* I wonder if close (open (pty_name, ...)) would work? */
+ /* I wonder if emacs_close (emacs_open (pty_name, ...))
+ would work? */
if (xforkin >= 0)
- close (xforkin);
- xforkout = xforkin = open (pty_name, O_RDWR, 0);
+ emacs_close (xforkin);
+ xforkout = xforkin = emacs_open (pty_name, O_RDWR, 0);
if (xforkin < 0)
{
- write (1, "Couldn't open the pty terminal ", 31);
- write (1, pty_name, strlen (pty_name));
- write (1, "\n", 1);
+ emacs_write (1, "Couldn't open the pty terminal ", 31);
+ emacs_write (1, pty_name, strlen (pty_name));
+ emacs_write (1, "\n", 1);
_exit (1);
}
if (pid < 0)
{
if (forkin >= 0)
- close (forkin);
+ emacs_close (forkin);
if (forkin != forkout && forkout >= 0)
- close (forkout);
+ emacs_close (forkout);
}
else
{
/* If the subfork execv fails, and it exits,
this close hangs. I don't know why.
So have an interrupt jar it loose. */
- stop_polling ();
- signal (SIGALRM, create_process_1);
- alarm (1);
- XPROCESS (process)->subtty = Qnil;
- if (forkin >= 0)
- close (forkin);
- alarm (0);
- start_polling ();
+ {
+ struct atimer *timer;
+ EMACS_TIME offset;
+
+ stop_polling ();
+ EMACS_SET_SECS_USECS (offset, 1, 0);
+ timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
+
+ XPROCESS (process)->subtty = Qnil;
+ if (forkin >= 0)
+ emacs_close (forkin);
+
+ cancel_atimer (timer);
+ start_polling ();
+ }
+
if (forkin != forkout && forkout >= 0)
- close (forkout);
+ emacs_close (forkout);
#ifdef HAVE_PTYS
if (pty_flag)
Lisp_Object name, buffer, host, service;
{
Lisp_Object proc;
- register int i;
+#ifndef HAVE_GETADDRINFO
struct sockaddr_in address;
struct servent *svc_info;
struct hostent *host_info_ptr, host_info;
char *(addr_list[2]);
IN_ADDR numeric_addr;
- int s, outch, inch;
- char errstring[80];
int port;
- struct hostent host_info_fixed;
+#else /* HAVE_GETADDRINFO */
+ struct addrinfo hints, *res, *lres;
+ int ret = 0;
+ int xerrno = 0;
+ char *portstring, portbuf[128];
+#endif /* HAVE_GETADDRINFO */
+ int s = -1, outch, inch;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int retry = 0;
int count = specpdl_ptr - specpdl;
+ int count1;
#ifdef WINDOWSNT
/* Ensure socket support is loaded if available. */
GCPRO4 (name, buffer, host, service);
CHECK_STRING (name, 0);
CHECK_STRING (host, 0);
+
+#ifdef HAVE_GETADDRINFO
+ /*
+ * SERVICE can either be a string or int.
+ * Convert to a C string for later use by getaddrinfo.
+ */
+ if (INTEGERP (service))
+ {
+ sprintf (portbuf, "%d", XINT (service));
+ portstring = portbuf;
+ }
+ else
+ {
+ CHECK_STRING (service, 0);
+ portstring = XSTRING (service)->data;
+ }
+#else /* ! HAVE_GETADDRINFO */
if (INTEGERP (service))
port = htons ((unsigned short) XINT (service));
else
error ("Unknown service \"%s\"", XSTRING (service)->data);
port = svc_info->s_port;
}
+#endif /* ! HAVE_GETADDRINFO */
+
/* Slow down polling to every ten seconds.
Some kernels have a bug which causes retrying connect to fail
after a connect. Polling can interfere with gethostbyname too. */
#ifdef POLL_FOR_INPUT
+ record_unwind_protect (unwind_stop_other_atimers, Qnil);
bind_polling_period (10);
#endif
#ifndef TERM
+#ifdef HAVE_GETADDRINFO
+ {
+ immediate_quit = 1;
+ QUIT;
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_flags = 0;
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res);
+ if (ret)
+ {
+ error ("%s/%s %s", XSTRING (host)->data, portstring,
+ strerror (ret));
+ }
+ immediate_quit = 0;
+ }
+
+ s = -1;
+ count1 = specpdl_ptr - specpdl;
+ record_unwind_protect (close_file_unwind, make_number (s));
+
+ for (lres = res; lres; lres = lres->ai_next)
+ {
+ s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
+ if (s < 0)
+ continue;
+
+ /* 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
+ when not interrupt_input, and thus not normally used on the systems
+ which have this bug. On systems which use polling, there's no way
+ to quit if polling is turned off. */
+ if (interrupt_input)
+ unrequest_sigio ();
+
+ immediate_quit = 1;
+ QUIT;
+
+ ret = connect (s, lres->ai_addr, lres->ai_addrlen);
+ if (ret == 0)
+ break;
+ emacs_close (s);
+ s = -1;
+ }
+
+ freeaddrinfo (res);
+ if (s < 0)
+ {
+ if (interrupt_input)
+ request_sigio ();
+
+ errno = xerrno;
+ report_file_error ("connection failed",
+ Fcons (host, Fcons (name, Qnil)));
+ }
+#else /* ! HAVE_GETADDRINFO */
+
while (1)
{
+#if 0
#ifdef TRY_AGAIN
h_errno = 0;
+#endif
#endif
immediate_quit = 1;
QUIT;
host_info_ptr = gethostbyname (XSTRING (host)->data);
immediate_quit = 0;
+#if 0
#ifdef TRY_AGAIN
if (! (host_info_ptr == 0 && h_errno == TRY_AGAIN))
+#endif
#endif
break;
Fsleep_for (make_number (1), Qnil);
if (s < 0)
report_file_error ("error creating socket", Fcons (name, Qnil));
+ count1 = specpdl_ptr - specpdl;
+ record_unwind_protect (close_file_unwind, make_number (s));
+
/* 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
goto loop;
}
- close (s);
+ /* Discard the unwind protect. */
+ specpdl_ptr = specpdl + count1;
+
+ emacs_close (s);
if (interrupt_input)
request_sigio ();
report_file_error ("connection failed",
Fcons (host, Fcons (name, Qnil)));
}
+#endif /* ! HAVE_GETADDRINFO */
immediate_quit = 0;
+ /* Discard the unwind protect. */
+ specpdl_ptr = specpdl + count1;
+
#ifdef POLL_FOR_INPUT
unbind_to (count, Qnil);
#endif
if (!NILP (Vcoding_system_for_read))
val = Vcoding_system_for_read;
- else if (!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters)
- || NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters))
+ else if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters))
+ || (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)))
/* We dare not decode end-of-line format by setting VAL to
Qraw_text, because the existing Emacs Lisp libraries
assume that they receive bare code including a sequene of
coding_systems = Ffind_operation_coding_system (5, args);
UNGCPRO;
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->car;
+ val = XCAR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->car;
+ val = XCAR (Vdefault_process_coding_system);
else
val = Qnil;
}
UNGCPRO;
}
if (CONSP (coding_systems))
- val = XCONS (coding_systems)->cdr;
+ val = XCDR (coding_systems);
else if (CONSP (Vdefault_process_coding_system))
- val = XCONS (Vdefault_process_coding_system)->cdr;
+ val = XCDR (Vdefault_process_coding_system);
else
val = Qnil;
}
give_back_vms_process_stuff (vs);
}
#else
- close (inchannel);
+ emacs_close (inchannel);
if (outchannel >= 0 && outchannel != inchannel)
- close (outchannel);
+ emacs_close (outchannel);
#endif
XSETINT (p->infd, -1);
int in = XINT (XPROCESS (process)->infd);
int out = XINT (XPROCESS (process)->outfd);
if (in >= 0)
- close (in);
+ emacs_close (in);
if (out >= 0 && in != out)
- close (out);
+ emacs_close (out);
}
}
#endif
Lisp_Object read_kbd;
int do_display;
{
- register int channel, nfds, m;
+ register int channel, nfds;
static SELECT_TYPE Available;
int xerrno;
Lisp_Object proc;
- EMACS_TIME timeout, end_time, garbage;
+ EMACS_TIME timeout, end_time;
SELECT_TYPE Atemp;
int wait_channel = -1;
struct Lisp_Process *wait_proc = 0;
/* If waiting for non-nil in a cell, record where. */
if (CONSP (read_kbd))
{
- wait_for_cell = &XCONS (read_kbd)->car;
+ wait_for_cell = &XCAR (read_kbd);
XSETFASTINT (read_kbd, 0);
}
Causes "poll: interrupted system call" messages when Emacs is run
in an X window
Turn off periodic alarms (in case they are in use) */
- stop_polling ();
+ turn_on_atimers (0);
#endif
while (1)
{
int timeout_reduced_for_timers = 0;
-#ifdef HAVE_X_WINDOWS
- if (display_busy_cursor_p)
- Fx_hide_busy_cursor (Qnil);
-#endif
-
/* 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. */
XSETPROCESS (proc, wait_proc);
/* Read data from the process, until we exhaust it. */
- while (XINT (wait_proc->infd) >= 0
- && (nread
- = read_process_output (proc, XINT (wait_proc->infd))))
+ while (XINT (wait_proc->infd) >= 0)
{
+ nread = read_process_output (proc, XINT (wait_proc->infd));
+
+ if (nread == 0)
+ break;
+
if (0 < nread)
total_nread += nread;
#ifdef EIO
else if (nread == -1 && EIO == errno)
break;
+#endif
+#ifdef EAGAIN
+ else if (nread == -1 && EAGAIN == errno)
+ break;
+#endif
+#ifdef EWOULDBLOCK
+ else if (nread == -1 && EWOULDBLOCK == errno)
+ break;
#endif
}
if (total_nread > 0 && do_display)
clear_waiting_for_input ();
/* If we woke up due to SIGWINCH, actually change size now. */
- do_pending_window_change ();
+ do_pending_window_change (0);
if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
/* We wanted the full specified time, so return now. */
#endif
}
else
- error ("select error: %s", strerror (xerrno));
+ error ("select error: %s", emacs_strerror (xerrno));
}
#if defined(sun) && !defined(USG5_4)
else if (nfds > 0 && keyboard_bit_set (&Available)
/* If checking input just got us a size-change event from X,
obey it now if we should. */
if (XINT (read_kbd) || wait_for_cell)
- do_pending_window_change ();
+ do_pending_window_change (0);
/* Check for data from a process. */
/* Really FIRST_PROC_DESC should be 0 on Unix,
start_polling ();
#endif
-#ifdef HAVE_X_WINDOWS
- if (display_busy_cursor_p)
- if (!inhibit_busy_cursor)
- Fx_show_busy_cursor ();
-#endif
-
return got_some_input;
}
\f
read_process_output_call (fun_and_args)
Lisp_Object fun_and_args;
{
- return apply1 (XCONS (fun_and_args)->car, XCONS (fun_and_args)->cdr);
+ return apply1 (XCAR (fun_and_args), XCDR (fun_and_args));
}
static Lisp_Object
Vinhibit_quit = Qt;
update_echo_area ();
Fsleep_for (make_number (2), Qnil);
+ return Qt;
}
/* Read pending output from the process channel,
if (vs)
{
if (!vs->iosb[0])
- return(0); /* Really weird if it does this */
+ return (0); /* Really weird if it does this */
if (!(vs->iosb[0] & 1))
return -1; /* I/O error */
}
buf, carryover);
if (proc_buffered_char[channel] < 0)
- nbytes = read (channel, buf + carryover, (sizeof buf) - carryover);
+ nbytes = emacs_read (channel, buf + carryover, (sizeof buf) - carryover);
else
{
buf[carryover] = proc_buffered_char[channel];
proc_buffered_char[channel] = -1;
- nbytes = read (channel, buf + carryover + 1,
- (sizeof buf) - carryover - 1);
+ nbytes = emacs_read (channel, buf + carryover + 1,
+ (sizeof buf) - carryover - 1);
if (nbytes < 0)
nbytes = 1;
else
else
{
insert_1_both (chars, nchars, nbytes, 0, 1, 1);
- signal_after_change (opoint, 0, PT - opoint);
+ signal_after_change (before, 0, PT - before);
+ update_compositions (before, PT, CHECK_BORDER);
}
set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
is sent. But if the data ends at the middle of multi-byte
representation, that incomplete sequence of bytes are sent without
being encoded. Should we store them in a buffer to prepend them to
- the data send later? */
+ the data send later?
+
+ This function can evaluate Lisp code and can garbage collect. */
void
send_process (proc, buf, len, object)
{
/* Use volatile to protect variables from being clobbered by longjmp. */
int rv;
- volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
struct coding_system *coding;
struct gcpro gcpro1;
int carryover = XINT (XPROCESS (proc)->encoding_carryover);
if (! NILP (XPROCESS (proc)->raw_status_low))
update_status (XPROCESS (proc));
if (! EQ (XPROCESS (proc)->status, Qrun))
- error ("Process %s not running", procname);
+ error ("Process %s not running",
+ XSTRING (XPROCESS (proc)->name)->data);
if (XINT (XPROCESS (proc)->outfd) < 0)
- error ("Output file descriptor of %s is closed", procname);
+ error ("Output file descriptor of %s is closed",
+ XSTRING (XPROCESS (proc)->name)->data);
coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
Vlast_coding_system_used = coding->symbol;
if (CODING_REQUIRE_ENCODING (coding))
{
int require = encoding_buffer_size (coding, len);
- int offset, dummy;
+ int offset;
unsigned char *temp_buf = NULL;
/* Remember the offset of data because a string or a buffer may
{
int this = len;
SIGTYPE (*old_sigpipe)();
- int flush_pty = 0;
/* Decide how much data we can send in one batch.
Long lines need to be split into multiple batches. */
while (this > 0)
{
old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
- rv = write (XINT (XPROCESS (proc)->outfd), buf, this);
+ rv = emacs_write (XINT (XPROCESS (proc)->outfd), buf, this);
signal (SIGPIPE, old_sigpipe);
if (rv < 0)
Lisp_Object zero;
int offset;
+#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
+ /* A gross hack to work around a bug in FreeBSD.
+ In the following sequence, read(2) returns
+ bogus data:
+
+ write(2) 1022 bytes
+ write(2) 954 bytes, get EAGAIN
+ read(2) 1024 bytes in process_read_output
+ read(2) 11 bytes in process_read_output
+
+ That is, read(2) returns more bytes than have
+ ever been written successfully. The 1033 bytes
+ read are the 1022 bytes written successfully
+ after processing (for example with CRs added if
+ the terminal is set up that way which it is
+ here). The same bytes will be seen again in a
+ later read(2), without the CRs. */
+
+ if (errno == EAGAIN)
+ {
+ int flags = FWRITE;
+ ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH,
+ &flags);
+ }
+#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
+
/* Running filters might relocate buffers or strings.
Arrange to relocate BUF. */
if (BUFFERP (object))
XSETINT (XPROCESS (proc)->tick, ++process_tick);
deactivate_process (proc);
#ifdef VMS
- error ("Error writing to process %s; closed it", procname);
+ error ("Error writing to process %s; closed it",
+ XSTRING (XPROCESS (proc)->name)->data);
#else
- error ("SIGPIPE raised on process %s; closed it", procname);
+ error ("SIGPIPE raised on process %s; closed it",
+ XSTRING (XPROCESS (proc)->name)->data);
#endif
}
shutdown (XINT (XPROCESS (proc)->outfd), 1);
/* In case of socketpair, outfd == infd, so don't close it. */
if (XINT (XPROCESS (proc)->outfd) != XINT (XPROCESS (proc)->infd))
- close (XINT (XPROCESS (proc)->outfd));
+ emacs_close (XINT (XPROCESS (proc)->outfd));
#else /* not HAVE_SHUTDOWN */
- close (XINT (XPROCESS (proc)->outfd));
+ emacs_close (XINT (XPROCESS (proc)->outfd));
#endif /* not HAVE_SHUTDOWN */
- new_outfd = open (NULL_DEVICE, O_WRONLY);
+ new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0);
old_outfd = XINT (XPROCESS (proc)->outfd);
if (!proc_encode_coding_system[new_outfd])
{
Lisp_Object tail, proc;
- for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
{
- proc = XCONS (XCONS (tail)->car)->cdr;
+ proc = XCDR (XCAR (tail));
if (GC_PROCESSP (proc)
&& (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
{
/* Find the process that signaled us, and record its status. */
p = 0;
- for (tail = Vprocess_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
- proc = XCONS (XCONS (tail)->car)->cdr;
+ proc = XCDR (XCAR (tail));
p = XPROCESS (proc);
if (EQ (p->childp, Qt) && XFASTINT (p->pid) == pid)
break;
/* Look for an asynchronous process whose pid hasn't been filled
in yet. */
if (p == 0)
- for (tail = Vprocess_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
- proc = XCONS (XCONS (tail)->car)->cdr;
+ proc = XCDR (XCAR (tail));
p = XPROCESS (proc);
if (INTEGERP (p->pid) && XINT (p->pid) == -1)
break;
else if (WIFSIGNALED (w))
{
int code = WTERMSIG (w);
- char *signame = 0;
+ char *signame;
+
+ synchronize_system_messages_locale ();
+ signame = strsignal (code);
- if (code < NSIG)
- {
-#ifndef VMS
- /* Suppress warning if the table has const char *. */
- signame = (char *) sys_siglist[code];
-#else
- signame = sys_errlist[code];
-#endif
- }
if (signame == 0)
signame = "unknown";
exec_sentinel_unwind (data)
Lisp_Object data;
{
- XPROCESS (XCONS (data)->car)->sentinel = XCONS (data)->cdr;
+ XPROCESS (XCAR (data))->sentinel = XCDR (data);
return Qnil;
}
Vinhibit_quit = Qt;
update_echo_area ();
Fsleep_for (make_number (2), Qnil);
+ return Qt;
}
static void
/* If process is terminated, deactivate it or delete it. */
symbol = p->status;
if (CONSP (p->status))
- symbol = XCONS (p->status)->car;
+ symbol = XCAR (p->status);
if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)
|| EQ (symbol, Qclosed))
/* If waiting for non-nil in a cell, record where. */
if (CONSP (read_kbd))
{
- wait_for_cell = &XCONS (read_kbd)->car;
+ wait_for_cell = &XCAR (read_kbd);
XSETFASTINT (read_kbd, 0);
}
/* Turn off periodic alarms (in case they are in use)
because the select emulator uses alarms. */
- stop_polling ();
+ turn_on_atimers (0);
while (1)
{
clear_waiting_for_input ();
/* If we woke up due to SIGWINCH, actually change size now. */
- do_pending_window_change ();
+ do_pending_window_change (0);
if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
/* We waited the full specified time, so return now. */
if (xerrno == EINTR)
FD_ZERO (&waitchannels);
else
- error ("select error: %s", strerror (xerrno));
+ error ("select error: %s", emacs_strerror (xerrno));
}
#ifdef sun
else if (nfds > 0 && (waitchannels & 1) && interrupt_input)