1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)runcont.c 1.5 03/15/82";
4 
5 /*
6  * Execution management.
7  */
8 
9 #include "defs.h"
10 #include <signal.h>
11 #include "process.h"
12 #include "machine.h"
13 #include "object.h"
14 #include "main.h"
15 #include "breakpoint.h"
16 #include "command.h"
17 #include "process.rep"
18 
19 #define MAXNARGS 100        /* maximum number of arguments to RUN */
20 
21 typedef char *String;
22 
23 LOCAL BOOLEAN just_started;
24 LOCAL int argc;
25 LOCAL String argv[MAXNARGS];
26 LOCAL String infile;
27 LOCAL String outfile;
28 LOCAL PROCESS pbuf;
29 PROCESS *process = &pbuf;
30 
31 /*
32  * This is a px-related kludge to deal with the possibility
33  * of object code magically coming from a tmp file.
34  */
35 
36 LOCAL String mode;
37 LOCAL String realname;
38 
39 setargs(m, r)
40 char *m, *r;
41 {
42     mode = m;
43     realname = r;
44 }
45 
46 /*
47  * Initialize the argument list.
48  */
49 
50 arginit()
51 {
52     infile = NIL;
53     outfile = NIL;
54 #   if (isvaxpx)
55 	argv[0] = mode;
56 	argv[1] = objname;
57 	if (option('t') && realname == NIL) {
58 	    argc = 2;
59 	} else {
60 	    argv[2] = realname;
61 	    argc = 3;
62 	}
63 #   else
64 	argv[0] = objname;
65 	argc = 1;
66 #   endif
67 }
68 
69 /*
70  * Add an argument to the list for the debuggee.
71  */
72 
73 newarg(arg)
74 String arg;
75 {
76     if (argc >= MAXNARGS) {
77 	error("too many arguments to run");
78     }
79     argv[argc++] = arg;
80 }
81 
82 /*
83  * Set the standard input for the debuggee.
84  */
85 
86 inarg(filename)
87 String filename;
88 {
89     if (infile != NIL) {
90 	error("multiple input redirects");
91     }
92     infile = filename;
93 }
94 
95 /*
96  * Set the standard output for the debuggee.
97  * Probably should check to avoid overwriting an existing file.
98  */
99 
100 outarg(filename)
101 String filename;
102 {
103     if (outfile != NIL) {
104 	error("multiple output redirect");
105     }
106     outfile = filename;
107 }
108 
109 /*
110  * Initial start of the process.  The idea is to get it to the point
111  * where the object code has been loaded but execution has not begun.
112  */
113 
114 initstart()
115 {
116     arginit();
117     argv[argc] = NIL;
118     initcache(process);
119     start(argv, infile, outfile);
120     if (process->status != STOPPED) {
121 	panic("could not start program");
122     }
123 }
124 
125 /*
126  * Run starts debuggee executing.
127  */
128 
129 run()
130 {
131     fixbps();
132     curline = 0;
133     argv[argc] = NIL;
134     start(argv, infile, outfile);
135     if (process->status == STOPPED) {
136 	just_started = TRUE;
137 	isstopped = FALSE;
138 	cont();
139     } else if (option('r')) {
140 	panic("could not start program");
141     }
142 }
143 
144 /*
145  * Continue execution wherever we left off.
146  *
147  * Note that this routine never returns.  Eventually bpact() will fail
148  * and we'll call printstatus or step will call it.
149  */
150 
151 typedef int INTFUNC();
152 
153 LOCAL INTFUNC *dbintr;
154 LOCAL intr();
155 
156 #define succeeds    == TRUE
157 #define fails       == FALSE
158 
159 cont()
160 {
161     dbintr = signal(SIGINT, intr);
162     if (just_started) {
163 	just_started = FALSE;
164     } else {
165 	if (!isstopped) {
166 	    error("can't continue execution");
167 	}
168 	isstopped = FALSE;
169 	step();
170     }
171     for (;;) {
172 	if (single_stepping) {
173 	    printnews();
174 	} else {
175 	    setallbps();
176 	    resume();
177 	    unsetallbps();
178 	    if (bpact() fails) {
179 		printstatus();
180 	    }
181 	}
182 	step();
183     }
184     /* NOTREACHED */
185 }
186 
187 /*
188  * This routine is called if we get an interrupt while "running" px
189  * but actually in the debugger.  Could happen, for example, while
190  * processing breakpoints.
191  *
192  * We basically just want to keep going; the assumption is
193  * that when the process resumes it will get the interrupt
194  * which will then be handled.
195  */
196 
197 LOCAL intr()
198 {
199     signal(SIGINT, intr);
200 }
201 
202 fixintr()
203 {
204     signal(SIGINT, dbintr);
205 }
206