/* Asynchronous subprocess control for GNU Emacs.
Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
1996, 1998, 1999, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 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 <client.h>
#endif
-/* On some systems, e.g. DGUX, inet_addr returns a 'struct in_addr'. */
+/* On some systems, inet_addr returns a 'struct in_addr'. */
#ifdef HAVE_BROKEN_INET_ADDR
#define IN_ADDR struct in_addr
#define NUMERIC_ADDR_ERROR (numeric_addr.s_addr == -1)
#define NUMERIC_ADDR_ERROR (numeric_addr == -1)
#endif
-#if defined(BSD_SYSTEM) || defined(STRIDE)
+#if defined(BSD_SYSTEM)
#include <sys/ioctl.h>
#if !defined (O_NDELAY) && defined (HAVE_PTYS) && !defined(USG5)
#include <fcntl.h>
#endif /* HAVE_PTYS and no O_NDELAY */
-#endif /* BSD_SYSTEM || STRIDE */
+#endif /* BSD_SYSTEM */
#ifdef BROKEN_O_NONBLOCK
#undef O_NONBLOCK
#include <sys/wait.h>
#endif
+#ifdef HAVE_RES_INIT
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#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"
#else
sprintf (pty_name, "/dev/tty%c%x", c, i);
#endif /* no PTY_TTY_NAME_SPRINTF */
-#ifndef UNIPLUS
if (access (pty_name, 6) != 0)
{
emacs_close (fd);
return -1;
# endif /* IRIS */
}
-#endif /* not UNIPLUS */
setup_pty (fd);
return fd;
}
p->tick = 0;
p->update_tick = 0;
p->pid = 0;
+ p->pty_flag = 0;
p->raw_status_new = 0;
p->status = Qrun;
p->mark = Fmake_marker ();
buf = Fget_buffer (buffer);
if (NILP (buf)) return Qnil;
- for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
- proc = Fcdr (Fcar (tail));
+ proc = Fcdr (XCAR (tail));
if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
return proc;
}
DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
2, 2, 0,
doc: /* Give PROCESS the filter function FILTER; nil means no filter.
-t means stop accepting output from the process.
+A value of t means stop accepting output from the process.
When a process has a filter, its buffer is not used for output.
Instead, each time it does output, the entire string of output is
w_buffer = 6; /* Buffer */
w_tty = 0; /* Omit if no ttys */
- for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
int i;
- proc = Fcdr (Fcar (tail));
+ proc = Fcdr (XCAR (tail));
p = XPROCESS (proc);
if (NILP (p->childp))
continue;
w_proc = i;
if (!NILP (p->buffer))
{
- if (NILP (XBUFFER (p->buffer)->name) && w_buffer < 8)
- w_buffer = 8; /* (Killed) */
+ if (NILP (XBUFFER (p->buffer)->name))
+ {
+ if (w_buffer < 8)
+ w_buffer = 8; /* (Killed) */
+ }
else if ((i = SCHARS (XBUFFER (p->buffer)->name), (i > w_buffer)))
w_buffer = i;
}
if (w_tty)
{
XSETFASTINT (i_tty, XFASTINT (i_buffer) + w_buffer + 1);
- XSETFASTINT (i_command, XFASTINT (i_buffer) + w_tty + 1);
- } else {
+ XSETFASTINT (i_command, XFASTINT (i_tty) + w_tty + 1);
+ }
+ else
+ {
i_tty = Qnil;
XSETFASTINT (i_command, XFASTINT (i_buffer) + w_buffer + 1);
}
Findent_to (i_command, minspace); write_string ("-------", -1);
write_string ("\n", -1);
- for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object symbol;
- proc = Fcdr (Fcar (tail));
+ proc = Fcdr (XCAR (tail));
p = XPROCESS (proc);
if (NILP (p->childp))
continue;
#endif
if (forkin < 0)
report_file_error ("Opening pty", Qnil);
-#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
+#if defined (DONT_REOPEN_PTY)
/* In the case that vfork is defined as fork, the parent process
(Emacs) may send some data before the child process completes
tty options setup. So we setup tty before forking. */
child_setup_tty (forkout);
-#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
+#endif /* DONT_REOPEN_PTY */
#else
forkin = forkout = -1;
#endif /* not USG, or USG_SUBTTY_WORKS */
set_exclusive_use (outchannel);
#endif
-/* Stride people say it's a mystery why this is needed
- as well as the O_NDELAY, but that it fails without this. */
-#if defined (STRIDE) || (defined (pfa) && defined (HAVE_PTYS))
- {
- int one = 1;
- ioctl (inchannel, FIONBIO, &one);
- }
-#endif
-
#ifdef O_NONBLOCK
fcntl (inchannel, F_SETFL, O_NONBLOCK);
fcntl (outchannel, F_SETFL, O_NONBLOCK);
#ifdef BSD4_1
sighold (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (HPUX)
sigsetmask (sigmask (SIGCHLD));
#else /* ordinary USG */
#if 0
}
#endif /* TIOCNOTTY */
-#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
+#if !defined (DONT_REOPEN_PTY)
/*** There is a suggestion that this ought to be a
conditional on TIOCSPGRP,
or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
ioctl (xforkout, TIOCSPGRP, &pgrp);
#endif
}
-#endif /* not UNIPLUS and not RTU and not DONT_REOPEN_PTY */
+#endif /* not DONT_REOPEN_PTY */
#ifdef SETUP_SLAVE_PTY
if (pty_flag)
#ifdef BSD4_1
sigrelse (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
#if 0
#endif /* SIGCHLD */
#endif /* !POSIX_SIGNALS */
-#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
+#if !defined (DONT_REOPEN_PTY)
if (pty_flag)
child_setup_tty (xforkout);
-#endif /* not RTU and not UNIPLUS and not DONT_REOPEN_PTY */
+#endif /* not DONT_REOPEN_PTY */
#ifdef WINDOWSNT
pid = child_setup (xforkin, xforkout, xforkout,
new_argv, 1, current_dir);
#ifdef BSD4_1
sigrelse (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
#if 0
\f
/* A version of request_sigio suitable for a record_unwind_protect. */
+#ifdef __ultrix__
static Lisp_Object
unwind_request_sigio (dummy)
Lisp_Object dummy;
request_sigio ();
return Qnil;
}
+#endif
/* Create a network stream/datagram client/server process. Treated
exactly like a normal process when reading and writing. Primary
:service SERVICE -- SERVICE is name of the service desired, or an
integer specifying a port number to connect to. If SERVICE is t,
-a random port number is selected for the server.
+a random port number is selected for the server. (If Emacs was
+compiled with getaddrinfo, a port number can also be specified as a
+string, e.g. "80", as well as an integer. This is not portable.)
:type TYPE -- TYPE is the type of connection. The default (nil) is a
stream type connection, `datagram' creates a datagram type connection.
:filter-multibyte BOOL -- If BOOL is non-nil, strings given to the
process filter are multibyte, otherwise they are unibyte.
-If this keyword is not specified, the strings are multibyte iff
+If this keyword is not specified, the strings are multibyte if
`default-enable-multibyte-characters' is non-nil.
:sentinel SENTINEL -- Install SENTINEL as the process sentinel.
hints.ai_family = family;
hints.ai_socktype = socktype;
hints.ai_protocol = 0;
+
+#ifdef HAVE_RES_INIT
+ res_init ();
+#endif
+
ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
if (ret)
#ifdef HAVE_GAI_STRERROR
as it may `hang' Emacs for a very long time. */
immediate_quit = 1;
QUIT;
+
+#ifdef HAVE_RES_INIT
+ res_init ();
+#endif
+
host_info_ptr = gethostbyname (SDATA (host));
immediate_quit = 0;
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 ();
If optional fourth arg JUST-THIS-ONE is non-nil, only accept output
from PROCESS, suspending reading output from other processes.
If JUST-THIS-ONE is an integer, don't run any timers either.
-Return non-nil iff we received any output before the timeout expired. */)
+Return non-nil if we received any output before the timeout expired. */)
(process, seconds, millisec, just_this_one)
register Lisp_Object process, seconds, millisec, just_this_one;
{
(and gobble terminal input into the buffer if any arrives).
If WAIT_PROC is specified, wait until something arrives from that
- process. The return value is true iff we read some input from
+ 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
(suspending output from other processes). A negative value
means don't run any timers either.
- If WAIT_PROC is specified, then the function returns true iff we
+ If WAIT_PROC is specified, then the function returns true if we
received input from that process before the timeout elapsed.
- Otherwise, return true iff we received input from any process. */
+ Otherwise, return true if we received input from any process. */
int
wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
not by DEC's bundled CC. -JimB */
else if (xerrno == ENOMEM)
no_avail = 1;
-#endif
-#ifdef ALLIANT
- /* This happens for no known reason on ALLIANT.
- I am guessing that this is the right response. -- RMS. */
- else if (xerrno == EFAULT)
- no_avail = 1;
#endif
else if (xerrno == EBADF)
{
{
int old_timers_run = timers_run;
struct buffer *old_buffer = current_buffer;
+ Lisp_Object old_window = selected_window;
int leave = 0;
if (detect_input_pending_run_timers (do_display))
an alike. Make read_key_sequence aware of that. */
if (timers_run != old_timers_run
&& waiting_for_user_input_p == -1
- && old_buffer != current_buffer)
+ && (old_buffer != current_buffer
+ || !EQ (old_window, selected_window)))
record_asynch_buffer_change ();
if (leave)
that we run, we get called again to handle their status changes. */
update_tick = process_tick;
- for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+ for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object symbol;
register struct Lisp_Process *p;
- proc = Fcdr (Fcar (tail));
+ proc = Fcdr (XCAR (tail));
p = XPROCESS (proc);
if (p->tick != p->update_tick)
\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)
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
do_display != 0 means redisplay should be done to show subprocess
output that arrives.
- Return true iff we received input from any process. */
+ Return true if we received input from any process. */
int
wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,