Index: src/process.c =================================================================== RCS file: /sources/emacs/emacs/src/process.c,v retrieving revision 1.481 diff -c -r1.481 process.c *** src/process.c 8 May 2006 05:19:42 -0000 1.481 --- src/process.c 30 May 2006 12:35:10 -0000 *************** *** 778,783 **** --- 778,793 ---- 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 *************** *** 799,810 **** } 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); } remove_process (process); return Qnil; --- 809,839 ---- } else if (XINT (p->infd) >= 0) { ! #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; *************** *** 6316,6321 **** --- 6345,6351 ---- ** 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; *************** *** 6373,6378 **** --- 6403,6417 ---- /* 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)) { *************** *** 6424,6431 **** 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. */ else { synch_process_alive = 0; --- 6463,6470 ---- EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); } ! /* There was no asynchronous process found for that pid: we have ! a synchronous process. */ else { synch_process_alive = 0; *************** *** 6442,6447 **** --- 6481,6490 ---- 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. *************** *** 6458,6463 **** --- 6501,6507 ---- #endif /* USG, but not HPUX with WNOHANG */ } } + #endif /* SIGCHLD */ static Lisp_Object *************** *** 6843,6848 **** --- 6887,6895 ---- 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; *************** *** 6981,6986 **** --- 7028,7036 ---- 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.