-/* Asynchronous subprocess implemenation for UNIX
+/* Asynchronous subprocess implementation for UNIX
Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995
Free Software Foundation, Inc.
Copyright (C) 1995 Sun Microsystems, Inc.
#include "lisp.h"
#include "buffer.h"
-#include "commands.h"
#include "events.h"
#include "frame.h"
#include "hash.h"
-#include "insdel.h"
#include "lstream.h"
#include "opaque.h"
#include "process.h"
/*
- * Implemenation-specific data. Pointed to by Lisp_Process->process_data
+ * Implementation-specific data. Pointed to by Lisp_Process->process_data
*/
struct unix_process_data
#else /* no PTY_OPEN */
#ifdef IRIS
/* Unusual IRIS code */
- *ptyv = open ("/dev/ptc", O_RDWR | O_NDELAY | OPEN_BINARY, 0);
+ *ptyv = open ("/dev/ptc", O_RDWR | O_NONBLOCK | OPEN_BINARY, 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 | OPEN_BINARY, 0);
-#else
- fd = open (pty_name, O_RDWR | O_NDELAY | OPEN_BINARY, 0);
-#endif
#endif /* not IRIS */
#endif /* no PTY_OPEN */
unix_mark_process_data (struct Lisp_Process *proc,
void (*markobj) (Lisp_Object))
{
- ((markobj) (UNIX_DATA(proc)->tty_name));
+ markobj (UNIX_DATA(proc)->tty_name);
}
/*
- * Initialize XEmacs process implemenation once
+ * Initialize XEmacs process implementation once
*/
#ifdef SIGCHLD
}
/*
- * Fork off a subprocess. P is a pointer to newly created subprocess
+ * Fork off a subprocess. P is a pointer to a newly created subprocess
* object. If this function signals, the caller is responsible for
* deleting (and finalizing) the process object.
*
- * The method must return PID of the new proces, a (positive??? ####) number
+ * The method must return PID of the new process, a (positive??? ####) number
* which fits into Lisp_Int. No return value indicates an error, the method
* must signal an error instead.
*/
{
/* This function rewritten by ben@xemacs.org. */
- int pid, inchannel, outchannel;
+ int pid;
+ int inchannel = -1;
+ int outchannel = -1;
/* Use volatile to protect variables from being clobbered by longjmp. */
- volatile int forkin, forkout;
+ volatile int forkin = -1;
+ volatile int forkout = -1;
volatile int pty_flag = 0;
- char **env;
- char **new_argv;
- char *current_dir;
- int i;
-
- env = environ;
-
- inchannel = outchannel = forkin = forkout = -1;
-
- /* Nothing below here GCs so our string pointers shouldn't move. */
- new_argv = alloca_array (char *, nargv + 2);
- new_argv[0] = (char *) XSTRING_DATA (program);
- for (i = 0; i < nargv; i++)
- {
- Lisp_Object tem = argv[i];
- CHECK_STRING (tem);
- new_argv[i + 1] = (char *) XSTRING_DATA (tem);
- }
- new_argv[i + 1] = 0;
- current_dir = (char *) XSTRING_DATA (cur_dir);
#ifdef HAVE_PTYS
if (!NILP (Vprocess_connection_type))
better error checking. */
#if !defined(USG)
/* On USG systems it does not work to open the pty's tty here
- and then close and reopen it in the child. */
+ and then close and reopen it in the child. */
#ifdef O_NOCTTY
/* Don't let this terminal become our controlling terminal
(in case we don't have one). */
char **save_environ = environ;
#endif
-#ifdef EMACS_BTL
- /* when performance monitoring is on, turn it off before the vfork(),
- as the child has no handler for the signal -- when back in the
- parent process, turn it back on if it was really on when you "turned
- it off" */
- int logging_on = cadillac_stop_logging (); /* #### rename me */
-#endif
-
pid = fork ();
if (pid == 0)
{
EMACS_SET_TTY_PROCESS_GROUP (xforkin, &piddly);
}
-# ifdef AIX
/* On AIX, we've disabled SIGHUP above once we start a
child on a pty. Now reenable it in the child, so it
- will die when we want it to. */
+ will die when we want it to.
+ JV: This needs to be done ALWAYS as we might have inherited
+ a SIG_IGN handling from our parent (nohup) and we are in new
+ process group.
+ */
signal (SIGHUP, SIG_DFL);
-# endif /* AIX */
}
+
+ if (pty_flag)
+ /* Set up the terminal characteristics of the pty. */
+ child_setup_tty (xforkout);
+
#endif /* HAVE_PTYS */
- signal (SIGINT, SIG_DFL);
+ signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
- if (pty_flag)
- {
- /* Set up the terminal characteristics of the pty. */
- child_setup_tty (xforkout);
- }
+ {
+ char *current_dir;
+ char **new_argv = alloca_array (char *, nargv + 2);
+ int i;
- child_setup (xforkin, xforkout, xforkout, new_argv, current_dir);
- }
-#ifdef EMACS_BTL
- else if (logging_on)
- cadillac_start_logging (); /* #### rename me */
-#endif
+ /* Nothing below here GCs so our string pointers shouldn't move. */
+ new_argv[0] = (char *) XSTRING_DATA (program);
+ for (i = 0; i < nargv; i++)
+ {
+ CHECK_STRING (argv[i]);
+ new_argv[i + 1] = (char *) XSTRING_DATA (argv[i]);
+ }
+ new_argv[i + 1] = 0;
+ GET_C_STRING_FILENAME_DATA_ALLOCA (cur_dir, current_dir);
+
+ child_setup (xforkin, xforkout, xforkout, new_argv, current_dir);
+ }
+
+ } /**** End of child code ****/
+
+ /**** Back in parent process ****/
#if !defined(__CYGWIN32__)
environ = save_environ;
#endif
io_failure:
{
- int temp = errno;
+ int save_errno = errno;
close_descriptor_pair (forkin, forkout);
close_descriptor_pair (inchannel, outchannel);
- errno = temp;
+ errno = save_errno;
report_file_error ("Opening pty or pipe", Qnil);
+ return 0; /* not reached */
}
-
- RETURN_NOT_REACHED (0);
}
-/*
- * Return nonzero if this process is a ToolTalk connection.
- */
+/* Return nonzero if this process is a ToolTalk connection. */
static int
unix_tooltalk_connection_p (struct Lisp_Process *p)
return UNIX_DATA(p)->connected_via_filedesc_p;
}
-/*
- * This is called to set process' virtual terminal size
- */
+/* This is called to set process' virtual terminal size */
static int
unix_set_window_size (struct Lisp_Process* p, int cols, int rows)
#endif /* SIGCHLD */
/*
- * Stuff the entire contents of LSTREAM to the process ouptut pipe
+ * Stuff the entire contents of LSTREAM to the process output pipe
*/
static JMP_BUF send_process_frame;
if (writeret < 0)
/* This is a real error. Blocking errors are handled
specially inside of the filedesc stream. */
- report_file_error ("writing to process",
- list1 (vol_proc));
+ report_file_error ("writing to process", list1 (proc));
while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
{
/* Buffer is full. Wait, accepting input;
else
{ /* We got here from a longjmp() from the SIGPIPE handler */
signal (SIGPIPE, old_sigpipe);
+ /* Close the file lstream so we don't attempt to write to it further */
+ /* #### There is controversy over whether this might cause fd leakage */
+ /* my tests say no. -slb */
+ XLSTREAM (p->pipe_outstream)->flags &= ~LSTREAM_FL_IS_OPEN;
p->status_symbol = Qexit;
p->exit_code = 256; /* #### SIGPIPE ??? */
p->core_dumped = 0;
p->tick++;
process_tick++;
- deactivate_process (vol_proc);
+ deactivate_process (*((Lisp_Object *) (&vol_proc)));
error ("SIGPIPE raised on process %s; closed it",
XSTRING_DATA (p->name));
}
* In the lack of this method, only event_stream_delete_stream_pair
* is called on both I/O streams of the process.
*
- * The UNIX version quards this by ignoring possible SIGPIPE.
+ * The UNIX version guards this by ignoring possible SIGPIPE.
*/
static USID
/*
* Canonicalize host name HOST, and return its canonical form
*
- * The default implemenation just takes HOST for a canonical name.
+ * The default implementation just takes HOST for a canonical name.
*/
#ifdef HAVE_SOCKETS
TCP case, the multicast connection will be seen as a sub-process,
Some notes:
- - Normaly, we should use sendto and recvfrom with non connected
+ - Normally, we should use sendto and recvfrom with non connected
sockets. The current code doesn't allow us to do this. In the future, it
would be a good idea to extend the process data structure in order to deal
properly with the different types network connections.
/* Socket configuration for writing ----------------------- */
- /* Normaly, there's no 'connect' in multicast, since we use preferentialy
+ /* Normally, there's no 'connect' in multicast, since we prefer to use
'sendto' and 'recvfrom'. However, in order to handle this connection in
the process-like way it is done for TCP, we must be able to use 'write'
instead of 'sendto'. Consequently, we 'connect' this socket. */