Annotation of OpenXM_contrib2/fep/fep_main.c, Revision 1.1
1.1 ! noro 1: /* Copyright (c) 1987, 1988 by Software Research Associates, Inc. */
! 2:
! 3: #ifndef lint
! 4: static char rcsid[]=
! 5: "$Id: fep_main.c,v 4.11 1993/06/10 02:51:28 utashiro Exp $ (SRA)";
! 6: #endif /* lint */
! 7:
! 8: #include <stdio.h>
! 9: #include <signal.h>
! 10: #include <sys/types.h>
! 11: #include <sys/stat.h>
! 12: #include <sys/ioctl.h>
! 13: #ifdef TERMIOS
! 14: #include <termios.h>
! 15: #if defined(__linux__) || defined(__CYGWIN__)
! 16: #ifndef _POSIX_VDISABLE
! 17: #define _POSIX_VDISABLE '\0'
! 18: #endif
! 19: #endif
! 20: #else
! 21: #include <sgtty.h>
! 22: #endif
! 23: #include <sys/file.h>
! 24: #include <sys/time.h>
! 25: #include <sys/resource.h>
! 26: #include <sys/errno.h>
! 27:
! 28: #include "fep_defs.h"
! 29: #include "fep_glob.h"
! 30: #include "fep_funcs.h"
! 31: #ifdef STAT
! 32: #include "fep_stat.h"
! 33: #endif
! 34:
! 35: #ifndef lint
! 36: static char fep_defsrc[] = FEP_DEFS;
! 37: static char fep_globrc[] = FEP_GLOB;
! 38: static char fep_funcsrc[] = FEP_FUNCS;
! 39: #ifdef STAT
! 40: static char fep_statrc[] = FEP_STAT;
! 41: #endif
! 42: #endif /* lint */
! 43:
! 44: char *myself; /* the command name */
! 45: char *prompt = ""; /* prompt string */
! 46: char *delimiters = DEFAULT_DELIMITERS;
! 47: /* delimiter characters */
! 48: int master; /* file discriptor for pty master */
! 49: int slave; /* file discriptor for pty slave */
! 50: fd_set mastermask; /* 1<<master */
! 51: fd_set stdinmask; /* 1<<fileno(stdin) */
! 52: fd_set selectmask; /* stdinmask | mastermask */
! 53: int selectnfds; /* max (fileno(stdin), master) + 1*/
! 54: int child_pid; /* child pid */
! 55: int ptyflag = ON; /* flag to use pty or not */
! 56: int histlen = -1; /* history length */
! 57: int debug = OFF; /* debug switch */
! 58: int auto_tty_fix = ON; /* fix tty mode automaticaly */
! 59: FILE *script_fp = NULL; /* script file pointer */
! 60: void catchsig __P((int)); /* function take care SIGCHILD */
! 61:
! 62: #ifdef TERMIOS
! 63: #define ttystruct termios
! 64: #elif defined(TIOCSETN)
! 65: #define ttystruct sgttyb
! 66: #endif
! 67: struct ttystruct initial_ttymode; /* initial tty mode */
! 68: struct ttystruct master_ttymode; /* master tty mode */
! 69: struct ttystruct slave_ttymode; /* slave tty mode */
! 70:
! 71: int lines; /* terminal line size */
! 72: int columns; /* terminal coulumn size */
! 73: char *term_clear; /* terminal clear code */
! 74:
! 75: void (*sighup) __P((int)), (*sigchld) __P((int)), (*sigtstp) __P((int));
! 76: /* function buffer for signal */
! 77:
! 78: #ifdef TIOCSETN
! 79: struct tchars tchars_buf; /* tty characters */
! 80: struct ltchars ltchars_buf; /* tty characters */
! 81: #endif
! 82: int lmode_buf; /* local mode */
! 83: int line_desc; /* line descipline */
! 84: #ifdef KANJI
! 85: struct jtchars jtchars_buf; /* kanji tty characters */
! 86: int kmode_buf; /* kanji mode */
! 87: #endif /* KANJI */
! 88:
! 89: char master_tty[16]; /* master tty name */
! 90: char slave_tty[16]; /* slave tty name */
! 91:
! 92: BUFFER iobuffer; /* buffer self */
! 93: BUFFER *output_buffer = &iobuffer; /* buffer pointer */
! 94:
! 95: struct cmdinfo {
! 96: char *command;
! 97: char *prompt;
! 98: char *delimiters;
! 99: } cmdinfo_tab [] = {
! 100: {"/bin/sh", "$ ", " \t()<>{};&|='\""},
! 101: {"sh", "$ ", " \t()<>{};&|='\""},
! 102: {"jsh", "$ ", " \t()<>{};&|='\""},
! 103: {"/bin/csh", "% ", " \t()<>{};&|='\""},
! 104: {"csh", "% ", " \t()<>{};&|='\""},
! 105: {"jcsh", "% ", " \t()<>{};&|='\""},
! 106: {"/usr/ucb/dbx", "(dbx) ", " \t>"},
! 107: {"dbx", "(dbx) ", " \t>"},
! 108: {"/etc/lpc", "lpc> ", " \t"},
! 109: {"lpc", "lpc> ", " \t"},
! 110: {"/usr/ucb/mail", "& ", " \t"},
! 111: {"mail", "& ", " \t"},
! 112: {"/usr/lib/sendmail", "> ", " \t"},
! 113: {"sendmail", "> ", " \t"},
! 114: {"/usr/sra/calc", "CALC: ", " \t"},
! 115: {"calc", "CALC: ", " \t"},
! 116: {0, 0}
! 117: };
! 118:
! 119: main(argc, argv)
! 120: int argc;
! 121: char *argv[];
! 122: {
! 123: int i;
! 124: char *cp;
! 125: char *getenv();
! 126: char **commandv;
! 127: char *allocAndCopyThere();
! 128:
! 129: myself = argv[0];
! 130:
! 131: setvbuf(stdin, NULL, _IONBF, 0);
! 132: setvbuf(stdout, NULL, _IONBF, 0);
! 133: setvbuf(stderr, NULL, _IONBF, 0);
! 134:
! 135: /*
! 136: * Initialize binding table
! 137: */
! 138: init_bind_table ();
! 139:
! 140: /*
! 141: * Set default variables before process arguments.
! 142: */
! 143: set_default_vars ();
! 144:
! 145:
! 146: /*
! 147: * Look environment variable first.
! 148: */
! 149: /* EDITMODE */
! 150: if ((cp=getenv("EDITMODE")) && (eq(cp,"emacs")||eq(cp,"vi")))
! 151: set_only_var ("editmode", cp);
! 152: /* USER */
! 153: if (cp=getenv("USER"))
! 154: set_only_var ("user", cp);
! 155: /* HOME */
! 156: if (cp=getenv("HOME"))
! 157: set_only_var ("home", cp);
! 158: /* TERM */
! 159: if (cp=getenv("TERM"))
! 160: set_only_var ("term", cp);
! 161: /* SHELL */
! 162: if (cp=getenv("SHELL"))
! 163: set_only_var ("shell", cp);
! 164:
! 165: /*
! 166: * Check arguments.
! 167: */
! 168: while (argv[1] && argv[1][0] == '-') {
! 169: switch (argv[1][1]) {
! 170:
! 171: case '\0': /* - */
! 172: ptyflag = 0;
! 173: break;
! 174:
! 175: case 'd': /* -d */
! 176: debug = ON;
! 177: break;
! 178:
! 179: case 'e': /* -emacs */
! 180: if (strcmp (argv[1], "-emacs") == 0)
! 181: set_only_var ("editmode", "emacs");
! 182: else
! 183: goto DEFAULT;
! 184: break;
! 185:
! 186: case 'h': /* -h */
! 187: if (argv[1][2] == '\0') {
! 188: argv++;
! 189: argc--;
! 190: if (argc == 1)
! 191: usageAndExit ();
! 192: histlen = atoi (argv[1]);
! 193: }
! 194: else {
! 195: histlen = atoi (&argv[1] + 2);
! 196: }
! 197: break;
! 198:
! 199: case 'p': /* -p */
! 200: if (argv[1][2] == '\0') {
! 201: argv++;
! 202: argc--;
! 203: if (argc == 1)
! 204: usageAndExit ();
! 205: prompt = allocAndCopyThere (argv[1]);
! 206: }
! 207: else {
! 208: prompt = allocAndCopyThere (argv[1] + 2);
! 209: }
! 210: break;
! 211:
! 212: case 'v': /* -vi */
! 213: if (strcmp (argv[1], "-vi") == 0)
! 214: set_only_var ("editmode", "vi");
! 215: else
! 216: goto DEFAULT;
! 217: break;
! 218: DEFAULT:
! 219: default:
! 220: printf ("Unknown option \"%s\"\n", argv[1]);
! 221: }
! 222: argv++;
! 223: argc--;
! 224: }
! 225: fflush (stdout);
! 226:
! 227: if (argc < 2 && ptyflag) {
! 228: usageAndExit ();
! 229: }
! 230:
! 231: look_cmdinfo (argv[1]);
! 232:
! 233: /*
! 234: * Set variable of command name.
! 235: */
! 236: {
! 237: char *cp = argv[1], *rindex();
! 238:
! 239: if (any ('/', cp))
! 240: cp = rindex (cp, '/') + 1;
! 241: set_var (cp, "1");
! 242: set_var ("command", cp);
! 243: }
! 244:
! 245: commandv = &argv[1];
! 246:
! 247: if (! isatty (0)) {
! 248: execvp (*commandv, commandv, 0);
! 249: perror (*commandv);
! 250: exit (1);
! 251: }
! 252:
! 253: get_pty_master ();
! 254: fix_tty ();
! 255:
! 256: if (histlen < 0) {
! 257: if (getenv ("HISTLEN"))
! 258: histlen = atoi (getenv ("HISTLEN"));
! 259: else
! 260: histlen = DFL_HISTLEN;
! 261: }
! 262:
! 263: init_hist (histlen);
! 264: init_edit_params ();
! 265:
! 266: /*
! 267: * Initialize output buffer.
! 268: */
! 269: if (!output_buffer->b_buf) {
! 270: int size;
! 271:
! 272: if ((size = atoi (look_var ("buffer"))) <= 0)
! 273: size = 5120;
! 274: if (!set_buffer (output_buffer, size)) {
! 275: fprintf (stderr, "Can't allocate enough momory\n");
! 276: kill_process ();
! 277: exit (1);
! 278: }
! 279: }
! 280:
! 281: if (ptyflag) {
! 282: child_pid = fork ();
! 283: if (child_pid < 0) {
! 284: perror ("fork");
! 285: kill_process ();
! 286: exit (1);
! 287: }
! 288: if (child_pid == 0)
! 289: exec_to_command (commandv);
! 290: }
! 291: fix_signal ();
! 292:
! 293: input_handler ();
! 294: }
! 295:
! 296: fix_signal ()
! 297: {
! 298: #ifdef SIGWINCH
! 299: void sigwinch __P((int));
! 300: #endif
! 301:
! 302: sighup = signal (SIGHUP, terminate);
! 303: sigchld = signal (SIGCHLD, catchsig);
! 304: sigtstp = signal (SIGTSTP, SIG_IGN);
! 305: signal (SIGINT, (void(*)())send_int_sig);
! 306: #ifdef SIGWINCH
! 307: (void) signal(SIGWINCH, sigwinch);
! 308: #endif
! 309: }
! 310:
! 311: recover_signal ()
! 312: {
! 313:
! 314: (void) signal (SIGHUP, sighup);
! 315: (void) signal (SIGCHLD, sigchld);
! 316: (void) signal (SIGTSTP, sigtstp);
! 317: }
! 318:
! 319: input_handler()
! 320: {
! 321: char *inputline;
! 322: char *getline ();
! 323:
! 324: /*
! 325: * Get slave tty descriptor for auto-tty-fix
! 326: */
! 327: if ((slave = open (slave_tty, O_RDONLY)) < 0)
! 328: perror ("open");
! 329:
! 330: while (inputline = getline ()) {
! 331: /*
! 332: * XXX: nbyte should be greater than 0 only for ^@ input in emacs.
! 333: * This solution is very ugly.. but it will takes a half day
! 334: * to fix this problem in more right way. I will fix this problem
! 335: * in future release.
! 336: */
! 337: register int nbyte = max (strlen (inputline), 1);
! 338:
! 339: /*
! 340: * Write to master pty
! 341: */
! 342: write (master, inputline, nbyte);
! 343:
! 344: /*
! 345: * NOTE:
! 346: * Saving command line to output buffer is done in getline().
! 347: * Because inputline here is converted by alias.
! 348: */
! 349:
! 350: #ifdef STAT
! 351: stat_ibyte += nbyte;
! 352: #endif
! 353:
! 354: /*
! 355: * Write to script file.
! 356: */
! 357: if (Through == OFF && Transparency == OFF && script_fp)
! 358: fwrite (inputline, sizeof(CHAR), strlen (inputline), script_fp);
! 359: }
! 360: terminate (0);
! 361: }
! 362:
! 363: #define INPUT_BUFFER_SIZE 1024
! 364:
! 365: #ifdef USE_TIMEOUT
! 366: /*
! 367: * NOTE:
! 368: * Now these time mechanism is not used.
! 369: * Terminal status is get at every input from stdin.
! 370: */
! 371: struct timeval timeout_0s = {0L, 0L};
! 372: struct timeval timeout_500ms = {0L, 500000L};
! 373: struct timeval timeout_1s = {1L, 0L};
! 374: struct timeval timeout_5s = {5L, 0L};
! 375: struct timeval timeout_10s = {10L, 0L};
! 376: struct timeval timeout_60s = {60L, 0L};
! 377:
! 378: #define TIMEOUT_IMMID &timeout_500ms
! 379: #define TIMEOUT_SOON &timeout_1s
! 380: #define TIMEOUT_SHORT &timeout_5s
! 381: #define TIMEOUT_MID &timeout_10s
! 382: #define TIMEOUT_LONG &timeout_60s
! 383: #define TIMEOUT_FOREVER (struct timeval *)0
! 384: #define TIMEOUT_NOBLOCK &timeout_0s
! 385:
! 386: struct timeval *timeout_list[] = {
! 387: TIMEOUT_IMMID,
! 388: TIMEOUT_SOON,
! 389: TIMEOUT_SHORT,
! 390: TIMEOUT_MID,
! 391: TIMEOUT_LONG,
! 392: TIMEOUT_FOREVER
! 393: };
! 394: #else
! 395: struct timeval timeout_0s = {0L, 0L};
! 396: #define TIMEOUT_FOREVER (struct timeval *)0
! 397: #define TIMEOUT_NOBLOCK &timeout_0s
! 398: #endif
! 399:
! 400: struct timeval *notimeout[] = {
! 401: TIMEOUT_FOREVER
! 402: };
! 403:
! 404: getcharacter()
! 405: {
! 406: char c;
! 407: int n;
! 408: int nfound;
! 409: fd_set readfd, writefd, exceptfd;
! 410: #ifdef USE_TIMEOUT
! 411: struct timeval **timeout = auto_tty_fix ? timeout_list : notimeout;
! 412: #else
! 413: struct timeval **timeout = notimeout;
! 414: #endif
! 415: extern int errno;
! 416:
! 417:
! 418: /*
! 419: * Sorry, this cording depends to an implementation of getc().
! 420: */
! 421: FD_ZERO(&writefd);
! 422: FD_ZERO(&exceptfd);
! 423:
! 424: RETRY:
! 425: readfd = selectmask;
! 426:
! 427: #ifdef STAT
! 428: stat_nselect++;
! 429: #endif
! 430: while ((nfound = select (selectnfds, &readfd, 0, 0, *timeout)) < 0)
! 431: if (errno != EINTR) {
! 432: perror ("select");
! 433: terminate(0);
! 434: }
! 435:
! 436: /*
! 437: * Found output from pty.
! 438: */
! 439: if (FD_ISSET(master, &readfd)) {
! 440: int nbyte;
! 441:
! 442: /*
! 443: * Read from pty.
! 444: */
! 445: nbyte = buf_read (master, output_buffer);
! 446:
! 447: if (nbyte > 0) {
! 448: /*
! 449: * Write to stdout
! 450: */
! 451: write (1, output_buffer->b_lastbuf, nbyte);
! 452:
! 453: /*
! 454: * Write to script file
! 455: */
! 456: if (script_fp)
! 457: fwrite (output_buffer->b_lastbuf,
! 458: sizeof(CHAR), nbyte, script_fp);
! 459:
! 460: #ifdef STAT
! 461: stat_obyte += nbyte;
! 462: #endif
! 463: }
! 464: else if (nbyte < 0) {
! 465: perror ("read");
! 466: #ifdef STAT
! 467: stat_rerror++;
! 468: #endif
! 469: }
! 470: }
! 471:
! 472: /*
! 473: * Found input from terminal
! 474: */
! 475: if (FD_ISSET(fileno(stdin), &readfd)) {
! 476:
! 477: #ifndef USE_TIMEOUT
! 478: /*
! 479: * Look slave tty mode before every input.
! 480: * This will be done only before real input from stdin, because
! 481: * if character remained in FILE buffer, control goes to RETURNCHAR
! 482: * label.
! 483: */
! 484: if (Through == OFF && auto_tty_fix)
! 485: (void) fix_transparency ();
! 486: #endif
! 487:
! 488: RETURNCHAR:
! 489: if ((c = getc (stdin)) == EOF) {
! 490: if (debug)
! 491: printf ("EOF chatched\n");
! 492: terminate (0);
! 493: }
! 494: else
! 495: return (c & CHARMASK);
! 496: }
! 497:
! 498: #ifdef USE_TIMEOUT
! 499: /*
! 500: * In the case of timeout.
! 501: */
! 502: if (nfound == 0) {
! 503:
! 504: /*
! 505: * Only to make sure
! 506: */
! 507: if (!auto_tty_fix) {
! 508: printf ("Timeout should not happen!!\n");
! 509: timeout = notimeout;
! 510: goto RETRY;
! 511: }
! 512:
! 513: (void) fix_transparency ();
! 514: ++timeout;
! 515:
! 516: if (debug)
! 517: errorBell();
! 518: }
! 519: #endif
! 520:
! 521: goto RETRY;
! 522: }
! 523:
! 524: int set_buffer (bp, size)
! 525: BUFFER *bp;
! 526: int size;
! 527: {
! 528: char *newbuf, *malloc(), *realloc();
! 529:
! 530: if (bp->b_buf)
! 531: newbuf = (char *) realloc (bp->b_buf, size);
! 532: else {
! 533: newbuf = (char *) malloc (size);
! 534: bp->b_count = bp->b_next = 0;
! 535: }
! 536:
! 537: if (newbuf == 0)
! 538: return (0);
! 539:
! 540: bp->b_buf = newbuf;
! 541: bp->b_max = size;
! 542: bp->b_hiwater = size * 4 / 5;
! 543:
! 544: if (bp->b_next > bp->b_hiwater) {
! 545: bp->b_count = bp->b_next;
! 546: bp->b_next = 0;
! 547: }
! 548: return (1);
! 549: }
! 550:
! 551: int buf_read (fd, bp)
! 552: int fd; /* file discriptor */
! 553: BUFFER *bp; /* buffer pointer */
! 554: {
! 555: int nbyte;
! 556:
! 557: /*
! 558: * save previous next pointer
! 559: */
! 560: bp->b_lastbuf = bp->b_buf + bp->b_next;
! 561:
! 562: /*
! 563: * read from fd as possible
! 564: */
! 565: nbyte = read (fd, bp->b_buf + bp->b_next, bp->b_max - bp->b_next);
! 566:
! 567: /*
! 568: * move next read pointer
! 569: */
! 570: bp->b_next += nbyte;
! 571:
! 572: /*
! 573: * If count has not reached high-water mark, increment count
! 574: * by read count.
! 575: */
! 576: if (bp->b_count < bp->b_hiwater)
! 577: bp->b_count += nbyte;
! 578:
! 579: /*
! 580: * If next pointer goes further than high-water mark, discard contents
! 581: * after next pointer, and move next pointer to buffer top.
! 582: */
! 583: if (bp->b_next > bp->b_hiwater) {
! 584: bp->b_count = bp->b_next;
! 585: bp->b_next = 0;
! 586: }
! 587:
! 588: return (nbyte);
! 589: }
! 590:
! 591: buf_put (bp, s)
! 592: BUFFER *bp; /* buffer pointer */
! 593: char *s; /* string pointer */
! 594: {
! 595: int nbyte;
! 596: int slen;
! 597:
! 598: nbyte = strlen (s);
! 599:
! 600: while (nbyte > 0) {
! 601:
! 602: slen = min (bp->b_max - bp->b_next, nbyte);
! 603: strncpy (bp->b_buf + bp->b_next, s, slen);
! 604: s += slen;
! 605: nbyte -= slen;
! 606: bp->b_next += slen;
! 607:
! 608: if (bp->b_count < bp->b_hiwater)
! 609: bp->b_count += slen;
! 610:
! 611: if (bp->b_next > bp->b_hiwater) {
! 612: bp->b_count = bp->b_next;
! 613: bp->b_next = 0;
! 614: }
! 615: }
! 616: }
! 617:
! 618: swallow_output()
! 619: {
! 620: fd_set readfd = mastermask;
! 621: int r;
! 622: int nbyte;
! 623: int ncount = 10;
! 624:
! 625: while (
! 626: ncount-- &&
! 627: select (selectnfds, &readfd, 0, 0, TIMEOUT_NOBLOCK) > 0 &&
! 628: FD_ISSET(master, &mastermask)
! 629: ) {
! 630: nbyte = buf_read (master, output_buffer);
! 631: if (nbyte > 0) {
! 632: write (1, output_buffer->b_lastbuf, nbyte);
! 633: #ifdef STAT
! 634: stat_obyte += nbyte;
! 635: stat_nselect++;
! 636: #endif
! 637:
! 638: /*
! 639: * Write to script file
! 640: */
! 641: if (script_fp)
! 642: fwrite (output_buffer->b_lastbuf,
! 643: sizeof(CHAR), nbyte, script_fp);
! 644: }
! 645: else if (nbyte < 0) {
! 646: perror ("read");
! 647: #ifdef STAT
! 648: stat_rerror++;
! 649: #endif
! 650: }
! 651: }
! 652: return;
! 653: }
! 654:
! 655: #include <sys/wait.h>
! 656: #ifdef AIX
! 657: #include <sys/m_wait.h>
! 658: #endif
! 659:
! 660: void
! 661: catchsig(n)
! 662: int n;
! 663: {
! 664: int status;
! 665: struct rusage ru;
! 666:
! 667: if (wait3 (&status, WNOHANG | WUNTRACED, &ru) != child_pid)
! 668: return;
! 669: if (WIFSTOPPED (status) /* || WIFSIGNALED (status) */) {
! 670: if (debug) {
! 671: message ("Child has sttoped!!\n");
! 672: }
! 673: suspend ();
! 674: return;
! 675: }
! 676: terminate (0);
! 677: }
! 678:
! 679: exec_to_command(argv)
! 680: char *argv[];
! 681: {
! 682: int t;
! 683:
! 684: /*
! 685: * Disconnect control terminal
! 686: */
! 687: t = open ("/dev/tty", 2);
! 688: if (t >= 0) {
! 689: #ifndef __CYGWIN32__
! 690: ioctl (t, TIOCNOTTY, (char *) 0);
! 691: #endif
! 692: (void) close (t);
! 693: }
! 694:
! 695: get_pty_slave ();
! 696:
! 697: (void) close (master);
! 698: dup2 (slave, 0);
! 699: dup2 (slave, 1);
! 700: dup2 (slave, 2);
! 701: (void) close (slave);
! 702:
! 703: #ifdef TERMIOS
! 704: tcsetattr(0, TCSANOW, &slave_ttymode);
! 705: #elif defined(TIOCSETN)
! 706: ioctl (0, TIOCSETN, (char *) & slave_ttymode);
! 707: #endif
! 708: execvp (*argv, argv, 0);
! 709: perror (*argv);
! 710: exit (1);
! 711: }
! 712:
! 713: #ifdef TERMIOS
! 714: fix_tty()
! 715: {
! 716: int i;
! 717: master_ttymode = initial_ttymode;
! 718: slave_ttymode = initial_ttymode;
! 719: master_ttymode.c_lflag &= ~(ECHO|ECHOE|ECHOK|ICANON);
! 720:
! 721: for (i = 0; i < NCCS; i++)
! 722: master_ttymode.c_cc[i] = _POSIX_VDISABLE;
! 723:
! 724: master_ttymode.c_cc[VMIN] = 1;
! 725: master_ttymode.c_cc[VTIME] = 0;
! 726: slave_ttymode.c_lflag &= ~(ECHO|ECHOE|ECHOK);
! 727: slave_ttymode.c_iflag &= ~(ICRNL);
! 728: slave_ttymode.c_oflag &= ~(ONLCR);
! 729: tcsetattr(0, TCSANOW, &master_ttymode);
! 730: }
! 731:
! 732: #elif defined(TIOCSETN)
! 733:
! 734: fix_tty()
! 735: {
! 736: struct tchars tcbuf;
! 737: struct ltchars lcbuf;
! 738:
! 739: master_ttymode = initial_ttymode;
! 740: slave_ttymode = initial_ttymode;
! 741: tcbuf = tchars_buf;
! 742: lcbuf = ltchars_buf;
! 743:
! 744: master_ttymode.sg_flags |= CBREAK;
! 745: master_ttymode.sg_flags &= ~ECHO;
! 746:
! 747: slave_ttymode.sg_erase = -1;
! 748: slave_ttymode.sg_kill = -1;
! 749: slave_ttymode.sg_flags &= ~(ECHO|CRMOD);
! 750:
! 751: tcbuf.t_intrc = -1;
! 752: tcbuf.t_quitc = -1;
! 753: #ifdef AIX
! 754: tcbuf.t_eofc = 0;
! 755: #else
! 756: tcbuf.t_eofc = -1;
! 757: #endif
! 758: tcbuf.t_brkc = -1;
! 759:
! 760: lcbuf.t_suspc = -1;
! 761: lcbuf.t_dsuspc = -1;
! 762: lcbuf.t_rprntc = -1;
! 763: lcbuf.t_flushc = -1;
! 764: lcbuf.t_werasc = -1;
! 765: lcbuf.t_lnextc = -1;
! 766:
! 767: ioctl (0, TIOCSETN, (char *) & master_ttymode);
! 768: ioctl (0, TIOCSETC, (char *) & tcbuf);
! 769: ioctl (0, TIOCSLTC, (char *) & lcbuf);
! 770: }
! 771: #endif
! 772:
! 773: kill_process()
! 774: {
! 775:
! 776: if (child_pid)
! 777: (void) killpg (child_pid, SIGTERM);
! 778: }
! 779:
! 780: void
! 781: terminate(n)
! 782: int n;
! 783: {
! 784: extern int errno;
! 785:
! 786: /*
! 787: * Save history if 'history-file' is set
! 788: */
! 789: {
! 790: char *cp, *mk_home_relative(), *look_var();
! 791: char buf [256];
! 792: int num;
! 793:
! 794: if (look_var ("savehist") && (cp = look_var ("history-file"))) {
! 795:
! 796: num = lookd_var ("savehist");
! 797: strcpy (buf, mk_home_relative (cp));
! 798: save_history (buf, num);
! 799: }
! 800: }
! 801:
! 802: /*
! 803: * If scripting, close script file.
! 804: */
! 805: if (script_fp)
! 806: fclose (script_fp);
! 807:
! 808: (void) signal (SIGCHLD, SIG_IGN);
! 809: if (killpg (child_pid, SIGTERM) < 0 && errno != ESRCH)
! 810: if (killpg (child_pid, SIGHUP) < 0)
! 811: if (killpg (child_pid, SIGKILL) < 0)
! 812: perror ("kill");
! 813:
! 814: #ifdef TERMIOS
! 815: tcsetattr(0, TCSANOW, &initial_ttymode);
! 816: #elif defined(TIOCSETN)
! 817: ioctl (0, TIOCSETN, (char *) & initial_ttymode);
! 818: ioctl (0, TIOCSETC, (char *) & tchars_buf);
! 819: ioctl (0, TIOCSLTC, (char *) & ltchars_buf);
! 820: #endif
! 821: exit (0);
! 822: }
! 823:
! 824: send_int_sig() {
! 825: #ifndef __CYGWIN__
! 826: kill(child_pid,SIGINT);
! 827: #endif
! 828: return 0;
! 829: }
! 830:
! 831: get_pty_master()
! 832: {
! 833: char c;
! 834: struct stat stb;
! 835: int i;
! 836:
! 837: if (ptyflag == 0) {
! 838: master = 1;
! 839: return;
! 840: }
! 841: #ifdef __CYGWIN32__
! 842: for (i = 0; i < 16; i++) {
! 843: sprintf (master_tty, "/dev/ptmx");
! 844: master = open (master_tty, O_RDWR);
! 845: if (master >= 0) {
! 846: sprintf (slave_tty, "/dev/tty%x",i);
! 847: goto FOUND;
! 848: }
! 849: }
! 850: #else
! 851: for (c = 'p'; c <= 's'; c++) {
! 852: for (i = 0; i < 16; i++) {
! 853: sprintf (master_tty, "/dev/pty%c%x", c, i);
! 854: master = open (master_tty, O_RDWR);
! 855: if (master >= 0) {
! 856: sprintf (slave_tty, "/dev/tty%c%x", c, i);
! 857: goto FOUND;
! 858: }
! 859: }
! 860: }
! 861: #endif
! 862: /*
! 863: * Can't get master tty
! 864: */
! 865: if (master < 0) {
! 866: fprintf (stderr, "Couldn't open pseudo tty\n");
! 867: kill_process ();
! 868: exit (1);
! 869: }
! 870:
! 871: FOUND:
! 872: #ifdef TERMIOS
! 873: tcgetattr(0, &initial_ttymode);
! 874: #elif defined(TIOCSETN)
! 875: ioctl (0, TIOCGETP, (char *) &initial_ttymode);
! 876: ioctl (0, TIOCGETC, (char *) &tchars_buf);
! 877: ioctl (0, TIOCGETD, (char *) &line_desc);
! 878: ioctl (0, TIOCGLTC, (char *) <chars_buf);
! 879: ioctl (0, TIOCLGET, (char *) &lmode_buf);
! 880: #endif
! 881:
! 882: #ifdef TIOCGWINSZ
! 883: {
! 884: struct winsize win;
! 885:
! 886: if (ioctl (0, TIOCGWINSZ, &win) >= 0) {
! 887: lines = win.ws_row;
! 888: columns = win.ws_col;
! 889: }
! 890: }
! 891: #endif
! 892:
! 893: #ifdef KANJI
! 894: # if defined(TIOCKGET) && defined(TIOCKSET)
! 895: ioctl (0, TIOCKGET, (char *) &kmode_buf);
! 896: # endif
! 897: # if defined(TIOCKGETC) && defined(TIOCKSETC)
! 898: ioctl (0, TIOCKGETC, (char *) &jtchars_buf);
! 899: # endif
! 900: #endif /* KANJI */
! 901:
! 902: FD_ZERO(&stdinmask);
! 903: FD_ZERO(&mastermask);
! 904: FD_ZERO(&selectmask);
! 905: FD_SET(fileno(stdin), &stdinmask);
! 906: FD_SET(master, &mastermask);
! 907: FD_SET(fileno(stdin), &selectmask);
! 908: FD_SET(master, &selectmask);
! 909: selectnfds = max (fileno(stdin), master) + 1;
! 910:
! 911: return;
! 912: }
! 913:
! 914: get_pty_slave()
! 915: {
! 916:
! 917: slave = open (slave_tty, 2);
! 918: if (slave < 0) {
! 919: perror (slave_tty);
! 920: exit (1);
! 921: }
! 922: #ifdef TERMIOS
! 923: tcsetattr(slave, TCSANOW, &initial_ttymode);
! 924: #elif defined(TIOCSETN)
! 925: ioctl (slave, TIOCSETN, (char *) &initial_ttymode);
! 926: ioctl (slave, TIOCSETC, (char *) &tchars_buf);
! 927: ioctl (slave, TIOCSLTC, (char *) <chars_buf);
! 928: ioctl (slave, TIOCLSET, (char *) &lmode_buf);
! 929: ioctl (slave, TIOCSETD, (char *) &line_desc);
! 930: #endif
! 931:
! 932: #ifdef KANJI
! 933: # if defined(TIOCKGET) && defined(TIOCKSET)
! 934: ioctl (slave, TIOCKSET, (char *) &kmode_buf);
! 935: # endif
! 936: # if defined(TIOCKGETC) && defined(TIOCKSETC)
! 937: ioctl (slave, TIOCKSETC, (char *) &jtchars_buf);
! 938: # endif
! 939: #endif /* KANJI */
! 940:
! 941: #ifdef TIOCSWINSZ
! 942: {
! 943: struct winsize win;
! 944:
! 945: win.ws_row = lines;
! 946: win.ws_col = columns;
! 947: (void) ioctl (slave, TIOCSWINSZ, &win);
! 948: }
! 949: #endif
! 950: }
! 951:
! 952: recover_tty()
! 953: {
! 954: #ifdef TERMIOS
! 955: tcsetattr(0, TCSANOW, &initial_ttymode);
! 956: #elif defined(TIOCSETN)
! 957: ioctl (0, TIOCSETN, (char *) & initial_ttymode);
! 958: ioctl (0, TIOCSETC, (char *) & tchars_buf);
! 959: ioctl (0, TIOCSLTC, (char *) & ltchars_buf);
! 960: #endif
! 961: }
! 962:
! 963: suspend()
! 964: {
! 965: long pid;
! 966: void (*func) __P((int));
! 967: #ifndef __CYGWIN32__
! 968: int omask;
! 969: #endif
! 970: extern int errno;
! 971:
! 972: pid = getpid ();
! 973: /* reset signal handler so kill below stops us */
! 974: func = signal (SIGCHLD, SIG_IGN);
! 975: signal (SIGTSTP, SIG_DFL);
! 976: recover_tty();
! 977: #define mask(s) (1 << ((s)-1))
! 978: #ifndef __CYGWIN32__
! 979: omask = sigsetmask (sigblock (0) & ~mask (SIGTSTP));
! 980: #endif
! 981: kill (0, SIGTSTP);
! 982:
! 983: if (kill (child_pid, SIGCONT) < 0 && errno == ESRCH) {
! 984: printf ("Where my child has gone?!\n");
! 985: terminate (0);
! 986: }
! 987: killpg (child_pid, SIGCONT);
! 988: kill (0, SIGCONT);
! 989: signal (SIGCHLD, func);
! 990: signal (SIGTSTP, SIG_IGN);
! 991: #ifndef __CYGWIN32__
! 992: sigblock (mask (SIGTSTP));
! 993: #endif
! 994: fix_tty ();
! 995: if (look_var ("auto-repaint"))
! 996: fep_repaint(0);
! 997: }
! 998:
! 999: look_cmdinfo (command)
! 1000: char *command;
! 1001: {
! 1002: struct cmdinfo *p;
! 1003: char *allocAndCopyThere();
! 1004:
! 1005: if (strcmp (prompt, "") != 0)
! 1006: return;
! 1007:
! 1008: for (p = cmdinfo_tab; p->command; p++) {
! 1009: if (strcmp (command, p->command) == 0) {
! 1010: prompt = allocAndCopyThere (p->prompt);
! 1011: set_var ("prompt", p->prompt);
! 1012: set_var ("delimiters", p->delimiters);
! 1013: break;
! 1014: }
! 1015: }
! 1016: }
! 1017:
! 1018:
! 1019: usageAndExit()
! 1020: {
! 1021:
! 1022: printf ("Usage: %s [-emacs|-vi] command\n", myself);
! 1023: exit (1);
! 1024: }
! 1025:
! 1026: #ifdef SIGWINCH
! 1027: /*
! 1028: * Propagate window size changes to the slave tty.
! 1029: */
! 1030: sigwinch()
! 1031: {
! 1032: #ifdef TIOCGWINSZ /* 4.3BSD */
! 1033: struct winsize win;
! 1034:
! 1035: if (ioctl (0, TIOCGWINSZ, (char *)&win) >= 0) {
! 1036: (void) ioctl (slave, TIOCSWINSZ, (char *)&win);
! 1037: set_var ("crt", itoa (win.ws_row));
! 1038: set_var ("showhist", itoa (win.ws_row - 1));
! 1039: }
! 1040: #else
! 1041: #ifdef TIOCGSIZE /* SONY NEWS OS2.2 */
! 1042: struct ttysize win;
! 1043:
! 1044: if (ioctl(0, TIOCGSIZE, (char *)&win) >= 0) {
! 1045: (void) ioctl(slave, TIOCSSIZE, (char *)&win);
! 1046: set_var ("crt", itoa (win.ts_lines));
! 1047: set_var ("showhist", itoa (win.ts_lines - 1));
! 1048: }
! 1049: #endif /* TIOCGWINSZ */
! 1050: #endif /* TIOCGSIZE */
! 1051: }
! 1052: #endif /* SIGWINCH */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>