]> code.delx.au - gnu-emacs/blobdiff - src/process.c
(Fredisplay): Doc fix.
[gnu-emacs] / src / process.c
index a17ef0e0915e9c35051ed9beb3fce794504119b3..857d7494c698556f1f91445fe71a675ae0f6c24d 100644 (file)
@@ -695,6 +695,8 @@ setup_process_coding_systems (process)
       = (struct coding_system *) xmalloc (sizeof (struct coding_system));
   setup_coding_system (p->encode_coding_system,
                       proc_encode_coding_system[outch]);
+  if (proc_encode_coding_system[outch]->eol_type == CODING_EOL_UNDECIDED)
+    proc_encode_coding_system[outch]->eol_type = system_eol_type;
 }
 \f
 DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0,
@@ -776,6 +778,16 @@ get_process (name)
   return proc;
 }
 
+
+#ifdef SIGCHLD
+/* Fdelete_process promises to immediately forget about the process, but in
+   reality, Emacs needs to remember those processes until they have been
+   treated by sigchld_handler; otherwise this handler would consider the
+   process as being synchronous and say that the synchronous process is
+   dead.  */
+static Lisp_Object deleted_pid_list;
+#endif
+
 DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
        doc: /* Delete PROCESS: kill it and forget about it immediately.
 PROCESS may be a process, a buffer, the name of a process or buffer, or
@@ -797,12 +809,31 @@ nil, indicating the current buffer's process.  */)
     }
   else if (XINT (p->infd) >= 0)
     {
-      Fkill_process (process, Qnil);
-      /* Do this now, since remove_process will make sigchld_handler do nothing.  */
-      p->status
-       = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
-      XSETINT (p->tick, ++process_tick);
-      status_notify (p);
+#ifdef SIGCHLD
+      Lisp_Object symbol;
+
+      /* No problem storing the pid here, as it is still in Vprocess_alist.  */
+      deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
+                               /* GC treated elements set to nil.  */
+                               Fdelq (Qnil, deleted_pid_list));
+      /* If the process has already signaled, remove it from the list.  */
+      if (p->raw_status_new)
+       update_status (p);
+      symbol = p->status;
+      if (CONSP (p->status))
+       symbol = XCAR (p->status);
+      if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
+       Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
+      else
+#endif
+       {
+         Fkill_process (process, Qnil);
+         /* Do this now, since remove_process will make sigchld_handler do nothing.  */
+         p->status
+           = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
+         XSETINT (p->tick, ++process_tick);
+         status_notify (p);
+       }
     }
   remove_process (process);
   return Qnil;
@@ -2322,9 +2353,11 @@ get_lisp_to_sockaddr_size (address, familyp)
 }
 
 /* Convert an address object (vector or string) to an internal sockaddr.
-   Address format has already been validated by get_lisp_to_sockaddr_size,
-   but just to be nice, we return without doing anything
-   if FAMILY is not valid.  */
+
+   The address format has been basically validated by
+   get_lisp_to_sockaddr_size, but this does not mean FAMILY is valid;
+   it could have come from user data.  So if FAMILY is not valid,
+   we return after zeroing *SA.  */
 
 static void
 conv_lisp_to_sockaddr (family, address, sa, len)
@@ -2338,7 +2371,6 @@ conv_lisp_to_sockaddr (family, address, sa, len)
   register int i;
 
   bzero (sa, len);
-  sa->sa_family = family;
 
   if (VECTORP (address))
     {
@@ -2350,6 +2382,7 @@ conv_lisp_to_sockaddr (family, address, sa, len)
          i = XINT (p->contents[--len]);
          sin->sin_port = htons (i);
          cp = (unsigned char *)&sin->sin_addr;
+         sa->sa_family = family;
        }
 #ifdef AF_INET6
       else if (family == AF_INET6)
@@ -2365,7 +2398,7 @@ conv_lisp_to_sockaddr (family, address, sa, len)
                int j = XFASTINT (p->contents[i]) & 0xffff;
                ip6[i] = ntohs (j);
              }
-         return;
+         sa->sa_family = family;
        }
 #endif
       return;
@@ -2379,6 +2412,7 @@ conv_lisp_to_sockaddr (family, address, sa, len)
          cp = SDATA (address);
          for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++)
            sockun->sun_path[i] = *cp++;
+         sa->sa_family = family;
        }
 #endif
       return;
@@ -4130,6 +4164,25 @@ wait_reading_process_output_1 ()
 {
 }
 
+/* Use a wrapper around select to work around a bug in gdb 5.3.
+   Normally, the wrapper is optimzed away by inlining.
+
+   If emacs is stopped inside select, the gdb backtrace doesn't
+   show the function which called select, so it is practically
+   impossible to step through wait_reading_process_output.  */
+
+#ifndef select
+static INLINE int
+select_wrapper (n, rfd, wfd, xfd, tmo)
+  int n;
+  SELECT_TYPE *rfd, *wfd, *xfd;
+  EMACS_TIME *tmo;
+{
+  return select (n, rfd, wfd, xfd, tmo);
+}
+#define select select_wrapper
+#endif
+
 /* Read and dispose of subprocess output while waiting for timeout to
    elapse and/or keyboard input to be available.
 
@@ -5063,6 +5116,10 @@ read_process_output (proc, channel)
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
                                   proc_encode_coding_system[XINT (p->outfd)]);
+             if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 == CODING_EOL_UNDECIDED)
+               proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 = system_eol_type;
            }
        }
 
@@ -5103,7 +5160,7 @@ read_process_output (proc, channel)
 #endif
        /* But do it only if the caller is actually going to read events.
           Otherwise there's no need to make him wake up, and it could
-          cause trouble (for example it would make Fsit_for return).  */
+          cause trouble (for example it would make sit_for return).  */
        if (waiting_for_user_input_p == -1)
          record_asynch_buffer_change ();
 
@@ -5170,6 +5227,10 @@ read_process_output (proc, channel)
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
                                   proc_encode_coding_system[XINT (p->outfd)]);
+             if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 == CODING_EOL_UNDECIDED)
+               proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 = system_eol_type;
            }
        }
       carryover = nbytes - coding->consumed;
@@ -5312,6 +5373,8 @@ send_process (proc, buf, len, object)
           sending a multibyte text, thus we must encode it by the
           original coding system specified for the current process.  */
        setup_coding_system (p->encode_coding_system, coding);
+      if (coding->eol_type == CODING_EOL_UNDECIDED)
+       coding->eol_type = system_eol_type;
       /* src_multibyte should be set to 1 _after_ a call to
         setup_coding_system, since it resets src_multibyte to
         zero.  */
@@ -6301,6 +6364,7 @@ kill_buffer_processes (buffer)
    ** Malloc WARNING: This should never call malloc either directly or
    indirectly; if it does, that is a bug  */
 
+#ifdef SIGCHLD
 SIGTYPE
 sigchld_handler (signo)
      int signo;
@@ -6358,6 +6422,15 @@ sigchld_handler (signo)
 
       /* Find the process that signaled us, and record its status.  */
 
+      /* The process can have been deleted by Fdelete_process.  */
+      tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list);
+      if (!NILP (tail))
+       {
+         Fsetcar (tail, Qnil);
+         goto sigchld_end_of_loop;
+       }
+
+      /* Otherwise, if it is asynchronous, it is in Vprocess_alist.  */
       p = 0;
       for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
        {
@@ -6409,8 +6482,8 @@ sigchld_handler (signo)
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
-       /* There was no asynchronous process found for that id.  Check
-          if we have a synchronous process.  */
+      /* There was no asynchronous process found for that pid: we have
+        a synchronous process.  */
       else
        {
          synch_process_alive = 0;
@@ -6427,6 +6500,9 @@ sigchld_handler (signo)
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
+    sigchld_end_of_loop:
+      ;
+
       /* On some systems, we must return right away.
         If any more processes want to signal us, we will
         get another signal.
@@ -6443,6 +6519,7 @@ sigchld_handler (signo)
 #endif /* USG, but not HPUX with WNOHANG */
     }
 }
+#endif /* SIGCHLD */
 \f
 
 static Lisp_Object
@@ -6530,7 +6607,7 @@ exec_sentinel (proc, reason)
 #endif
     /* But do it only if the caller is actually going to read events.
        Otherwise there's no need to make him wake up, and it could
-       cause trouble (for example it would make Fsit_for return).  */
+       cause trouble (for example it would make sit_for return).  */
     if (waiting_for_user_input_p == -1)
       record_asynch_buffer_change ();
 
@@ -6828,6 +6905,9 @@ init_process ()
   FD_SET (0, &input_wait_mask);
 
   Vprocess_alist = Qnil;
+#ifdef SIGCHLD
+  deleted_pid_list = Qnil;
+#endif
   for (i = 0; i < MAXDESC; i++)
     {
       chan_process[i] = Qnil;
@@ -6966,6 +7046,9 @@ syms_of_process ()
   staticpro (&Qlast_nonmenu_event);
 
   staticpro (&Vprocess_alist);
+#ifdef SIGCHLD
+  staticpro (&deleted_pid_list);
+#endif
 
   DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
               doc: /* *Non-nil means delete processes immediately when they exit.