1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)runcont.c 1.3 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 }
121 
122 /*
123  * Run starts debuggee executing.
124  */
125 
126 run()
127 {
128     fixbps();
129     curline = 0;
130     argv[argc] = NIL;
131     start(argv, infile, outfile);
132     just_started = TRUE;
133     isstopped = FALSE;
134     cont();
135 }
136 
137 /*
138  * Continue execution wherever we left off.
139  *
140  * Note that this routine never returns.  Eventually bpact() will fail
141  * and we'll call printstatus or step will call it.
142  */
143 
144 typedef int INTFUNC();
145 
146 LOCAL INTFUNC *dbintr;
147 LOCAL intr();
148 
149 #define succeeds    == TRUE
150 #define fails       == FALSE
151 
152 cont()
153 {
154     dbintr = signal(SIGINT, intr);
155     if (just_started) {
156 	just_started = FALSE;
157     } else {
158 	if (!isstopped) {
159 	    error("can't continue execution");
160 	}
161 	isstopped = FALSE;
162 	step();
163     }
164     for (;;) {
165 	if (single_stepping) {
166 	    printnews();
167 	} else {
168 	    setallbps();
169 	    resume();
170 	    unsetallbps();
171 	    if (bpact() fails) {
172 		printstatus();
173 	    }
174 	}
175 	step();
176     }
177     /* NOTREACHED */
178 }
179 
180 /*
181  * This routine is called if we get an interrupt while "running" px
182  * but actually in the debugger.  Could happen, for example, while
183  * processing breakpoints.
184  *
185  * We basically just want to keep going; the assumption is
186  * that when the process resumes it will get the interrupt
187  * which will then be handled.
188  */
189 
190 LOCAL intr()
191 {
192     signal(SIGINT, intr);
193 }
194 
195 fixintr()
196 {
197     signal(SIGINT, dbintr);
198 }
199