/* Qexit is declared and initialized in eval.c. */
/* a process object is a network connection when its childp field is neither
- Qt nor Qnil but is instead a string (name of foreign host we
- are connected to + name of port we are connected to) */
+ Qt nor Qnil but is instead a cons cell (HOSTNAME PORTNUM). */
#ifdef HAVE_SOCKETS
-static Lisp_Object stream_process;
-
-#define NETCONN_P(p) (GC_STRINGP (XPROCESS (p)->childp))
+#define NETCONN_P(p) (GC_CONSP (XPROCESS (p)->childp))
#else
#define NETCONN_P(p) 0
#endif /* HAVE_SOCKETS */
return Fnull (tem);
}
+DEFUN ("process-contact", Fprocess_contact, Sprocess_contact,
+ 1, 1, 0,
+ "Return the contact info of PROCESS; t for a real child.\n\
+For a net connection, the value is a cons cell of the form (HOST SERVICE).")
+ (process)
+ register Lisp_Object process;
+{
+ CHECK_PROCESS (process, 0);
+ return XPROCESS (process)->childp;
+}
+
#if 0 /* Turned off because we don't currently record this info
in the process. Perhaps add it. */
DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0,
if (NETCONN_P (proc))
{
sprintf (tembuf, "(network stream connection to %s)\n",
- XSTRING (p->childp)->data);
+ XSTRING (XCONS (p->childp)->car)->data);
insert_string (tembuf);
}
else
create_process_1 (signo)
int signo;
{
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
must reestablish each time */
signal (signo, create_process_1);
}
#else /* not SKTPAIR */
{
-#ifdef WINDOWSNT
- pipe_with_inherited_out (sv);
- inchannel = sv[0];
- forkout = sv[1];
-
- pipe_with_inherited_in (sv);
- forkin = sv[0];
- outchannel = sv[1];
-#else /* not WINDOWSNT */
pipe (sv);
inchannel = sv[0];
forkout = sv[1];
pipe (sv);
outchannel = sv[1];
forkin = sv[0];
-#endif /* not WINDOWSNT */
}
#endif /* not SKTPAIR */
/* In order to get a controlling terminal on some versions
of BSD, it is necessary to put the process in pgrp 0
before it opens the terminal. */
-#ifdef OSF1
+#ifdef HAVE_SETPGID
setpgid (0, 0);
#else
setpgrp (0, 0);
}
#endif /* TIOCNOTTY */
-#if !defined (RTU) && !defined (UNIPLUS)
+#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
/*** There is a suggestion that this ought to be a
- conditional on TIOCSPGRP. */
+ conditional on TIOCSPGRP,
+ or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
+ Trying the latter gave the wrong results on Debian GNU/Linux 1.1;
+ that system does seem to need this code, even though
+ both HAVE_SETSID and TIOCSCTTY are defined. */
/* Now close the pty (if we had it open) and reopen it.
This makes the pty the controlling terminal of the subprocess. */
if (pty_flag)
ioctl (xforkout, TIOCSPGRP, &pgrp);
#endif
}
-#endif /* not UNIPLUS and not RTU */
+#endif /* not UNIPLUS and not RTU and not DONT_REOPEN_PTY */
+
#ifdef SETUP_SLAVE_PTY
if (pty_flag)
{
int retry = 0;
int count = specpdl_ptr - specpdl;
+#ifdef WINDOWSNT
+ /* Ensure socket support is loaded if available. */
+ init_winsock (TRUE);
+#endif
+
GCPRO4 (name, buffer, host, service);
CHECK_STRING (name, 0);
CHECK_STRING (host, 0);
#endif
#endif
- XPROCESS (proc)->childp = host;
+ XPROCESS (proc)->childp = Fcons (host, Fcons (service, Qnil));
XPROCESS (proc)->command_channel_p = Qnil;
XPROCESS (proc)->buffer = buffer;
XPROCESS (proc)->sentinel = Qnil;
XPROCESS (proc)->filter = Qnil;
XPROCESS (proc)->command = Qnil;
XPROCESS (proc)->pid = Qnil;
- XSETINT (XPROCESS (proc)->infd, s);
+ XSETINT (XPROCESS (proc)->infd, inch);
XSETINT (XPROCESS (proc)->outfd, outch);
XPROCESS (proc)->status = Qrun;
FD_SET (inch, &input_wait_mask);
EMACS_SET_SECS_USECS (timeout, time_limit, microsecs);
EMACS_ADD_TIME (end_time, end_time, timeout);
}
+#ifdef hpux
+ /* AlainF 5-Jul-1996
+ HP-UX 10.10 seem to have problems with signals coming in
+ 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 ();
+#endif
while (1)
{
EMACS_SET_SECS_USECS (timeout, 100000, 0);
}
- /* If our caller will not immediately handle keyboard events,
- run timer events directly.
- (Callers that will immediately read keyboard events
- call timer_delay on their own.) */
- if (1)
+ /* Normally we run timers here.
+ But not if wait_for_cell; in those cases,
+ the wait is supposed to be short,
+ and those callers cannot handle running arbitrary Lisp code here. */
+ if (! wait_for_cell)
{
EMACS_TIME timer_delay;
int old_timers_run;
/* If there is any, return immediately
to give it higher priority than subprocesses */
- if ((XINT (read_kbd) != 0 || wait_for_cell)
+ if ((XINT (read_kbd) != 0)
&& detect_input_pending_run_timers (do_display))
{
swallow_events (do_display);
break;
}
+ /* If wait_for_cell. check for keyboard input
+ but don't run any timers.
+ ??? (It seems wrong to me to check for keyboard
+ input at all when wait_for_cell, but the code
+ has been this way since July 1994.
+ Try changing this after version 19.31.) */
+ if (wait_for_cell
+ && detect_input_pending ())
+ {
+ swallow_events (do_display);
+ if (detect_input_pending ())
+ break;
+ }
+
/* Exit now if the cell we're waiting for became non-nil. */
if (wait_for_cell && ! NILP (*wait_for_cell))
break;
#ifdef EWOULDBLOCK
else if (nread == -1 && errno == EWOULDBLOCK)
;
-#else
+#endif
+ /* ISC 4.1 defines both EWOULDBLOCK and O_NONBLOCK,
+ and Emacs uses O_NONBLOCK, so what we get is EAGAIN. */
#ifdef O_NONBLOCK
else if (nread == -1 && errno == EAGAIN)
;
;
#endif /* O_NDELAY */
#endif /* O_NONBLOCK */
-#endif /* EWOULDBLOCK */
#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
clear_input_pending ();
QUIT;
}
-
+#ifdef hpux
+ /* AlainF 5-Jul-1996
+ HP-UX 10.10 seems to have problems with signals coming in
+ Causes "poll: interrupted system call" messages when Emacs is run
+ in an X window
+ Turn periodic alarms back on */
+ start_polling();
+#endif
+
return got_some_input;
}
\f
#else /* not VMS */
if (proc_buffered_char[channel] < 0)
-#ifdef WINDOWSNT
- nchars = read_child_output (channel, chars, sizeof (chars));
-#else
- nchars = read (channel, chars, sizeof chars);
-#endif
+ nchars = read (channel, chars, sizeof (chars));
else
{
chars[0] = proc_buffered_char[channel];
proc_buffered_char[channel] = -1;
-#ifdef WINDOWSNT
- nchars = read_child_output (channel, chars + 1, sizeof (chars) - 1);
-#else
- nchars = read (channel, chars + 1, sizeof chars - 1);
-#endif
+ nchars = read (channel, chars + 1, sizeof (chars) - 1);
if (nchars < 0)
nchars = 1;
else
odeactivate = Vdeactivate_mark;
Fset_buffer (p->buffer);
- opoint = point;
+ opoint = PT;
old_read_only = current_buffer->read_only;
XSETFASTINT (old_begv, BEGV);
XSETFASTINT (old_zv, ZV);
/* If the output marker is outside of the visible region, save
the restriction and widen. */
- if (! (BEGV <= point && point <= ZV))
+ if (! (BEGV <= PT && PT <= ZV))
Fwiden ();
/* Make sure opoint floats ahead of any new text, just as point
would. */
- if (point <= opoint)
+ if (PT <= opoint)
opoint += nchars;
/* Insert after old_begv, but before old_zv. */
- if (point < XFASTINT (old_begv))
+ if (PT < XFASTINT (old_begv))
XSETFASTINT (old_begv, XFASTINT (old_begv) + nchars);
- if (point <= XFASTINT (old_zv))
+ if (PT <= XFASTINT (old_zv))
XSETFASTINT (old_zv, XFASTINT (old_zv) + nchars);
/* Insert before markers in case we are inserting where
the buffer's mark is, and the user's next command is Meta-y. */
insert_before_markers (chars, nchars);
- Fset_marker (p->mark, make_number (point), p->buffer);
+ Fset_marker (p->mark, make_number (PT), p->buffer);
update_mode_lines++;
/* Use volatile to protect variables from being clobbered by longjmp. */
int rv;
volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
+ struct gcpro gcpro1;
+
+ GCPRO1 (object);
#ifdef VMS
struct Lisp_Process *p = XPROCESS (proc);
error ("SIGPIPE raised on process %s; closed it", procname);
#endif
}
+
+ UNGCPRO;
}
DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,
#undef handle_signal
-#ifdef WINDOWSNT
- /* Only works for kill-type signals */
- return make_number (win32_kill_process (XINT (pid), XINT (sigcode)));
-#else
return make_number (kill (XINT (pid), XINT (sigcode)));
-#endif
}
DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
/* USG systems forget handlers when they are used;
must reestablish each time */
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
signal (signo, sigchld_handler); /* WARNING - must come after wait3() */
#endif
#ifdef BSD4_1
Otherwise (on systems that have WNOHANG), loop around
to use up all the processes that have something to tell us. */
#if defined (USG) && ! (defined (HPUX) && defined (WNOHANG)) || defined (WINDOWSNT)
-#ifdef USG
+#if defined (USG) && ! defined (POSIX_SIGNALS)
signal (signo, sigchld_handler);
#endif
errno = old_errno;
if (NILP (XBUFFER (buffer)->name))
continue;
Fset_buffer (buffer);
- opoint = point;
+ opoint = PT;
/* Insert new output into buffer
at the current end-of-output marker,
thus preserving logical ordering of input and output. */
SET_PT (marker_position (p->mark));
else
SET_PT (ZV);
- if (point <= opoint)
+ if (PT <= opoint)
opoint += XSTRING (msg)->size + XSTRING (p->name)->size + 10;
tem = current_buffer->read_only;
insert_string (" ");
Finsert (1, &msg);
current_buffer->read_only = tem;
- Fset_marker (p->mark, make_number (point), p->buffer);
+ Fset_marker (p->mark, make_number (PT), p->buffer);
SET_PT (opoint);
set_buffer_internal (old);
syms_of_process ()
{
-#ifdef HAVE_SOCKETS
- stream_process = intern ("stream");
-#endif
Qprocessp = intern ("processp");
staticpro (&Qprocessp);
Qrun = intern ("run");
defsubr (&Sset_process_filter);
defsubr (&Sprocess_filter);
defsubr (&Sset_process_sentinel);
- defsubr (&Sset_process_window_size);
defsubr (&Sprocess_sentinel);
+ defsubr (&Sset_process_window_size);
defsubr (&Sprocess_kill_without_query);
+ defsubr (&Sprocess_contact);
defsubr (&Slist_processes);
defsubr (&Sprocess_list);
defsubr (&Sstart_process);
run timer events directly.
(Callers that will immediately read keyboard events
call timer_delay on their own.) */
- if (1)
+ if (! wait_for_cell)
{
EMACS_TIME timer_delay;
int old_timers_run;
/* Check for keyboard input */
- if ((XINT (read_kbd) != 0 || wait_for_cell)
+ if ((XINT (read_kbd) != 0)
&& detect_input_pending_run_timers (do_display))
{
swallow_events (do_display);
break;
}
+ /* If wait_for_cell. check for keyboard input
+ but don't run any timers.
+ ??? (It seems wrong to me to check for keyboard
+ input at all when wait_for_cell, but the code
+ has been this way since July 1994.
+ Try changing this after version 19.31.) */
+ if (wait_for_cell
+ && detect_input_pending ())
+ {
+ swallow_events (do_display);
+ if (detect_input_pending ())
+ break;
+ }
+
/* Exit now if the cell we're waiting for became non-nil. */
if (wait_for_cell && ! NILP (*wait_for_cell))
break;