Пример #1
0
/* SHUTDOWN -- Call this to exit gracefully from the whole cl; never return.
 * Write out any remaining PF_UPDATE'd pfiles by restoring topd to just above
 *   first task unless we are in batch mode, then just flush io and die..
 * So that the restor will include the cl's pfile and any other pfiles that
 *   might have been cached or assigned into, we force its topd to be
 *   below its pfile head.  See the "pfp < topdp" loop in restor().
 * Don't bother with restor'ing if BATCH since we don't want to write out
 *   anything then anyway.
 */
static void
shutdown (void)
{
	float	cpu, clk;

	pr_dumpcache (0, YES);		/* flush process cache	*/
	clgflush();			/* flush graphics output */

	if (firstask->t_flags & T_BATCH) {
	    iofinish (currentask);
	    if (notify()) {
		cpu = (float)c_cputime(cpustart) / 1000.;
		clk = (float)c_clktime(clkstart);
		fprintf (stderr, "\n[%d] done  %.1f %.0m %d%%\n", bkgno,
		    cpu, clk/60., (int)((clk > 0 ? cpu / clk : 0.) * 100.));
	    }
	} else {
	    firstask->t_topd = dereference (firstask->t_ltp) + LTASKSIZ;
	    restor (firstask);
	}

	yy_startblock (LOG);			/* flush and close log	*/
	close_logfile (logfile());
	clexit();
}
Пример #2
0
Файл: bkg.c Проект: geechee/iraf
/* BKG_CLOSE -- Close a bkg job.  Called after determining that the job has
 * terminated.
 */
static void
bkg_close (
    int job,			/* job ordinal			*/
    int pmsg			/* print termination message	*/
)
{
	register struct	_bkgjob *bk = &jobtable[job-1];

	bk->b_clock = c_clktime (bk->b_clock);
	bk->b_exitcode = c_prcldpr (bk->b_jobno);
	bk->b_flags &= ~(J_RUNNING|J_SERVICE);

	if (bk->b_verbose && (pmsg > 1 || (pmsg == 1 && !notify()))) {
	    if (bk->b_exitcode != OK)
		eprintf ("[%d] exit %d\n", job, bk->b_exitcode);
	    else
		eprintf ("[%d] done\n", job);
	}

	/* Make a logfile entry, saying the background job ended.
	 */
	if (keeplog() && log_background()) {
	    char  buf[SZ_LINE];
	    sprintf (buf, "Stop [%d]", job);
	    putlog (0, buf);
	}
}
Пример #3
0
/* TODAY -- Get todays date as a string, for datestamping the logfile.
 */
char *
today (void)
{
	static	char datebuf[64];

	c_cnvtime (c_clktime(0L), datebuf, 64);
	return (datebuf);
}
Пример #4
0
Файл: bkg.c Проект: geechee/iraf
/* BKG_JOBSTATUS -- Print the status of one or more background jobs.
 * format jobno, elapsed clock time, status, user command, e.g.:
 *
 *		[1]   1:34  Running	command_1
 *		[2]  14:09  Stopped	command_2
 *		[3]   1:34 +Done 	command_3
 *		[4]   1:34  Exit 23	command_4
 *
 * A job will remain in the job table until another job is submitted which uses
 * the same slot.
 */
void 
bkg_jobstatus (
    FILE *fp,			/* output file		*/
    int job			/* job(s)		*/
)
{
	register struct _bkgjob *bk;
	register int	j, n, ch;
	register char	*ip;
	long	seconds;
	char	*outstr = NULL;

	bkg_update (1);
	for (bk=jobtable, j=1;  j <= NBKG;  j++, bk++)
	    if ((job == 0 && bk->b_jobno) || job == j) {
		/* Print jobno.  */
		fprintf (fp, "    [%d] ", j);

		/* If the clock is still running b_clock contains the start
		 * time.  If the job terminated it contains the elapsed time
		 * at job termination.
		 */
		if (busy(j))
		    seconds = c_clktime (bk->b_clock);
		else
		    seconds = bk->b_clock;
		fprintf (fp, "%6.0m ", (float)seconds / 60.0);
		fputc ((j == lastjobno) ? '+' : ' ', fp);
		    
		/* Print job status.
		 */
		if (busy(j)) {
		    if (bk->b_flags & J_SERVICE)
			outstr = "Stopped";
		    else
			outstr = "Running";
		} else if (bk->b_flags & J_KILLED) {
		    outstr = "Killed";
		} else if (bk->b_exitcode == OK) {
		    outstr = "Done";
		} else
		    sprintf (outstr, "Exit %d", bk->b_exitcode);
		fprintf (fp, "%-10s", outstr);

		/* Finally, print user command followed by newline.
		 */
		n = c_envgeti ("ttyncols") - (8 + 8 + 10) - 1;
		ip = bk->b_cmd;
		while (--n >= 0 && (ch = *ip++) != EOS)
		    if (ch == '\n' || ch == '\t')
			fputc (' ', fp);
		    else
			fputc (ch, fp);
		fputc ('\n', fp);
	    }
}
Пример #5
0
/* C_MAIN -- Called by the SPP procedure in cl.x to fire up the CL.
 * In effect we are chained to the IRAF Main, being called immediately after
 * the file system, etc. is initialized.  When we exit we signal that the
 * interpreter be skipped, proceeding directly to process shutdown.
 */
int
c_main (
  PKCHAR *cmd 			/* host command line			*/
)
{
	XINT	bp;

	/* Save the setjmp vector of the IRAF Main for restoration at clexit
	 * time.  We need to intercept all errors and do error recovery
	 * ourselves during normal execution, but when the CL exits we are
	 * not prepared to deal with errors occuring during shutdown.
	 */
	XMJBUF (&bp);  jumpcom = (long *)&Memc[bp];
	cl_amovi ((int *)jumpcom, (int *)jmp_save, LEN_JUMPBUF);

	/* Init clexit() in case we have to panic stop.  */
	if (setjmp (jmp_clexit))
	    goto exit_;

	/* Set up dictionary and catch signals.  If we are background, read in
	 * file and jump right into run, else hand craft first task.  Die if
	 * these fail.
	 */
	startup ();
	if (setjmp(child_startup)) {
	    cpustart = c_cputime (0L);
	    clkstart = c_clktime (0L);
	    execute (BACKGROUND);
	} else {
	    login ((char *) cmd);
	    execute (FOREGROUND);
	    logout();
	    execute (FOREGROUND);
	}

	shutdown();

exit_:
	/* Return to the IRAF Main.  The PR_EXIT code commands the main to
	 * skip the interpreter loop and shutdown.  Restore the error
	 * jump vector in the IRAF Main so that it can handle errors occuring
	 * during shutdown; we are turning control back over to the Main.
	 * This is ugly, but the real problem is the jump vectors.  There
	 * seems to be no alternative to this sort of thing...
	 */
	cl_amovi ((int *)jmp_save, (int *)jumpcom, LEN_JUMPBUF);
	return (PR_EXIT | (logout_status << 1));
}
Пример #6
0
Файл: bkg.c Проект: geechee/iraf
/* BKG_SPAWN -- Spawn a new background job.  Called by main() when we have
 * seen an '&'.
 */
void 
bkg_spawn (
    char *cmd		/* command entered by user to spawn job	*/
)
{
	register struct _bkgjob *bk;
	register int	jobno, stat;
	char	clprocess[SZ_PATHNAME];
	char	*wbkgfile();
	char	*bkgfile;

	/* Find first unused slot in a circular search.
	 */
	bkg_update (1);
	jobno = (lastjobno == NBKG) ? 1 : lastjobno + 1;
	while (jobno != lastjobno) {
	    if (!busy (jobno))
		break;
	    if (jobno++ >= NBKG)
		jobno = 1;
	}
	if (jobno == lastjobno)
	    cl_error (E_UERR, "no more background job slots");

	/* Write bkgfile.  Delete any dreg bkg communication files.
	 */
	bkg_delfiles (jobno);
	bkgfile = wbkgfile (jobno, cmd, NULL);

	/* Spawn bkg job.
	 */
	sprintf (clprocess, "%s%s", CLDIR, CLPROCESS);
	intr_disable();
	jobtable[jobno-1].b_jobno = stat =
	    c_propdpr (findexe (firstask->t_curpack, clprocess),
		bkgfile, bkgmsg);

	if (stat == NULL) {
	    c_delete (bkgfile);
	    intr_enable();
	    cl_error (E_IERR, "cannot spawn background CL");
	} else {
	    bk = &jobtable[jobno-1];
	    bk->b_flags = J_RUNNING;
	    bk->b_clock = c_clktime (0L);
            bk->b_verbose = 2;
	    strncpy (bk->b_cmd, cmd, SZ_CMD);
	    *(bk->b_cmd+SZ_CMD) = EOS;
	    intr_enable();
	}

	eprintf ("[%d]\n", lastjobno = jobno);

	/* Make a logfile entry, saying we started the background job.
	 */
	if (keeplog() && log_background()) {
	    char  buf[SZ_LINE];
	    sprintf (buf, "Start [%d]", jobno);
	    putlog (0, buf);
	}
}
Пример #7
0
/* EXECUTE -- Each loop corresponds to an exec in the interpreted code.
 * This occurs when a script task or process is ready to run.  In background
 * mode, we skip the preliminaries and jump right in and interpret the
 * compiled code.
 */
static void
execute (int mode)
{
	int	parsestat;
	XINT	old_parhead;
	char	*curcmd();

	alldone = 0;
	gologout = 0;
	if (mode == BACKGROUND) {
	    if (setjmp (jumpcom))
		onerr();
	    goto bkg;
	}

	/* Called when control stack contains only the firsttask.  ONEOF sets
	 * alldone true when eof/bye is seen and currentask=firstask,
	 * terminating the loop and returning to main.
	 */
	do {
	    /* Bkg_update() checks for blocked or finished bkg jobs and prints
	     * a message if it finds one.  This involves one or more access()
	     * calls so don't call it more than every 5 seconds.  The errenv
	     * jump vector is used by cl_error() for error restart.  The JUMPCOM
	     * vector is used to intercept system errors which would otherwise
	     * restart the CL.
	     */
	    if (currentask->t_flags & T_INTERACTIVE) {
		static	long last_clktime;

		if (c_clktime (last_clktime) > BKG_QUANTUM) {
		    last_clktime = c_clktime (0L);
		    bkg_update (1);
		}
		validerrenv = 1;
		setjmp (errenv);
		ninterrupts = 0;
		if (setjmp (jumpcom))
		    onerr();
	    } else if (!(currentask->t_flags & T_SCRIPT))
		setjmp (intenv);
    
	    pc = currentask->t_bascode;
	    currentask->t_topd = topd;
	    currentask->t_topcs = topcs;
	    recursion = 0;
	    errlev = 0;
	    c_erract (OK);
	    yeof = 0;

	    /* In the new CL the parser needs to know more about parameters
	     * than before.  Hence param files may be read in during parsing.
	     * Since we discard the dictionary after parsing we must unlink
	     * these param files, and re-read them when the
	     * program is run.  This is inefficient but appears to work.
	     */
	    old_parhead = parhead;

	    if (gologout)
		yeof++;
	    else {
		yy_startblock (LOG);		/* start new history blk   */
		parsestat = yyparse();		/* parse command block	   */
		topd = currentask->t_topd;	/* discard addconst()'s    */
		topcs = currentask->t_topcs;	/* discard compiler temps  */
		parhead = old_parhead;		/* forget param files.	   */
		if (parsestat != 0)
		    cl_error (E_IERR, "parser gagged");
	    }

	    if (dobkg) {
		bkg_spawn (curcmd());
	    } else {
bkg:
		if (yeof)
		    oneof();			/* restores previous task  */
		else {
		    /* set stack above pc, point pc back to code */
		    topos = basos = pc - 1;
		    pc = currentask->t_bascode;
		}

		if (!alldone)
		    run();			/* run code starting at pc */
	    }
	} until (alldone);
}