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