1 #ifndef lint 2 static char sccsid[] = "@(#)main.c 5.1 (Berkeley) 01/16/89"; 3 #endif 4 5 /* 6 * adb - main command loop and error/interrupt handling 7 */ 8 9 #include "defs.h" 10 #include <setjmp.h> 11 #include <sys/file.h> 12 #include <sys/uio.h> 13 14 extern char NOEOR[]; /* "newline expected" */ 15 16 /* 17 * executing is set by command.c whenever we are running a subprocess. 18 */ 19 int executing; 20 21 int infile; /* XXX */ 22 char *Ipath = "/usr/lib/adb";/* XXX */ 23 24 static int xargc; /* remembers argc for getfile() */ 25 26 static int reading; /* set whenever reading input */ 27 static jmp_buf mainloop; /* label for error jumps */ 28 29 int fault(); 30 off_t lseek(); 31 32 main(argc, argv) 33 register int argc; 34 register char **argv; 35 { 36 int waserr; 37 char line[LINELEN]; 38 39 radix = 16; /* default radix is hex */ 40 maxoff = MAXOFF; 41 maxcol = MAXCOL; 42 43 /* 44 * Set up machine dependent code (e.g., instruction decoding tables), 45 * then look at arguments, and open the object and core files; 46 * finally, set up signal handlers. Alas, cannot really use getopt. 47 */ 48 mch_init(); 49 symfile.name = "a.out"; 50 corefile.name = "core"; 51 while (argc > 1 && argv[1][0] == '-') { 52 register char *p = argv[1] + 1; 53 54 if (*p == 'w' && p[1] == 0) { 55 wtflag = 2; /* suitable for open() */ 56 argc--, argv++; 57 } else if (*p == 'k' && p[1] == 0) { 58 kernel = 1; 59 argc--, argv++; 60 } else if (*p == 'I') { 61 Ipath = argv[1] + 2; 62 argc--, argv++; 63 } else 64 break; 65 } 66 if (argc > 1) 67 symfile.name = argv[1]; 68 if (argc > 2) 69 corefile.name = argv[2]; 70 xargc = argc; /* remember for getfile() */ 71 setsym(); 72 setcore(); 73 if ((sigint = signal(SIGINT, SIG_IGN)) != SIG_IGN) { 74 intcatch = fault; 75 (void) signal(SIGINT, fault); 76 } 77 sigquit = signal(SIGQUIT, SIG_IGN); 78 79 /* 80 * Errors jump back to the main loop here. 81 * If the error occurred while the process was running, 82 * we need to remove any breakpoints. 83 */ 84 (void) setjmp(mainloop); 85 if (executing) { 86 executing = 0; 87 delbp(); 88 } 89 90 /* 91 * Main loop: 92 * flush pending output, and print any error message(s); 93 * read a line; if end of file, close current input and 94 * continue, unless input == stdin; otherwise, perform 95 * the command(s) on the line and make sure that that 96 * consumed the whole line. 97 */ 98 for (;;) { 99 flushbuf(); 100 if (errflag) { 101 adbprintf("%s\n", errflag); 102 waserr = 1; 103 errflag = NULL; 104 } 105 if (mkfault) { 106 mkfault = 0; 107 prints("\nadb\n"); 108 } 109 if (readline(line, sizeof line)) { 110 if (infile == 0) 111 done(waserr); 112 iclose(-1, 0); 113 } else { 114 waserr = 0; 115 command(line, 0); 116 if (/* lp && */ lastc != '\n') 117 errflag = NOEOR; 118 } 119 } 120 } 121 122 /* 123 * Exit with optional error status. 124 */ 125 done(err) 126 int err; 127 { 128 129 endpcs(); 130 exit(err); 131 } 132 133 /* 134 * Open the a.out (1) or core (2) file. If the name was given, 135 * rather than defaulted, and we were asked to open for writing, 136 * create the file if necessary. 137 */ 138 getfile(which) 139 int which; 140 { 141 char *fname; 142 int flags, fd; 143 144 switch (which) { 145 case 1: 146 fname = symfile.name; 147 break; 148 case 2: 149 fname = corefile.name; 150 break; 151 default: 152 panic("getfile"); 153 /* NOTREACHED */ 154 } 155 if (fname[0] == '-' && fname[1] == 0) 156 return (-1); 157 if ((flags = wtflag) != 0 && xargc > which) 158 flags |= O_CREAT; 159 if ((fd = open(fname, flags, 0666)) < 0 && flags & O_CREAT) 160 adbprintf("cannot open `%s'\n", fname); 161 return (fd); 162 } 163 164 165 /* 166 * Input routines 167 */ 168 169 /* 170 * Read a character, skipping white space. 171 */ 172 rdc() 173 { 174 175 while (*lp == ' ' || *lp == '\t') 176 lp++; 177 return (readchar()); 178 } 179 180 #ifndef readchar 181 /* 182 * Read a character, incrementing the pointer if not at end. 183 */ 184 readchar() 185 { 186 187 if ((lastc = *lp) != 0) 188 lp++; 189 return (lastc); 190 } 191 #endif 192 193 /* 194 * Read a line. Return -1 at end of file. 195 * Alas, cannot read more than one character at a time here (except 196 * possibly on tty devices; must think about that later). 197 */ 198 static 199 readline(p, n) 200 register char *p; 201 register int n; 202 { 203 204 n--; /* for \0 */ 205 reading++; 206 do { 207 if (--n > 0) { 208 if (read(infile, p, 1) != 1) 209 return (-1); 210 } else 211 *p = '\n'; 212 } while (*p++ != '\n'); 213 reading = 0; 214 *p = 0; /* can we perhaps eliminate this? */ 215 return (0); 216 } 217 218 /* 219 * Return the next non-white non-end-of-line character. 220 */ 221 nextchar() 222 { 223 int c = rdc(); 224 225 if (eol(c)) { 226 unreadc(); 227 return (0); 228 } 229 return (c); 230 } 231 232 233 /* 234 * Error handlers 235 */ 236 237 #ifndef checkerr 238 /* 239 * If there has been an error or a fault, take the error. 240 */ 241 checkerr() 242 { 243 244 if (errflag || mkfault) 245 error(errflag); 246 } 247 #endif 248 249 /* 250 * An error occurred. Save the message for later printing, 251 * close open files, and reset to main command loop. 252 */ 253 error(which) 254 char *which; 255 { 256 257 errflag = which; 258 iclose(0, 1); 259 oclose(); 260 longjmp(mainloop, 1); 261 /* NOTREACHED */ 262 } 263 264 /* 265 * An interrupt occurred. Seek to the end of the current input file. 266 * If we were reading commands, jump back to the main loop. 267 */ 268 /* ARGSUSED */ 269 fault(sig) 270 int sig; 271 { 272 273 /* (void) signal(sig, fault); */ /* unnecessary */ 274 (void) lseek(infile, 0L, 2); 275 mkfault++; 276 if (reading) { 277 reading = 0; 278 error((char *)NULL); 279 } 280 } 281 282 /* 283 * Panic announces an internally detected error. 284 */ 285 panic(s) 286 char *s; 287 { 288 static char p[] = "panic: \n"; 289 static struct iovec iov[3] = { { p, 7 }, { 0 }, { p + 7, 1 } }; 290 291 iov[1].iov_base = s; 292 iov[1].iov_len = strlen(s); 293 (void) writev(2, iov, 3); 294 abort(); /* beware, overwrites current core file! */ 295 /* exit(1); */ 296 } 297