15509Slinton /* Copyright (c) 1982 Regents of the University of California */
25509Slinton 
3*5652Slinton static char sccsid[] = "@(#)runcont.c 1.2 02/02/82";
45509Slinton 
55509Slinton /*
6*5652Slinton  * Execution management.
75509Slinton  */
85509Slinton 
95509Slinton #include "defs.h"
105509Slinton #include <signal.h>
115509Slinton #include "process.h"
125509Slinton #include "machine.h"
135509Slinton #include "object.h"
14*5652Slinton #include "main.h"
155509Slinton #include "breakpoint.h"
165509Slinton #include "command.h"
175509Slinton #include "process.rep"
185509Slinton 
19*5652Slinton #define MAXNARGS 100		/* maximum number of arguments to RUN */
205509Slinton 
21*5652Slinton typedef char *String;
225509Slinton 
235509Slinton LOCAL BOOLEAN just_started;
245509Slinton LOCAL int argc;
25*5652Slinton LOCAL String argv[MAXNARGS];
26*5652Slinton LOCAL String infile;
27*5652Slinton LOCAL String outfile;
285509Slinton 
295509Slinton /*
30*5652Slinton  * This is a px-related kludge to deal with the possibility
31*5652Slinton  * of object code magically coming from a tmp file.
325509Slinton  */
335509Slinton 
34*5652Slinton LOCAL String mode;
35*5652Slinton LOCAL String realname;
36*5652Slinton 
37*5652Slinton setargs(m, r)
38*5652Slinton char *m, *r;
39*5652Slinton {
40*5652Slinton 	mode = m;
41*5652Slinton 	realname = r;
42*5652Slinton }
43*5652Slinton 
44*5652Slinton /*
45*5652Slinton  * Initialize the argument list.
46*5652Slinton  */
47*5652Slinton 
485509Slinton arginit()
495509Slinton {
505509Slinton 	infile = NIL;
515509Slinton 	outfile = NIL;
525509Slinton #	if (isvaxpx)
53*5652Slinton 		argv[0] = mode;
54*5652Slinton 		argv[1] = objname;
55*5652Slinton 		if (option('t') && realname == NIL) {
56*5652Slinton 			argc = 2;
57*5652Slinton 		} else {
58*5652Slinton 			argv[2] = realname;
59*5652Slinton 			argc = 3;
60*5652Slinton 		}
615509Slinton #	else
625509Slinton 		argv[0] = objname;
635509Slinton 		argc = 1;
645509Slinton #	endif
655509Slinton }
665509Slinton 
675509Slinton /*
68*5652Slinton  * Add an argument to the list for the debuggee.
695509Slinton  */
705509Slinton 
715509Slinton newarg(arg)
72*5652Slinton String arg;
735509Slinton {
745509Slinton 	if (argc >= MAXNARGS) {
75*5652Slinton 		error("too many arguments to run");
765509Slinton 	}
775509Slinton 	argv[argc++] = arg;
785509Slinton }
795509Slinton 
805509Slinton /*
81*5652Slinton  * Set the standard input for the debuggee.
825509Slinton  */
835509Slinton 
845509Slinton inarg(filename)
85*5652Slinton String filename;
865509Slinton {
875509Slinton 	if (infile != NIL) {
885509Slinton 		error("multiple input redirects");
895509Slinton 	}
905509Slinton 	infile = filename;
915509Slinton }
925509Slinton 
935509Slinton /*
94*5652Slinton  * Set the standard output for the debuggee.
95*5652Slinton  * Probably should check to avoid overwriting an existing file.
965509Slinton  */
975509Slinton 
985509Slinton outarg(filename)
99*5652Slinton String filename;
1005509Slinton {
1015509Slinton 	if (outfile != NIL) {
1025509Slinton 		error("multiple output redirect");
1035509Slinton 	}
1045509Slinton 	outfile = filename;
1055509Slinton }
1065509Slinton 
1075509Slinton /*
108*5652Slinton  * Initial start of the process.  The idea is to get it to the point
109*5652Slinton  * where the object code has been loaded but execution has not begun.
1105509Slinton  */
1115509Slinton 
112*5652Slinton initstart()
113*5652Slinton {
114*5652Slinton 	arginit();
115*5652Slinton 	argv[argc] = NIL;
116*5652Slinton 	start(argv, infile, outfile);
117*5652Slinton }
118*5652Slinton 
119*5652Slinton /*
120*5652Slinton  * Run starts debuggee executing.
121*5652Slinton  */
122*5652Slinton 
1235509Slinton run()
1245509Slinton {
1255509Slinton 	fixbps();
1265509Slinton 	curline = 0;
127*5652Slinton 	argv[argc] = NIL;
1285509Slinton 	start(argv, infile, outfile);
1295509Slinton 	just_started = TRUE;
1305509Slinton 	isstopped = FALSE;
1315509Slinton 	cont();
1325509Slinton }
1335509Slinton 
1345509Slinton /*
135*5652Slinton  * Continue execution wherever we left off.
1365509Slinton  *
1375509Slinton  * Note that this routine never returns.  Eventually bpact() will fail
1385509Slinton  * and we'll call printstatus or step will call it.
1395509Slinton  */
1405509Slinton 
1415509Slinton typedef int INTFUNC();
1425509Slinton 
1435509Slinton LOCAL INTFUNC *dbintr;
1445509Slinton LOCAL intr();
1455509Slinton 
1465509Slinton #define succeeds	== TRUE
1475509Slinton #define fails		== FALSE
1485509Slinton 
1495509Slinton cont()
1505509Slinton {
1515509Slinton 	dbintr = signal(SIGINT, &intr);
1525509Slinton 	if (just_started) {
1535509Slinton 		just_started = FALSE;
1545509Slinton 	} else {
1555509Slinton 		if (!isstopped) {
1565509Slinton 			error("can't continue execution");
1575509Slinton 		}
1585509Slinton 		isstopped = FALSE;
1595509Slinton 		step();
1605509Slinton 	}
1615509Slinton 	for (;;) {
1625509Slinton 		if (single_stepping) {
1635509Slinton 			printnews();
1645509Slinton 		} else {
1655509Slinton 			setallbps();
1665509Slinton 			resume();
1675509Slinton 			unsetallbps();
1685509Slinton 			if (bpact() fails) {
1695509Slinton 				printstatus();
1705509Slinton 			}
1715509Slinton 		}
1725509Slinton 		step();
1735509Slinton 	}
174*5652Slinton 	/* NOTREACHED */
1755509Slinton }
1765509Slinton 
1775509Slinton /*
1785509Slinton  * This routine is called if we get an interrupt while "running" px
1795509Slinton  * but actually in the debugger.  Could happen, for example, while
1805509Slinton  * processing breakpoints.
1815509Slinton  *
1825509Slinton  * We basically just want to keep going; the assumption is
1835509Slinton  * that when the process resumes it will get the interrupt
1845509Slinton  * which will then be handled.
1855509Slinton  */
1865509Slinton 
1875509Slinton LOCAL intr()
1885509Slinton {
1895509Slinton 	signal(SIGINT, &intr);
1905509Slinton }
1915509Slinton 
1925509Slinton fixintr()
1935509Slinton {
1945509Slinton 	signal(SIGINT, &dbintr);
1955509Slinton }
196