15509Slinton /* Copyright (c) 1982 Regents of the University of California */
25509Slinton 
3*6081Slinton static char sccsid[] = "@(#)runcont.c 1.4 03/08/82";
45509Slinton 
55509Slinton /*
65652Slinton  * Execution management.
75509Slinton  */
85509Slinton 
95509Slinton #include "defs.h"
105509Slinton #include <signal.h>
115509Slinton #include "process.h"
125509Slinton #include "machine.h"
135509Slinton #include "object.h"
145652Slinton #include "main.h"
155509Slinton #include "breakpoint.h"
165509Slinton #include "command.h"
175509Slinton #include "process.rep"
185509Slinton 
196073Slinton #define MAXNARGS 100        /* maximum number of arguments to RUN */
205509Slinton 
215652Slinton typedef char *String;
225509Slinton 
235509Slinton LOCAL BOOLEAN just_started;
245509Slinton LOCAL int argc;
255652Slinton LOCAL String argv[MAXNARGS];
265652Slinton LOCAL String infile;
275652Slinton LOCAL String outfile;
286073Slinton LOCAL PROCESS pbuf;
295509Slinton 
305509Slinton /*
315652Slinton  * This is a px-related kludge to deal with the possibility
325652Slinton  * of object code magically coming from a tmp file.
335509Slinton  */
345509Slinton 
355652Slinton LOCAL String mode;
365652Slinton LOCAL String realname;
375652Slinton 
385652Slinton setargs(m, r)
395652Slinton char *m, *r;
405652Slinton {
416073Slinton     mode = m;
426073Slinton     realname = r;
435652Slinton }
445652Slinton 
455652Slinton /*
465652Slinton  * Initialize the argument list.
475652Slinton  */
485652Slinton 
495509Slinton arginit()
505509Slinton {
516073Slinton     infile = NIL;
526073Slinton     outfile = NIL;
536073Slinton #   if (isvaxpx)
546073Slinton 	argv[0] = mode;
556073Slinton 	argv[1] = objname;
566073Slinton 	if (option('t') && realname == NIL) {
576073Slinton 	    argc = 2;
586073Slinton 	} else {
596073Slinton 	    argv[2] = realname;
606073Slinton 	    argc = 3;
616073Slinton 	}
626073Slinton #   else
636073Slinton 	argv[0] = objname;
646073Slinton 	argc = 1;
656073Slinton #   endif
665509Slinton }
675509Slinton 
685509Slinton /*
695652Slinton  * Add an argument to the list for the debuggee.
705509Slinton  */
715509Slinton 
725509Slinton newarg(arg)
735652Slinton String arg;
745509Slinton {
756073Slinton     if (argc >= MAXNARGS) {
766073Slinton 	error("too many arguments to run");
776073Slinton     }
786073Slinton     argv[argc++] = arg;
795509Slinton }
805509Slinton 
815509Slinton /*
825652Slinton  * Set the standard input for the debuggee.
835509Slinton  */
845509Slinton 
855509Slinton inarg(filename)
865652Slinton String filename;
875509Slinton {
886073Slinton     if (infile != NIL) {
896073Slinton 	error("multiple input redirects");
906073Slinton     }
916073Slinton     infile = filename;
925509Slinton }
935509Slinton 
945509Slinton /*
955652Slinton  * Set the standard output for the debuggee.
965652Slinton  * Probably should check to avoid overwriting an existing file.
975509Slinton  */
985509Slinton 
995509Slinton outarg(filename)
1005652Slinton String filename;
1015509Slinton {
1026073Slinton     if (outfile != NIL) {
1036073Slinton 	error("multiple output redirect");
1046073Slinton     }
1056073Slinton     outfile = filename;
1065509Slinton }
1075509Slinton 
1085509Slinton /*
1095652Slinton  * Initial start of the process.  The idea is to get it to the point
1105652Slinton  * where the object code has been loaded but execution has not begun.
1115509Slinton  */
1125509Slinton 
1135652Slinton initstart()
1145652Slinton {
1156073Slinton     arginit();
1166073Slinton     argv[argc] = NIL;
1176073Slinton     process = &pbuf;
1186073Slinton     initcache(process);
1196073Slinton     start(argv, infile, outfile);
120*6081Slinton     if (process->status != STOPPED) {
121*6081Slinton 	panic("could not start program");
122*6081Slinton     }
1235652Slinton }
1245652Slinton 
1255652Slinton /*
1265652Slinton  * Run starts debuggee executing.
1275652Slinton  */
1285652Slinton 
1295509Slinton run()
1305509Slinton {
1316073Slinton     fixbps();
1326073Slinton     curline = 0;
1336073Slinton     argv[argc] = NIL;
1346073Slinton     start(argv, infile, outfile);
135*6081Slinton     if (process->status == STOPPED) {
136*6081Slinton 	just_started = TRUE;
137*6081Slinton 	isstopped = FALSE;
138*6081Slinton 	cont();
139*6081Slinton     } else if (option('r')) {
140*6081Slinton 	panic("could not start program");
141*6081Slinton     }
1425509Slinton }
1435509Slinton 
1445509Slinton /*
1455652Slinton  * Continue execution wherever we left off.
1465509Slinton  *
1475509Slinton  * Note that this routine never returns.  Eventually bpact() will fail
1485509Slinton  * and we'll call printstatus or step will call it.
1495509Slinton  */
1505509Slinton 
1515509Slinton typedef int INTFUNC();
1525509Slinton 
1535509Slinton LOCAL INTFUNC *dbintr;
1545509Slinton LOCAL intr();
1555509Slinton 
1566073Slinton #define succeeds    == TRUE
1576073Slinton #define fails       == FALSE
1585509Slinton 
1595509Slinton cont()
1605509Slinton {
1616073Slinton     dbintr = signal(SIGINT, intr);
1626073Slinton     if (just_started) {
1636073Slinton 	just_started = FALSE;
1646073Slinton     } else {
1656073Slinton 	if (!isstopped) {
1666073Slinton 	    error("can't continue execution");
1676073Slinton 	}
1686073Slinton 	isstopped = FALSE;
1696073Slinton 	step();
1706073Slinton     }
1716073Slinton     for (;;) {
1726073Slinton 	if (single_stepping) {
1736073Slinton 	    printnews();
1745509Slinton 	} else {
1756073Slinton 	    setallbps();
1766073Slinton 	    resume();
1776073Slinton 	    unsetallbps();
1786073Slinton 	    if (bpact() fails) {
1796073Slinton 		printstatus();
1806073Slinton 	    }
1815509Slinton 	}
1826073Slinton 	step();
1836073Slinton     }
1846073Slinton     /* NOTREACHED */
1855509Slinton }
1865509Slinton 
1875509Slinton /*
1885509Slinton  * This routine is called if we get an interrupt while "running" px
1895509Slinton  * but actually in the debugger.  Could happen, for example, while
1905509Slinton  * processing breakpoints.
1915509Slinton  *
1925509Slinton  * We basically just want to keep going; the assumption is
1935509Slinton  * that when the process resumes it will get the interrupt
1945509Slinton  * which will then be handled.
1955509Slinton  */
1965509Slinton 
1975509Slinton LOCAL intr()
1985509Slinton {
1996073Slinton     signal(SIGINT, intr);
2005509Slinton }
2015509Slinton 
2025509Slinton fixintr()
2035509Slinton {
2046073Slinton     signal(SIGINT, dbintr);
2055509Slinton }
206