1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)runcont.c 1.4 03/08/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 
30 /*
31  * This is a px-related kludge to deal with the possibility
32  * of object code magically coming from a tmp file.
33  */
34 
35 LOCAL String mode;
36 LOCAL String realname;
37 
38 setargs(m, r)
39 char *m, *r;
40 {
41     mode = m;
42     realname = r;
43 }
44 
45 /*
46  * Initialize the argument list.
47  */
48 
49 arginit()
50 {
51     infile = NIL;
52     outfile = NIL;
53 #   if (isvaxpx)
54 	argv[0] = mode;
55 	argv[1] = objname;
56 	if (option('t') && realname == NIL) {
57 	    argc = 2;
58 	} else {
59 	    argv[2] = realname;
60 	    argc = 3;
61 	}
62 #   else
63 	argv[0] = objname;
64 	argc = 1;
65 #   endif
66 }
67 
68 /*
69  * Add an argument to the list for the debuggee.
70  */
71 
72 newarg(arg)
73 String arg;
74 {
75     if (argc >= MAXNARGS) {
76 	error("too many arguments to run");
77     }
78     argv[argc++] = arg;
79 }
80 
81 /*
82  * Set the standard input for the debuggee.
83  */
84 
85 inarg(filename)
86 String filename;
87 {
88     if (infile != NIL) {
89 	error("multiple input redirects");
90     }
91     infile = filename;
92 }
93 
94 /*
95  * Set the standard output for the debuggee.
96  * Probably should check to avoid overwriting an existing file.
97  */
98 
99 outarg(filename)
100 String filename;
101 {
102     if (outfile != NIL) {
103 	error("multiple output redirect");
104     }
105     outfile = filename;
106 }
107 
108 /*
109  * Initial start of the process.  The idea is to get it to the point
110  * where the object code has been loaded but execution has not begun.
111  */
112 
113 initstart()
114 {
115     arginit();
116     argv[argc] = NIL;
117     process = &pbuf;
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