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