XEmacs 21.2.36 "Notos"
[chise/xemacs-chise.git] / src / process.c
index 028cfb4..5812151 100644 (file)
@@ -608,10 +608,24 @@ INCODE and OUTCODE specify the coding-system objects used in input/output
     }
   else
     {
-      if (!NILP (Ffile_directory_p (program)))
-       error ("Specified program for new process is a directory");
+      /* we still need to canonicalize it and ensure it has the proper
+        ending, e.g. .exe */
+      struct gcpro ngcpro1;
+
+      tem = Qnil;
+      NGCPRO1 (tem);
+      locate_file (list1 (build_string ("")), program, Vlisp_EXEC_SUFFIXES,
+                  &tem, X_OK);
+      if (NILP (tem))
+       report_file_error ("Searching for program", list1 (program));
+      program = tem;
+      NUNGCPRO;
     }
 
+  if (!NILP (Ffile_directory_p (program)))
+    invalid_operation ("Specified program for new process is a directory",
+                      program);
+
   proc = make_process_internal (name);
 
   XPROCESS (proc)->buffer = buffer;
@@ -664,7 +678,8 @@ INCODE and OUTCODE specify the coding-system objects used in input/output
    connection has no PID; you cannot signal it.  All you can do is
    deactivate and close it via delete-process */
 
-DEFUN ("open-network-stream-internal", Fopen_network_stream_internal, 4, 5, 0, /*
+DEFUN ("open-network-stream-internal", Fopen_network_stream_internal, 4, 5,
+       0, /*
 Open a TCP connection for a service to a host.
 Return a subprocess-object to represent the connection.
 Input and output work as for subprocesses; `delete-process' closes it.
@@ -682,7 +697,7 @@ Fifth argument PROTOCOL is a network protocol.  Currently 'tcp
  (Transmission Control Protocol) and 'udp (User Datagram Protocol) are
  supported.  When omitted, 'tcp is assumed.
 
-Ouput via `process-send-string' and input via buffer or filter (see
+Output via `process-send-string' and input via buffer or filter (see
 `set-process-filter') are stream-oriented.  That means UDP datagrams are
 not guaranteed to be sent and received in discrete packets. (But small
 datagrams around 500 bytes that are not truncated by `process-send-string'
@@ -1523,133 +1538,23 @@ If PROCESS has not yet exited or died, return 0.
 
 \f
 
-/* send a signal number SIGNO to PROCESS.
-   CURRENT_GROUP means send to the process group that currently owns
-   the terminal being used to communicate with PROCESS.
-   This is used for various commands in shell mode.
-   If NOMSG is zero, insert signal-announcements into process's buffers
-   right away.
-
-   If we can, we try to signal PROCESS by sending control characters
-   down the pty.  This allows us to signal inferiors who have changed
-   their uid, for which killpg would return an EPERM error.  */
-
-static void
-process_send_signal (Lisp_Object process, int signo,
-                     int current_group, int nomsg)
-{
-  /* This function can GC */
-  Lisp_Object proc = get_process (process);
-
-  if (network_connection_p (proc))
-    error ("Network connection %s is not a subprocess",
-          XSTRING_DATA (XPROCESS(proc)->name));
-  CHECK_LIVE_PROCESS (proc);
-
-  MAYBE_PROCMETH (kill_child_process, (proc, signo, current_group, nomsg));
-}
-
-DEFUN ("interrupt-process", Finterrupt_process, 0, 2, 0, /*
-Interrupt process PROCESS.  May be process or name of one.
-Nil or no arg means current buffer's process.
-Second arg CURRENT-GROUP non-nil means send signal to
-the current process-group of the process's controlling terminal
-rather than to the process's own process group.
-If the process is a shell, this means interrupt current subjob
-rather than the shell.
-*/
-       (process, current_group))
-{
-  /* This function can GC */
-  process_send_signal (process, SIGINT, !NILP (current_group), 0);
-  return process;
-}
-
-DEFUN ("kill-process", Fkill_process, 0, 2, 0, /*
-Kill process PROCESS.  May be process or name of one.
-See function `interrupt-process' for more details on usage.
-*/
-       (process, current_group))
-{
-  /* This function can GC */
-#ifdef SIGKILL
-  process_send_signal (process, SIGKILL, !NILP (current_group), 0);
-#else
-  error ("kill-process: Not supported on this system");
-#endif
-  return process;
-}
-
-DEFUN ("quit-process", Fquit_process, 0, 2, 0, /*
-Send QUIT signal to process PROCESS.  May be process or name of one.
-See function `interrupt-process' for more details on usage.
-*/
-       (process, current_group))
-{
-  /* This function can GC */
-#ifdef SIGQUIT
-  process_send_signal (process, SIGQUIT, !NILP (current_group), 0);
-#else
-  error ("quit-process: Not supported on this system");
-#endif
-  return process;
-}
-
-DEFUN ("stop-process", Fstop_process, 0, 2, 0, /*
-Stop process PROCESS.  May be process or name of one.
-See function `interrupt-process' for more details on usage.
-*/
-       (process, current_group))
-{
-  /* This function can GC */
-#ifdef SIGTSTP
-  process_send_signal (process, SIGTSTP, !NILP (current_group), 0);
-#else
-  error ("stop-process: Not supported on this system");
-#endif
-  return process;
-}
-
-DEFUN ("continue-process", Fcontinue_process, 0, 2, 0, /*
-Continue process PROCESS.  May be process or name of one.
-See function `interrupt-process' for more details on usage.
-*/
-       (process, current_group))
+static int
+decode_signal (Lisp_Object signal_)
 {
-  /* This function can GC */
-#ifdef SIGCONT
-  process_send_signal (process, SIGCONT, !NILP (current_group), 0);
-#else
-  error ("continue-process: Not supported on this system");
-#endif
-  return process;
-}
-
-DEFUN ("signal-process", Fsignal_process, 2, 2,
-       "nProcess number: \nnSignal code: ", /*
-Send the process with process id PID the signal with code SIGCODE.
-PID must be an integer.  The process need not be a child of this Emacs.
-SIGCODE may be an integer, or a symbol whose name is a signal name.
-*/
-       (pid, sigcode))
-{
-  CHECK_INT (pid);
-
-  if (INTP (sigcode))
-    ;
+  if (INTP (signal_))
+    return XINT (signal_);
   else
     {
       Bufbyte *name;
 
-      CHECK_SYMBOL (sigcode);
-      name = string_data (XSYMBOL (sigcode)->name);
+      CHECK_SYMBOL (signal_);
+      name = string_data (XSYMBOL (signal_)->name);
 
-#define handle_signal(signal)                          \
-  else if (!strcmp ((const char *) name, #signal))     \
-    XSETINT (sigcode, signal)
+#define handle_signal(sym) do {                                \
+       if (!strcmp ((const char *) name, #sym))        \
+         return sym;                                   \
+      } while (0)
 
-      if (0)
-       ;
       handle_signal (SIGINT);  /* ANSI */
       handle_signal (SIGILL);  /* ANSI */
       handle_signal (SIGABRT); /* ANSI */
@@ -1783,14 +1688,145 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.
 #ifdef SIGPWR
       handle_signal (SIGPWR);
 #endif
-      else
-       error ("Undefined signal name %s", name);
-    }
 
 #undef handle_signal
 
+      error ("Undefined signal name %s", name);
+      return 0; /* Unreached */
+    }
+}
+
+/* Send signal number SIGNO to PROCESS.
+   CURRENT-GROUP non-nil means send signal to the current
+   foreground process group of the process's controlling terminal rather
+   than to the process's own process group.
+   This is used for various commands in shell mode.
+   If NOMSG is zero, insert signal-announcements into process's buffers
+   right away.
+
+   If we can, we try to signal PROCESS by sending control characters
+   down the pty.  This allows us to signal inferiors who have changed
+   their uid, for which kill() would return an EPERM error, or to
+   processes running on another computer through a remote login.  */
+
+static void
+process_send_signal (Lisp_Object process, int signo,
+                     int current_group, int nomsg)
+{
+  /* This function can GC */
+  Lisp_Object proc = get_process (process);
+
+  if (network_connection_p (proc))
+    error ("Network connection %s is not a subprocess",
+          XSTRING_DATA (XPROCESS(proc)->name));
+  CHECK_LIVE_PROCESS (proc);
+
+  MAYBE_PROCMETH (kill_child_process, (proc, signo, current_group, nomsg));
+}
+
+DEFUN ("process-send-signal", Fprocess_send_signal, 1, 3, 0, /*
+Send signal SIGNAL to process PROCESS.
+SIGNAL may be an integer, or a symbol naming a signal, like `SIGSEGV'.
+PROCESS may be a process, a buffer, the name of a process or buffer, or
+nil, indicating the current buffer's process.
+Third arg CURRENT-GROUP non-nil means send signal to the current
+foreground process group of the process's controlling terminal rather
+than to the process's own process group.
+If the process is a shell that supports job control, this means
+send the signal to the current subjob rather than the shell.
+*/
+       (signal_, process, current_group))
+{
+  /* This function can GC */
+  process_send_signal (process, decode_signal (signal_),
+                      !NILP (current_group), 0);
+  return process;
+}
+
+DEFUN ("interrupt-process", Finterrupt_process, 0, 2, 0, /*
+Interrupt process PROCESS.
+See function `process-send-signal' for more details on usage.
+*/
+       (process, current_group))
+{
+  /* This function can GC */
+  process_send_signal (process, SIGINT, !NILP (current_group), 0);
+  return process;
+}
+
+DEFUN ("kill-process", Fkill_process, 0, 2, 0, /*
+Kill process PROCESS.
+See function `process-send-signal' for more details on usage.
+*/
+       (process, current_group))
+{
+  /* This function can GC */
+#ifdef SIGKILL
+  process_send_signal (process, SIGKILL, !NILP (current_group), 0);
+#else
+  error ("kill-process: Not supported on this system");
+#endif
+  return process;
+}
+
+DEFUN ("quit-process", Fquit_process, 0, 2, 0, /*
+Send QUIT signal to process PROCESS.
+See function `process-send-signal' for more details on usage.
+*/
+       (process, current_group))
+{
+  /* This function can GC */
+#ifdef SIGQUIT
+  process_send_signal (process, SIGQUIT, !NILP (current_group), 0);
+#else
+  error ("quit-process: Not supported on this system");
+#endif
+  return process;
+}
+
+DEFUN ("stop-process", Fstop_process, 0, 2, 0, /*
+Stop process PROCESS.
+See function `process-send-signal' for more details on usage.
+*/
+       (process, current_group))
+{
+  /* This function can GC */
+#ifdef SIGTSTP
+  process_send_signal (process, SIGTSTP, !NILP (current_group), 0);
+#else
+  error ("stop-process: Not supported on this system");
+#endif
+  return process;
+}
+
+DEFUN ("continue-process", Fcontinue_process, 0, 2, 0, /*
+Continue process PROCESS.
+See function `process-send-signal' for more details on usage.
+*/
+       (process, current_group))
+{
+  /* This function can GC */
+#ifdef SIGCONT
+  process_send_signal (process, SIGCONT, !NILP (current_group), 0);
+#else
+  error ("continue-process: Not supported on this system");
+#endif
+  return process;
+}
+
+DEFUN ("signal-process", Fsignal_process, 2, 2,
+       "nProcess number: \nnSignal code: ", /*
+Send the process with process id PID the signal with code SIGNAL.
+PID must be an integer.  The process need not be a child of this Emacs.
+SIGNAL may be an integer, or a symbol naming a signal, like `SIGSEGV'.
+*/
+       (pid, signal_))
+{
+  CHECK_INT (pid);
+
   return make_int (PROCMETH_OR_GIVEN (kill_process_by_pid,
-                                     (XINT (pid), XINT (sigcode)), -1));
+                                     (XINT (pid), decode_signal (signal_)),
+                                     -1));
 }
 
 DEFUN ("process-send-eof", Fprocess_send_eof, 0, 1, 0, /*
@@ -2039,6 +2075,7 @@ syms_of_process (void)
 #endif /* HAVE_SOCKETS */
   DEFSUBR (Fprocess_send_region);
   DEFSUBR (Fprocess_send_string);
+  DEFSUBR (Fprocess_send_signal);
   DEFSUBR (Finterrupt_process);
   DEFSUBR (Fkill_process);
   DEFSUBR (Fquit_process);