1*22513Sdist /*
2*22513Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22513Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22513Sdist  * specifies the terms and conditions for redistribution.
5*22513Sdist  */
65509Slinton 
7*22513Sdist #ifndef lint
8*22513Sdist static char sccsid[] = "@(#)runcont.c	5.1 (Berkeley) 06/06/85";
9*22513Sdist #endif not lint
105509Slinton 
115509Slinton /*
125652Slinton  * Execution management.
135509Slinton  */
145509Slinton 
155509Slinton #include "defs.h"
165509Slinton #include <signal.h>
175509Slinton #include "process.h"
185509Slinton #include "machine.h"
195509Slinton #include "object.h"
205652Slinton #include "main.h"
215509Slinton #include "breakpoint.h"
225509Slinton #include "command.h"
235509Slinton #include "process.rep"
245509Slinton 
256073Slinton #define MAXNARGS 100        /* maximum number of arguments to RUN */
265509Slinton 
275652Slinton typedef char *String;
285509Slinton 
295509Slinton LOCAL BOOLEAN just_started;
305509Slinton LOCAL int argc;
315652Slinton LOCAL String argv[MAXNARGS];
325652Slinton LOCAL String infile;
335652Slinton LOCAL String outfile;
346073Slinton LOCAL PROCESS pbuf;
356240Slinton PROCESS *process = &pbuf;
365509Slinton 
375509Slinton /*
385652Slinton  * This is a px-related kludge to deal with the possibility
395652Slinton  * of object code magically coming from a tmp file.
405509Slinton  */
415509Slinton 
425652Slinton LOCAL String mode;
435652Slinton LOCAL String realname;
445652Slinton 
455652Slinton setargs(m, r)
465652Slinton char *m, *r;
475652Slinton {
486073Slinton     mode = m;
496073Slinton     realname = r;
505652Slinton }
515652Slinton 
525652Slinton /*
535652Slinton  * Initialize the argument list.
545652Slinton  */
555652Slinton 
565509Slinton arginit()
575509Slinton {
586073Slinton     infile = NIL;
596073Slinton     outfile = NIL;
606073Slinton #   if (isvaxpx)
616073Slinton 	argv[0] = mode;
626073Slinton 	argv[1] = objname;
636073Slinton 	if (option('t') && realname == NIL) {
646073Slinton 	    argc = 2;
656073Slinton 	} else {
666073Slinton 	    argv[2] = realname;
676073Slinton 	    argc = 3;
686073Slinton 	}
696073Slinton #   else
706073Slinton 	argv[0] = objname;
716073Slinton 	argc = 1;
726073Slinton #   endif
735509Slinton }
745509Slinton 
755509Slinton /*
765652Slinton  * Add an argument to the list for the debuggee.
775509Slinton  */
785509Slinton 
795509Slinton newarg(arg)
805652Slinton String arg;
815509Slinton {
826073Slinton     if (argc >= MAXNARGS) {
836073Slinton 	error("too many arguments to run");
846073Slinton     }
856073Slinton     argv[argc++] = arg;
865509Slinton }
875509Slinton 
885509Slinton /*
895652Slinton  * Set the standard input for the debuggee.
905509Slinton  */
915509Slinton 
925509Slinton inarg(filename)
935652Slinton String filename;
945509Slinton {
956073Slinton     if (infile != NIL) {
966073Slinton 	error("multiple input redirects");
976073Slinton     }
986073Slinton     infile = filename;
995509Slinton }
1005509Slinton 
1015509Slinton /*
1025652Slinton  * Set the standard output for the debuggee.
1035652Slinton  * Probably should check to avoid overwriting an existing file.
1045509Slinton  */
1055509Slinton 
1065509Slinton outarg(filename)
1075652Slinton String filename;
1085509Slinton {
1096073Slinton     if (outfile != NIL) {
1106073Slinton 	error("multiple output redirect");
1116073Slinton     }
1126073Slinton     outfile = filename;
1135509Slinton }
1145509Slinton 
1155509Slinton /*
1165652Slinton  * Initial start of the process.  The idea is to get it to the point
1175652Slinton  * where the object code has been loaded but execution has not begun.
1185509Slinton  */
1195509Slinton 
1205652Slinton initstart()
1215652Slinton {
1226073Slinton     arginit();
1236073Slinton     argv[argc] = NIL;
1246073Slinton     initcache(process);
1256073Slinton     start(argv, infile, outfile);
1266081Slinton     if (process->status != STOPPED) {
1276081Slinton 	panic("could not start program");
1286081Slinton     }
1295652Slinton }
1305652Slinton 
1315652Slinton /*
1325652Slinton  * Run starts debuggee executing.
1335652Slinton  */
1345652Slinton 
1355509Slinton run()
1365509Slinton {
1376073Slinton     fixbps();
1386073Slinton     curline = 0;
1396073Slinton     argv[argc] = NIL;
1406073Slinton     start(argv, infile, outfile);
1416081Slinton     if (process->status == STOPPED) {
1426081Slinton 	just_started = TRUE;
1436081Slinton 	isstopped = FALSE;
1446081Slinton 	cont();
1456081Slinton     } else if (option('r')) {
1466081Slinton 	panic("could not start program");
1476081Slinton     }
1485509Slinton }
1495509Slinton 
1505509Slinton /*
1515652Slinton  * Continue execution wherever we left off.
1525509Slinton  *
1535509Slinton  * Note that this routine never returns.  Eventually bpact() will fail
1545509Slinton  * and we'll call printstatus or step will call it.
1555509Slinton  */
1565509Slinton 
1575509Slinton typedef int INTFUNC();
1585509Slinton 
1595509Slinton LOCAL INTFUNC *dbintr;
1605509Slinton LOCAL intr();
1615509Slinton 
1626073Slinton #define succeeds    == TRUE
1636073Slinton #define fails       == FALSE
1645509Slinton 
1655509Slinton cont()
1665509Slinton {
1676073Slinton     dbintr = signal(SIGINT, intr);
1686073Slinton     if (just_started) {
1696073Slinton 	just_started = FALSE;
1706073Slinton     } else {
1716073Slinton 	if (!isstopped) {
1726073Slinton 	    error("can't continue execution");
1736073Slinton 	}
1746073Slinton 	isstopped = FALSE;
1756073Slinton 	step();
1766073Slinton     }
1776073Slinton     for (;;) {
1786073Slinton 	if (single_stepping) {
1796073Slinton 	    printnews();
1805509Slinton 	} else {
1816073Slinton 	    setallbps();
1826073Slinton 	    resume();
1836073Slinton 	    unsetallbps();
1846073Slinton 	    if (bpact() fails) {
1856073Slinton 		printstatus();
1866073Slinton 	    }
1875509Slinton 	}
1886073Slinton 	step();
1896073Slinton     }
1906073Slinton     /* NOTREACHED */
1915509Slinton }
1925509Slinton 
1935509Slinton /*
1945509Slinton  * This routine is called if we get an interrupt while "running" px
1955509Slinton  * but actually in the debugger.  Could happen, for example, while
1965509Slinton  * processing breakpoints.
1975509Slinton  *
1985509Slinton  * We basically just want to keep going; the assumption is
1995509Slinton  * that when the process resumes it will get the interrupt
2005509Slinton  * which will then be handled.
2015509Slinton  */
2025509Slinton 
2035509Slinton LOCAL intr()
2045509Slinton {
2056073Slinton     signal(SIGINT, intr);
2065509Slinton }
2075509Slinton 
2085509Slinton fixintr()
2095509Slinton {
2106073Slinton     signal(SIGINT, dbintr);
2115509Slinton }
212