XEmacs 21.2.20 "Yoko".
[chise/xemacs-chise.git.1] / src / process-unix.c
index 6be1c1a..b4a612e 100644 (file)
@@ -1,4 +1,4 @@
-/* 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.
@@ -37,11 +37,9 @@ Boston, MA 02111-1307, USA.  */
 #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"
@@ -62,7 +60,7 @@ Boston, MA 02111-1307, USA.  */
 
 
 /*
- * Implemenation-specific data. Pointed to by Lisp_Process->process_data
+ * Implementation-specific data. Pointed to by Lisp_Process->process_data
  */
 
 struct unix_process_data
@@ -214,9 +212,11 @@ allocate_pty (void)
      end of the ptys.  */
   int failed_count = 0;
 #endif
-  int i;
   int fd;
+#ifndef HAVE_GETPT
+  int i;
   int c;
+#endif
 
 #ifdef PTY_ITERATION
   PTY_ITERATION
@@ -236,7 +236,7 @@ allocate_pty (void)
 #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)
@@ -250,11 +250,7 @@ allocate_pty (void)
          }
        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 */
 
@@ -267,7 +263,7 @@ allocate_pty (void)
 #else
             sprintf (pty_name, "/dev/tty%c%x", c, i);
 #endif /* no PTY_TTY_NAME_SPRINTF */
-#ifndef UNIPLUS
+#if !defined(UNIPLUS) && !defined(HAVE_GETPT)
            if (access (pty_name, 6) != 0)
              {
                close (fd);
@@ -390,7 +386,7 @@ set_socket_nonblocking_maybe (int fd, int port, CONST char* proto)
          else
            continue;
        }
-      else if ((INTP (tail_port)) && (htons ((unsigned short) XINT (tail_port)) == port))
+      else if (INTP (tail_port) && (htons ((unsigned short) XINT (tail_port)) == port))
        break;
     }
 
@@ -669,14 +665,13 @@ unix_alloc_process_data (struct Lisp_Process *p)
  */
 
 static void
-unix_mark_process_data (struct Lisp_Process *proc,
-                       void (*markobj) (Lisp_Object))
+unix_mark_process_data (struct Lisp_Process *proc)
 {
-  ((markobj) (UNIX_DATA(proc)->tty_name));
+  mark_object (UNIX_DATA(proc)->tty_name);
 }
 
 /*
- * Initialize XEmacs process implemenation once
+ * Initialize XEmacs process implementation once
  */
 
 #ifdef SIGCHLD
@@ -704,11 +699,11 @@ unix_init_process_io_handles (struct Lisp_Process *p, void* in, void* out, int f
 }
 
 /*
- * 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.
  */
@@ -720,30 +715,13 @@ unix_create_process (struct Lisp_Process *p,
 {
   /* 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))
@@ -761,7 +739,7 @@ unix_create_process (struct Lisp_Process *p,
         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).  */
@@ -802,14 +780,6 @@ unix_create_process (struct Lisp_Process *p,
     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)
       {
@@ -925,28 +895,42 @@ unix_create_process (struct Lisp_Process *p,
               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.          
+              process group.
            */
            signal (SIGHUP, SIG_DFL);
          }
+
+       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
@@ -986,19 +970,16 @@ unix_create_process (struct Lisp_Process *p,
 
 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)
@@ -1006,9 +987,7 @@ 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)
@@ -1132,7 +1111,7 @@ unix_reap_exited_processes (void)
 #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;
@@ -1180,8 +1159,7 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream)
          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;
@@ -1207,7 +1185,7 @@ unix_send_process (Lisp_Object proc, struct lstream* lstream)
       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));
     }
@@ -1254,7 +1232,7 @@ unix_process_send_eof (Lisp_Object proc)
  * 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
@@ -1425,7 +1403,7 @@ unix_get_tty_name (struct Lisp_Process *p)
 /*
  * 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
@@ -1452,19 +1430,21 @@ unix_canonicalize_host_name (Lisp_Object host)
 
 static void
 unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service,
-                         Lisp_Object family, void** vinfd, void** voutfd)
+                         Lisp_Object protocol, void** vinfd, void** voutfd)
 {
   struct sockaddr_in address;
-  int s, inch, outch;
+  int inch;
+  int outch;
+  volatile int s;
   volatile int port;
   volatile int retry = 0;
   int retval;
 
   CHECK_STRING (host);
 
-  if (!EQ (family, Qtcpip))
-    error ("Unsupported protocol family \"%s\"",
-          string_data (symbol_name (XSYMBOL (family))));
+  if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp))
+    error ("Unsupported protocol \"%s\"",
+          string_data (symbol_name (XSYMBOL (protocol))));
 
   if (INTP (service))
     port = htons ((unsigned short) XINT (service));
@@ -1472,7 +1452,12 @@ unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object servic
     {
       struct servent *svc_info;
       CHECK_STRING (service);
-      svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
+
+      if (EQ (protocol, Qtcp))
+         svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
+      else /* EQ (protocol, Qudp) */
+         svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp");
+
       if (svc_info == 0)
        error ("Unknown service \"%s\"", XSTRING_DATA (service));
       port = svc_info->s_port;
@@ -1481,7 +1466,11 @@ unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object servic
   get_internet_address (host, &address, ERROR_ME);
   address.sin_port = port;
 
-  s = socket (address.sin_family, SOCK_STREAM, 0);
+  if (EQ (protocol, Qtcp))
+      s = socket (address.sin_family, SOCK_STREAM, 0);
+  else /* EQ (protocol, Qudp) */
+      s = socket (address.sin_family, SOCK_DGRAM, 0);
+
   if (s < 0)
     report_file_error ("error creating socket", list1 (name));
 
@@ -1575,7 +1564,7 @@ unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object servic
    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.
@@ -1656,7 +1645,7 @@ unix_open_multicast_group (Lisp_Object name, Lisp_Object dest, Lisp_Object port,
 
   /* 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. */