示例#1
0
文件: exec.c 项目: geechee/iraf
/* KILLTASK -- Abort the currently executing task.  Only call this when a task
 *  is to be killed spontaneously, as from interrupt, not when it is just dying
 *   due to a "bye" or eof.
 * Close all pipes and pseudofiles, being careful not to close any that
 *   are real stdio files.
 * Note that our function is to kill an external task, not the process in which
 *   it resides.  The process is left running in the cache in case it is needed
 *   again.
 */
void
killtask (
  register struct task *tp
)
{
	char	buf[128];

	/* Print stack trace, with arguments.
	 */
	if (!(tp->t_ltp->lt_flags&LT_INVIS) && !(firstask->t_flags&T_BATCH) &&
	    !(strcmp (tp->t_ltp->lt_lname, "error") == 0))
	    printcall (currentask->t_stderr, tp);

	/* If task is running in a subprocess, interrupt it and read the ERROR
	 * message.  Not certain there isn't some case where this could cause
	 * deadlock, but it does not seem so.  Interrupts are disabled during
	 * process startup.  If task issues ERROR then it is popped before
	 * we are called, without issuing the signal.
	 */
	if (tp->t_pid != -1) {
	    fflush (tp->t_out);
	    c_prsignal (tp->t_pid, X_INT);
	    fgets (buf, 128, tp->t_in);
	}

	iofinish (tp);
}
示例#2
0
文件: main.c 项目: olebole/iraf
/* ARGSUSED */
void
onint (
  int	*vex,			/* virtual exception code	*/
  int	(**next_handler)(void) 	/* next handler to be called	*/
)
{
	if (firstask->t_flags & T_BATCH) {
	    /* Batch task.
	     */
	    iofinish (currentask);
	    bkg_abort();
	    clexit();

	} else if (currentask->t_flags & (T_SCRIPT|T_CL|T_BUILTIN)) {
	    /* CL task.
	     */
	    cl_error (E_UERR, "interrupt!!!");

	} else {
	    /* External task connected via IPC.  Pass the interrupt on to
	     * the child.
	     */
	    c_prsignal (currentask->t_pid, X_INT);

	    /* Cancel any output and disable i/o on the tasks pseudofiles.
	     * This is necessary to cancel any i/o still buffered in the
	     * IPC channel.  Commonly when the task is writing to STDOUT,
	     * for example, the CL will be writing the last buffer sent
	     * to the terminal, while the task waits after having already
	     * pushed the next buffer into the IPC.  When we resume reading
	     * from the task we will see this buffered output on the next
	     * read and we wish to discard it.  Leave STDERR connected to
	     * give a path to the terminal for recovery actions such as
	     * turning standout or graphics mode off.  This gives the task
	     * a chance to cleanup but does not permit full recovery.  The
	     * pseudofiles will be reconnected for the next task run.
	     */
	    c_fseti (fileno(stdout),            F_CANCEL, OK);
	    c_fseti (fileno(currentask->t_in),  F_CANCEL, OK);
	    c_fseti (fileno(currentask->t_out), F_CANCEL, OK);

	    c_prredir (currentask->t_pid, STDIN, 0);
	    c_prredir (currentask->t_pid, STDOUT, 0);

	    /* If a subprocess is repeatedly interrupted we assume that it
	     * is hung in a loop and abort, advising the user to kill the
	     * process.
	     */
	    if (++ninterrupts >= MAX_INTERRUPTS)
		cl_error (E_UERR, "subprocess is hung; should be killed");
	    else
		longjmp (intenv, 1);
	}

	*next_handler = NULL;
}