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