#define NUMERIC_ADDR_ERROR (numeric_addr == -1)
#endif
-#if defined(BSD) || defined(STRIDE)
+#if defined(BSD_SYSTEM) || defined(STRIDE)
#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 or STRIDE */
+#endif /* BSD_SYSTEM || STRIDE */
#ifdef BROKEN_O_NONBLOCK
#undef O_NONBLOCK
/* 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);
#ifdef BSD4_1
sighold (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
sigsetmask (sigmask (SIGCHLD));
#else /* ordinary USG */
#if 0
/* 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)
{
#ifdef BSD4_1
sigrelse (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
#if 0
#ifdef BSD4_1
sigrelse (SIGCHLD);
#else /* not BSD4_1 */
-#if defined (BSD) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
sigsetmask (SIGEMPTYMASK);
#else /* ordinary USG */
#if 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;
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)
{
#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
int count = specpdl_ptr - specpdl;
Lisp_Object odeactivate;
Lisp_Object obuffer, okeymap;
+ int outer_running_asynch_code = running_asynch_code;
/* 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. */
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 ();
+ restore_match_data ();
+ record_unwind_protect (Fstore_match_data, Fmatch_data ());
+ Fstore_match_data (tem);
+ }
+
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
running_asynch_code = 1;
+
+ /* Read and dispose of the process output. */
internal_condition_case_1 (read_process_output_call,
Fcons (outstream,
Fcons (proc,
Qnil))),
!NILP (Vdebug_on_error) ? Qnil : Qerror,
read_process_output_error_handler);
- running_asynch_code = 0;
+
+ /* If we saved the match data nonrecursively, restore it now. */
restore_match_data ();
+ running_asynch_code = outer_running_asynch_code;
/* Handling the process output should not deactivate the mark. */
Vdeactivate_mark = odeactivate;
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,
/* 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;
Lisp_Object sentinel, obuffer, odeactivate, okeymap;
register struct Lisp_Process *p = XPROCESS (proc);
int count = specpdl_ptr - specpdl;
+ int outer_running_asynch_code = running_asynch_code;
/* 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. */
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;
+ tem = Fmatch_data ();
+ restore_match_data ();
+ record_unwind_protect (Fstore_match_data, Fmatch_data ());
+ Fstore_match_data (tem);
+ }
+
+ /* For speed, if a search happens within this code,
+ save the match data in a special nonrecursive fashion. */
running_asynch_code = 1;
+
internal_condition_case_1 (read_process_output_call,
Fcons (sentinel,
Fcons (proc, Fcons (reason, Qnil))),
!NILP (Vdebug_on_error) ? Qnil : Qerror,
exec_sentinel_error_handler);
- running_asynch_code = 0;
+
+ /* If we saved the match data nonrecursively, restore it now. */
restore_match_data ();
+ running_asynch_code = outer_running_asynch_code;
Vdeactivate_mark = odeactivate;
#if 0
XSETINT (p->update_tick, XINT (p->tick));
/* If process is still active, read any output that remains. */
- if (XINT (p->infd) >= 0)
- while (! EQ (p->filter, Qt)
- && read_process_output (proc, XINT (p->infd)) > 0);
+ while (! EQ (p->filter, Qt)
+ && XINT (p->infd) >= 0
+ && read_process_output (proc, XINT (p->infd)) > 0);
buffer = p->buffer;
deactivate_process (proc);
}
+ /* 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. */
+ XSETINT (p->update_tick, XINT (p->tick));
/* Now output the message suitably. */
if (!NILP (p->sentinel))
exec_sentinel (proc, msg);
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);