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 28 May 2006 15:29:27 -0000 *************** *** 778,783 **** --- 778,792 ---- return proc; } + + /* 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; + + 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 *************** *** 800,805 **** --- 809,818 ---- else if (XINT (p->infd) >= 0) { Fkill_process (process, Qnil); + /* No problem storing the pid here, as it is still in Vprocess_alist. */ + deleted_pid_list = Fcons (make_fixnum_or_float (p->pid), + /* GC handled elements set to nil. */ + Fdelq (Qnil, deleted_pid_list)); /* Do this now, since remove_process will make sigchld_handler do nothing. */ p->status = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)); *************** *** 6373,6445 **** /* Find the process that signaled us, and record its status. */ ! p = 0; ! for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) ! { ! proc = XCDR (XCAR (tail)); ! p = XPROCESS (proc); ! if (GC_EQ (p->childp, Qt) && p->pid == pid) ! break; p = 0; ! } ! /* Look for an asynchronous process whose pid hasn't been filled ! in yet. */ ! if (p == 0) ! for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) ! { ! proc = XCDR (XCAR (tail)); ! p = XPROCESS (proc); ! if (p->pid == -1) ! break; ! p = 0; ! } ! /* Change the status of the process that was found. */ ! if (p != 0) ! { ! union { int i; WAITTYPE wt; } u; ! int clear_desc_flag = 0; ! XSETINT (p->tick, ++process_tick); ! u.wt = w; ! p->raw_status = u.i; ! p->raw_status_new = 1; ! ! /* If process has terminated, stop waiting for its output. */ ! if ((WIFSIGNALED (w) || WIFEXITED (w)) ! && XINT (p->infd) >= 0) ! clear_desc_flag = 1; ! /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ ! if (clear_desc_flag) ! { ! FD_CLR (XINT (p->infd), &input_wait_mask); ! FD_CLR (XINT (p->infd), &non_keyboard_wait_mask); ! } ! /* Tell wait_reading_process_output that it needs to wake up and ! look around. */ ! if (input_available_clear_time) ! 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; ! /* Report the status of the synchronous process. */ ! if (WIFEXITED (w)) ! synch_process_retcode = WRETCODE (w); ! else if (WIFSIGNALED (w)) ! synch_process_termsig = WTERMSIG (w); ! ! /* Tell wait_reading_process_output that it needs to wake up and ! look around. */ ! if (input_available_clear_time) ! EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); } /* On some systems, we must return right away. --- 6386,6466 ---- /* 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); ! else ! { ! /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ p = 0; ! for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) ! { ! proc = XCDR (XCAR (tail)); ! p = XPROCESS (proc); ! if (GC_EQ (p->childp, Qt) && p->pid == pid) ! break; ! p = 0; ! } ! /* Look for an asynchronous process whose pid hasn't been filled ! in yet. */ ! if (p == 0) ! for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail)) ! { ! proc = XCDR (XCAR (tail)); ! p = XPROCESS (proc); ! if (p->pid == -1) ! break; ! p = 0; ! } ! /* Change the status of the process that was found. */ ! if (p != 0) ! { ! union { int i; WAITTYPE wt; } u; ! int clear_desc_flag = 0; ! XSETINT (p->tick, ++process_tick); ! u.wt = w; ! p->raw_status = u.i; ! p->raw_status_new = 1; ! ! /* If process has terminated, stop waiting for its output. */ ! if ((WIFSIGNALED (w) || WIFEXITED (w)) ! && XINT (p->infd) >= 0) ! clear_desc_flag = 1; ! /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ ! if (clear_desc_flag) ! { ! FD_CLR (XINT (p->infd), &input_wait_mask); ! FD_CLR (XINT (p->infd), &non_keyboard_wait_mask); ! } ! /* Tell wait_reading_process_output that it needs to wake up and ! look around. */ ! if (input_available_clear_time) ! 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; ! /* Report the status of the synchronous process. */ ! if (WIFEXITED (w)) ! synch_process_retcode = WRETCODE (w); ! else if (WIFSIGNALED (w)) ! synch_process_termsig = WTERMSIG (w); ! ! /* Tell wait_reading_process_output that it needs to wake up and ! look around. */ ! if (input_available_clear_time) ! EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); ! } } /* On some systems, we must return right away. *************** *** 6843,6848 **** --- 6864,6870 ---- FD_SET (0, &input_wait_mask); Vprocess_alist = Qnil; + deleted_pid_list = Qnil; for (i = 0; i < MAXDESC; i++) { chan_process[i] = Qnil;