set umask here until switchover (get it from init).
[unix-history] / usr / src / old / dbx / main.c
CommitLineData
00102538
ML
1/* Copyright (c) 1982 Regents of the University of California */
2
32a94702 3static char sccsid[] = "@(#)main.c 1.9 (Berkeley) %G%";
00102538
ML
4
5/*
6 * Debugger main routine.
7 */
8
9#include "defs.h"
10#include <setjmp.h>
11#include <signal.h>
12#include <errno.h>
13#include "main.h"
1c5b15ac 14#include "symbols.h"
00102538
ML
15#include "scanner.h"
16#include "process.h"
2fd0f574 17#include "runtime.h"
00102538
ML
18#include "source.h"
19#include "object.h"
1c5b15ac 20#include "mappings.h"
00102538
ML
21
22#ifndef public
23
24#define isterm(file) (interactive or isatty(fileno(file)))
25
39144fe1
ML
26#include <sgtty.h>
27
28typedef struct sgttyb Ttyinfo;
29
00102538
ML
30#endif
31
32public Boolean coredump; /* true if using a core dump */
33public Boolean runfirst; /* run program immediately */
34public Boolean interactive; /* standard input IS a terminal */
35public Boolean lexdebug; /* trace yylex return values */
36public Boolean tracebpts; /* trace create/delete breakpoints */
37public Boolean traceexec; /* trace process execution */
38public Boolean tracesyms; /* print symbols as their read */
2fd0f574 39public Boolean traceblocks; /* trace blocks while reading symbols */
00102538
ML
40
41public File corefile; /* File id of core dump */
42
43#define FIRST_TIME 0 /* initial value setjmp returns */
44
45private Boolean initdone = false; /* true if initialization done */
46private jmp_buf env; /* setjmp/longjmp data */
00102538
ML
47private char namebuf[512]; /* possible name of object file */
48private int firstarg; /* first program argument (for -r) */
49
39144fe1
ML
50private Ttyinfo ttyinfo;
51
00102538
ML
52private catchintr();
53
54/*
55 * Main program.
56 */
57
58main(argc, argv)
59int argc;
60String argv[];
61{
2fd0f574 62 register integer i;
39144fe1 63 extern String date;
2fd0f574 64 extern integer versionNumber;
00102538
ML
65
66 cmdname = argv[0];
67 catcherrs();
68 onsyserr(EINTR, nil);
a55f5f56 69 setlinebuf(stderr);
2fd0f574
SL
70 printf("dbx version %d of %s.\nType 'help' for help.\n",
71 versionNumber, date);
39144fe1 72 fflush(stdout);
00102538
ML
73 scanargs(argc, argv);
74 language_init();
75 process_init();
76 if (runfirst) {
77 if (setjmp(env) == FIRST_TIME) {
78 arginit();
79 for (i = firstarg; i < argc; i++) {
80 newarg(argv[i]);
81 }
82 run();
83 /* NOTREACHED */
84 } else {
85 runfirst = false;
86 }
87 } else {
88 init();
89 }
2fd0f574
SL
90 if (setjmp(env) != FIRST_TIME) {
91 restoretty(stdout, &ttyinfo);
92 }
00102538 93 signal(SIGINT, catchintr);
a55f5f56
SL
94 if (isterm(stdin)) {
95 printf("(%s) ", cmdname);
96 fflush(stdout);
97 }
98 endshellmode(); /* after an error longjmp */
99 startaliasing();
00102538
ML
100 yyparse();
101 putchar('\n');
102 quit(0);
103}
104
105/*
106 * Initialize the world, including setting initial input file
107 * if the file exists.
108 */
109
110public init()
111{
112 File f;
113 String home;
114 char buf[100];
115 extern String getenv();
116
39144fe1 117 savetty(stdout, &ttyinfo);
00102538
ML
118 enterkeywords();
119 scanner_init();
120 if (not coredump and not runfirst) {
121 start(nil, nil, nil);
122 }
39144fe1
ML
123 printf("reading symbolic information ...");
124 fflush(stdout);
00102538 125 readobj(objname);
39144fe1
ML
126 printf("\n");
127 fflush(stdout);
1c5b15ac 128 if (coredump) {
2fd0f574 129 setcurfunc(whatblock(pc));
1c5b15ac 130 } else {
2fd0f574 131 setcurfunc(program);
1c5b15ac 132 }
00102538
ML
133 bpinit();
134 f = fopen(initfile, "r");
135 if (f != nil) {
136 fclose(f);
137 setinput(initfile);
138 } else {
139 home = getenv("HOME");
140 if (home != nil) {
141 sprintf(buf, "%s/%s", home, initfile);
142 f = fopen(buf, "r");
143 if (f != nil) {
144 fclose(f);
145 setinput(strdup(buf));
146 }
147 }
148 }
149 initdone = true;
150}
151
152/*
153 * Re-initialize the world, first de-allocating all storage.
154 * This is necessary when the symbol information must be re-read
155 * from the object file when it has changed.
156 *
157 * Before "forgetting" things, we save the current tracing/breakpoint
158 * information to a temp file. Then after re-creating the world,
159 * we read the temp file as commands. This isn't always the right thing;
160 * if a procedure that was being traced is deleted, an error message
161 * will be generated.
162 *
163 * If the argument vector is not nil, then this is re-initialize is being
164 * done in preparation for running the program. Since we want to process
165 * the commands in the temp file before running the program, we add the
166 * run command at the end of the temp file. In this case, reinit longjmps
167 * back to parsing rather than returning.
168 */
169
170public reinit(argv, infile, outfile)
171String *argv;
172String infile;
173String outfile;
174{
175 register Integer i;
176 String tmpfile;
177 extern String mktemp();
178
179 tmpfile = mktemp("/tmp/dbxXXXX");
180 setout(tmpfile);
181 status();
182 print_alias(nil);
183 if (argv != nil) {
184 printf("run");
185 for (i = 1; argv[i] != nil; i++) {
186 printf(" %s", argv[i]);
187 }
188 if (infile != nil) {
189 printf(" < %s", infile);
190 }
191 if (outfile != nil) {
192 printf(" > %s", outfile);
193 }
194 putchar('\n');
195 }
196 unsetout();
197 bpfree();
198 objfree();
199 process_init();
200 enterkeywords();
201 scanner_init();
202 readobj(objname);
203 bpinit();
204 fflush(stdout);
205 setinput(tmpfile);
206 unlink(tmpfile);
207 if (argv != nil) {
208 longjmp(env, 1);
209 /* NOTREACHED */
210 }
211}
212
213/*
214 * After a non-fatal error we jump back to command parsing.
215 */
216
217public erecover()
218{
219 if (initdone) {
220 gobble();
221 longjmp(env, 1);
222 }
223}
224
225/*
226 * This routine is called when an interrupt occurs.
227 */
228
229private catchintr()
230{
231 putchar('\n');
232 longjmp(env, 1);
233}
234
235/*
236 * Scan the argument list.
237 */
238
239private scanargs(argc, argv)
240int argc;
241String argv[];
242{
243 register int i, j;
244 register Boolean foundfile;
245 register File f;
246 char *tmp;
247
248 runfirst = false;
249 interactive = false;
250 lexdebug = false;
251 tracebpts = false;
252 traceexec = false;
253 tracesyms = false;
2fd0f574 254 traceblocks = false;
00102538
ML
255 foundfile = false;
256 corefile = nil;
257 coredump = true;
258 sourcepath = list_alloc();
259 list_append(list_item("."), nil, sourcepath);
260 i = 1;
2fd0f574 261 while (i < argc and (not foundfile or corefile == nil)) {
00102538
ML
262 if (argv[i][0] == '-') {
263 if (streq(argv[i], "-I")) {
264 ++i;
265 if (i >= argc) {
266 fatal("missing directory for -I");
267 }
268 list_append(list_item(argv[i]), nil, sourcepath);
269 } else {
270 for (j = 1; argv[i][j] != '\0'; j++) {
271 setoption(argv[i][j]);
272 }
273 }
274 } else if (not foundfile) {
275 objname = argv[i];
276 foundfile = true;
277 } else if (coredump and corefile == nil) {
278 corefile = fopen(argv[i], "r");
279 if (corefile == nil) {
280 coredump = false;
281 }
282 }
283 ++i;
284 }
285 if (i < argc and not runfirst) {
286 fatal("extraneous argument %s", argv[i]);
287 }
288 firstarg = i;
289 if (not foundfile and isatty(0)) {
290 printf("enter object file name (default is `%s'): ", objname);
291 fflush(stdout);
292 gets(namebuf);
293 if (namebuf[0] != '\0') {
294 objname = namebuf;
295 }
296 }
297 f = fopen(objname, "r");
298 if (f == nil) {
299 fatal("can't read %s", objname);
300 } else {
301 fclose(f);
302 }
303 if (rindex(objname, '/') != nil) {
304 tmp = strdup(objname);
305 *(rindex(tmp, '/')) = '\0';
306 list_append(list_item(tmp), nil, sourcepath);
307 }
308 if (coredump and corefile == nil) {
309 corefile = fopen("core", "r");
310 if (corefile == nil) {
311 coredump = false;
312 }
313 }
314}
315
316/*
317 * Take appropriate action for recognized command argument.
318 */
319
320private setoption(c)
321char c;
322{
323 switch (c) {
324 case 'r': /* run program before accepting commands */
325 runfirst = true;
326 coredump = false;
327 break;
328
329 case 'i':
330 interactive = true;
331 break;
332
333 case 'b':
334 tracebpts = true;
335 break;
336
337 case 'e':
338 traceexec = true;
339 break;
340
341 case 's':
342 tracesyms = true;
343 break;
344
2fd0f574
SL
345 case 'n':
346 traceblocks = true;
347 break;
348
00102538 349 case 'l':
00102538 350 lexdebug = true;
00102538
ML
351 break;
352
353 default:
354 fatal("unknown option '%c'", c);
355 }
356}
357
39144fe1
ML
358/*
359 * Save/restore the state of a tty.
360 */
361
362public savetty(f, t)
363File f;
364Ttyinfo *t;
365{
a55f5f56 366 ioctl(fileno(f), TIOCGETP, t);
39144fe1
ML
367}
368
369public restoretty(f, t)
370File f;
371Ttyinfo *t;
372{
a55f5f56 373 ioctl(fileno(f), TIOCSETN, t);
39144fe1
ML
374}
375
00102538
ML
376/*
377 * Exit gracefully.
378 */
379
380public quit(r)
381Integer r;
382{
2fd0f574 383 pterm(process);
00102538
ML
384 exit(r);
385}