|
|
1.1 ! root 1: /************************************************************************* ! 2: * This program is copyright (C) 1985, 1986 by Jonathan Payne. It is * ! 3: * provided to you without charge for use only on a licensed Unix * ! 4: * system. You may copy JOVE provided that this notice is included with * ! 5: * the copy. You may not sell copies of this program or versions * ! 6: * modified for use on microcomputer systems, unless the copies are * ! 7: * included with a Unix system distribution and the source is provided. * ! 8: *************************************************************************/ ! 9: ! 10: #ifdef BSD4_2 ! 11: # include <sys/wait.h> ! 12: #else ! 13: # include <wait.h> ! 14: #endif ! 15: #include <signal.h> ! 16: #include <sgtty.h> ! 17: ! 18: typedef struct process Process; ! 19: ! 20: #define DEAD 1 /* Dead but haven't informed user yet */ ! 21: #define STOPPED 2 /* Job stopped */ ! 22: #define RUNNING 3 /* Just running */ ! 23: #define NEW 4 /* This process is brand new */ ! 24: ! 25: /* If process is dead, flags says how. */ ! 26: #define EXITED 1 ! 27: #define KILLED 2 ! 28: ! 29: #define isdead(p) (p == 0 || proc_state(p) == DEAD || p->p_fd == -1) ! 30: ! 31: #define proc_buf(p) (p->p_buffer->b_name) ! 32: #define proc_cmd(p) (p->p_name) ! 33: #define proc_state(p) (p->p_state) ! 34: ! 35: struct process { ! 36: Process *p_next; ! 37: int p_fd, /* File descriptor of ptyp? opened r/w */ ! 38: p_pid; /* pid of child (the shell) */ ! 39: Buffer *p_buffer; /* Add output to end of this buffer */ ! 40: char *p_name; /* ... */ ! 41: char p_state, /* State */ ! 42: p_howdied, /* Killed? or Exited? */ ! 43: p_reason, /* If signaled, p_reason is the signal; else ! 44: it is the the exit code */ ! 45: p_eof; /* Received EOF, so can be free'd up */ ! 46: Mark *p_mark; /* Where output left us. */ ! 47: data_obj ! 48: *p_cmd; /* Command to call when process dies */ ! 49: } *procs = 0, ! 50: *cur_proc = 0; ! 51: ! 52: char proc_prompt[80] = "% "; ! 53: ! 54: int global_fd = 1, ! 55: NumProcs = 0; ! 56: ! 57: #ifdef BRLUNIX ! 58: extern struct sg_brl sg1; ! 59: #else ! 60: extern struct sgttyb sg1; ! 61: #endif ! 62: ! 63: extern struct tchars tc1; ! 64: ! 65: #ifdef TIOCSLTC ! 66: extern struct ltchars ls1; ! 67: #endif ! 68: ! 69: static char * ! 70: pstate(p) ! 71: Process *p; ! 72: { ! 73: switch (proc_state(p)) { ! 74: case STOPPED: ! 75: return "Stopped"; ! 76: ! 77: case RUNNING: ! 78: return "Running"; ! 79: ! 80: case DEAD: ! 81: if (p->p_howdied == EXITED) { ! 82: if (p->p_reason == 0) ! 83: return "Done"; ! 84: return sprint("exit(%d)", p->p_reason); ! 85: } ! 86: return sprint("Killed(%d)", p->p_reason); ! 87: ! 88: default: ! 89: return "Unknown state."; ! 90: } ! 91: } ! 92: ! 93: static Process * ! 94: proc_pid(pid) ! 95: { ! 96: register Process *p; ! 97: ! 98: for (p = procs; p != 0; p = p->p_next) ! 99: if (p->p_pid == pid) ! 100: break; ! 101: ! 102: return p; ! 103: } ! 104: ! 105: read_proc(fd) ! 106: register int fd; ! 107: { ! 108: register Process *p; ! 109: unsigned int n; ! 110: char ibuf[1024]; ! 111: ! 112: for (p = procs; p != 0; p = p->p_next) ! 113: if (p->p_fd == fd) ! 114: break; ! 115: ! 116: if (p == 0) { ! 117: printf("\riproc: unknown fd %d", fd); ! 118: return; ! 119: } ! 120: ! 121: n = read(fd, ibuf, sizeof(ibuf) - 1); ! 122: ! 123: if (n == 0) { ! 124: proc_close(p); ! 125: NumProcs--; ! 126: return; ! 127: } ! 128: ! 129: ibuf[n] = '\0'; ! 130: proc_rec(p, ibuf); ! 131: redisplay(); ! 132: } ! 133: ! 134: ProcKill() ! 135: { ! 136: register Buffer *b; ! 137: register Process *p; ! 138: Process *buf_to_proc(); ! 139: char *bname; ! 140: ! 141: bname = ask_buf(cur_proc ? cur_proc->p_buffer : (Buffer *) 0); ! 142: ! 143: if ((b = buf_exists(bname)) == 0) ! 144: complain("[No such buffer]"); ! 145: if ((p = buf_to_proc(b)) == 0) ! 146: complain("%s not tied to a process.", bname); ! 147: proc_kill(p, SIGKILL); ! 148: } ! 149: ! 150: Process * ! 151: buf_to_proc(b) ! 152: register Buffer *b; ! 153: { ! 154: register Process *p; ! 155: ! 156: for (p = procs; p != 0; p = p->p_next) ! 157: if (p->p_buffer == b) ! 158: return p; ! 159: return 0; ! 160: } ! 161: ! 162: ProcCont() ! 163: { ! 164: if (cur_proc == 0) ! 165: complain("[No processes]"); ! 166: if (cur_proc->p_state != DEAD) { ! 167: proc_kill(cur_proc, SIGCONT); ! 168: cur_proc->p_state = RUNNING; ! 169: } ! 170: } ! 171: ! 172: ProcEof() ! 173: { ! 174: send_p(tc1.t_eofc); ! 175: } ! 176: ! 177: ProcInt() ! 178: { ! 179: send_p(tc1.t_intrc); ! 180: } ! 181: ! 182: ProcQuit() ! 183: { ! 184: send_p(tc1.t_quitc); ! 185: } ! 186: ! 187: #ifdef TIOCSLTC ! 188: ! 189: ProcStop() ! 190: { ! 191: send_p(ls1.t_suspc); ! 192: } ! 193: ! 194: ProcDStop() ! 195: { ! 196: send_p(ls1.t_dsuspc); ! 197: } ! 198: ! 199: #endif ! 200: ! 201: send_p(c) ! 202: char c; ! 203: { ! 204: if (cur_proc == 0) ! 205: complain("[No processes]"); ! 206: if (cur_proc->p_buffer == curbuf) ! 207: ToLast(); ! 208: (void) write(cur_proc->p_fd, &c, 1); ! 209: } ! 210: ! 211: static ! 212: proc_close(p) ! 213: Process *p; ! 214: { ! 215: (void) close(p->p_fd); ! 216: global_fd &= ~(1 << p->p_fd); ! 217: p->p_eof++; ! 218: } ! 219: ! 220: do_rtp(mp) ! 221: register Mark *mp; ! 222: { ! 223: register Process *p = cur_proc; ! 224: Line *line1 = curline, ! 225: *line2 = mp->m_line; ! 226: int char1 = curchar, ! 227: char2 = mp->m_char; ! 228: char *gp; ! 229: ! 230: if (isdead(p) || p->p_buffer != curbuf) ! 231: return; ! 232: ! 233: (void) fixorder(&line1, &char1, &line2, &char2); ! 234: while (line1 != line2->l_next) { ! 235: gp = ltobuf(line1, genbuf) + char1; ! 236: if (line1 == line2) ! 237: gp[char2] = '\0'; ! 238: else ! 239: strcat(gp, "\n"); ! 240: (void) write(p->p_fd, gp, strlen(gp)); ! 241: line1 = line1->l_next; ! 242: char1 = 0; ! 243: } ! 244: } ! 245: ! 246: /* VARARGS2 */ ! 247: ! 248: static ! 249: proc_strt(bufname, procname, cmd) ! 250: char *bufname, ! 251: *procname, ! 252: *cmd; ! 253: { ! 254: Window *owind = curwind; ! 255: int pid; ! 256: Process *newp; ! 257: Buffer *bp; ! 258: char **cp; ! 259: int i, ! 260: f, ! 261: ttyfd; ! 262: long ldisc, ! 263: lmode; ! 264: register char *s, ! 265: *t; ! 266: extern int errno; ! 267: extern char **environ; ! 268: static char ttybuf[11], ! 269: ptybuf[11]; ! 270: char cmdbuf[128]; ! 271: #ifdef BRLUNIX ! 272: struct sg_brl sg; ! 273: #else ! 274: struct sgttyb sg; ! 275: #endif ! 276: ! 277: #ifdef TIOCGWINSZ ! 278: struct winsize win; ! 279: #else ! 280: # ifdef BTL_BLIT ! 281: # include <sys/jioctl.h> ! 282: struct jwinsize jwin; ! 283: # endif ! 284: #endif ! 285: ! 286: bp = buf_exists(bufname); ! 287: if (bp != 0 && IsModified(bp) && bp->b_type != B_IPROCESS && bp->b_type != B_PROCESS) ! 288: complain("Command would over-write buffer %s.", procname, bufname); ! 289: pop_wind(bufname, 1, B_IPROCESS); ! 290: ! 291: for (s = "pqrs"; *s; s++) { ! 292: for (t = "0123456789abcdef"; *t; t++) { ! 293: sprintf(ptybuf, "/dev/pty%c%c", *s, *t); ! 294: if ((ttyfd = open(ptybuf, 2)) >= 0) ! 295: goto out; ! 296: } ! 297: } ! 298: ! 299: out: if (s == 0 && t == 0) ! 300: complain("[Out of ptys!]"); ! 301: ! 302: strcpy(ttybuf, ptybuf); ! 303: ttybuf[5] = 't'; ! 304: ! 305: #ifdef TIOCGETD ! 306: (void) ioctl(0, TIOCGETD, (struct sgttyb *) &ldisc); ! 307: #endif ! 308: #ifdef TIOCLGET ! 309: (void) ioctl(0, TIOCLGET, (struct sgttyb *) &lmode); ! 310: #endif ! 311: #ifdef TIOCGWINSZ ! 312: (void) ioctl(0, TIOCGWINSZ, (struct sgttyb *) &win); ! 313: #else ! 314: # ifdef BTL_BLIT ! 315: (void) ioctl(0, JWINSIZE, (struct sgttyb *) &jwin); ! 316: # endif BTL_BLIT ! 317: #endif ! 318: ! 319: switch (pid = fork()) { ! 320: case -1: ! 321: (void) close(ttyfd); ! 322: complain("[Fork failed!]"); ! 323: ! 324: case 0: ! 325: cp = &cmd; ! 326: ! 327: for (i = 0; i < 32; i++) ! 328: (void) close(i); ! 329: ! 330: #ifdef TIOCNOTTY ! 331: if ((i = open("/dev/tty", 2)) >= 0) { ! 332: (void) ioctl(i, TIOCNOTTY, (struct sgttyb *) 0); ! 333: (void) close(i); ! 334: } ! 335: #endif ! 336: i = open(ttybuf, 2); ! 337: for (f = 0; f <= 2; f++) ! 338: (void) dup2(i, f); ! 339: ! 340: #ifdef TIOCSETD ! 341: (void) ioctl(0, TIOCSETD, (struct sgttyb *) &ldisc); ! 342: #endif ! 343: #ifdef TIOCLSET ! 344: (void) ioctl(0, TIOCLSET, (struct sgttyb *) &lmode); ! 345: #endif ! 346: #ifdef TIOCSETC ! 347: (void) ioctl(0, TIOCSETC, (struct sgttyb *) &tc1); ! 348: #endif ! 349: #ifdef TIOCSLTC ! 350: (void) ioctl(0, TIOCSLTC, (struct sgttyb *) &ls1); ! 351: #endif ! 352: ! 353: #ifdef TIOCGWINSZ ! 354: # ifdef SIGWINCH ! 355: (void) signal(SIGWINCH, SIG_IGN); ! 356: # endif ! 357: win.ws_row = curwind->w_height; ! 358: (void) ioctl(0, TIOCSWINSZ, (struct sgttyb *) &win); ! 359: #else ! 360: # ifdef BTL_BLIT ! 361: jwin.bytesy = curwind->w_height; ! 362: (void) ioctl(0, JSWINSIZE, (struct sgttyb *) &jwin); ! 363: # endif ! 364: #endif ! 365: ! 366: sg = sg1; ! 367: sg.sg_flags &= ~(ECHO | CRMOD); ! 368: (void) stty(0, &sg); ! 369: ! 370: i = getpid(); ! 371: (void) ioctl(0, TIOCSPGRP, (struct sgttyb *) &i); ! 372: (void) setpgrp(0, i); ! 373: execve(cp[0], &cp[1], environ); ! 374: (void) write(1, "execve failed!\n", 15); ! 375: _exit(errno + 1); ! 376: } ! 377: ! 378: sighold(SIGCHLD); ! 379: #ifdef SIGWINCH ! 380: sighold(SIGWINCH); ! 381: #endif ! 382: cur_proc = newp = (Process *) emalloc(sizeof *newp); ! 383: ! 384: newp->p_fd = ttyfd; ! 385: newp->p_pid = pid; ! 386: newp->p_eof = 0; ! 387: newp->p_buffer = curbuf; ! 388: ! 389: cp = &cmd + 1; ! 390: cmdbuf[0] = '\0'; ! 391: while (*cp != 0) ! 392: (void) sprintf(&cmdbuf[strlen(cmdbuf)], "%s ", *cp++); ! 393: ! 394: newp->p_name = copystr(cmdbuf); ! 395: newp->p_state = RUNNING; ! 396: newp->p_reason = 0; ! 397: newp->p_mark = MakeMark(curline, curchar, FLOATER); ! 398: ! 399: newp->p_next = procs; ! 400: procs = newp; ! 401: NumProcs++; ! 402: global_fd |= 1 << newp->p_fd; ! 403: sigrelse(SIGCHLD); ! 404: SetWind(owind); ! 405: } ! 406: ! 407: pinit() ! 408: { ! 409: (void) signal(SIGCHLD, proc_child); ! 410: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.