|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char *sccsid = "@(#)ex_subr.c 7.11 (Berkeley) 3/9/87"; ! 9: #endif not lint ! 10: ! 11: #include "ex.h" ! 12: #include "ex_re.h" ! 13: #include "ex_tty.h" ! 14: #include "ex_vis.h" ! 15: ! 16: /* ! 17: * Random routines, in alphabetical order. ! 18: */ ! 19: ! 20: any(c, s) ! 21: int c; ! 22: register char *s; ! 23: { ! 24: register int x; ! 25: ! 26: while (x = *s++) ! 27: if (x == c) ! 28: return (1); ! 29: return (0); ! 30: } ! 31: ! 32: backtab(i) ! 33: register int i; ! 34: { ! 35: register int j; ! 36: ! 37: j = i % value(SHIFTWIDTH); ! 38: if (j == 0) ! 39: j = value(SHIFTWIDTH); ! 40: i -= j; ! 41: if (i < 0) ! 42: i = 0; ! 43: return (i); ! 44: } ! 45: ! 46: change() ! 47: { ! 48: ! 49: tchng++; ! 50: chng = tchng; ! 51: } ! 52: ! 53: /* ! 54: * Column returns the number of ! 55: * columns occupied by printing the ! 56: * characters through position cp of the ! 57: * current line. ! 58: */ ! 59: column(cp) ! 60: register char *cp; ! 61: { ! 62: ! 63: if (cp == 0) ! 64: cp = &linebuf[LBSIZE - 2]; ! 65: return (qcolumn(cp, (char *) 0)); ! 66: } ! 67: ! 68: /* ! 69: * Ignore a comment to the end of the line. ! 70: * This routine eats the trailing newline so don't call newline(). ! 71: */ ! 72: comment() ! 73: { ! 74: register int c; ! 75: ! 76: do { ! 77: c = ex_getchar(); ! 78: } while (c != '\n' && c != EOF); ! 79: if (c == EOF) ! 80: ungetchar(c); ! 81: } ! 82: ! 83: Copy(to, from, size) ! 84: register char *from, *to; ! 85: register int size; ! 86: { ! 87: ! 88: if (size > 0) ! 89: do ! 90: *to++ = *from++; ! 91: while (--size > 0); ! 92: } ! 93: ! 94: copyw(to, from, size) ! 95: register line *from, *to; ! 96: register int size; ! 97: { ! 98: if (size > 0) ! 99: do ! 100: *to++ = *from++; ! 101: while (--size > 0); ! 102: } ! 103: ! 104: copywR(to, from, size) ! 105: register line *from, *to; ! 106: register int size; ! 107: { ! 108: ! 109: while (--size >= 0) ! 110: to[size] = from[size]; ! 111: } ! 112: ! 113: ctlof(c) ! 114: int c; ! 115: { ! 116: ! 117: return (c == TRIM ? '?' : c | ('A' - 1)); ! 118: } ! 119: ! 120: dingdong() ! 121: { ! 122: ! 123: if (VB) ! 124: putpad(VB); ! 125: else if (value(ERRORBELLS)) ! 126: putch('\207'); ! 127: } ! 128: ! 129: fixindent(indent) ! 130: int indent; ! 131: { ! 132: register int i; ! 133: register char *cp; ! 134: ! 135: i = whitecnt(genbuf); ! 136: cp = vpastwh(genbuf); ! 137: if (*cp == 0 && i == indent && linebuf[0] == 0) { ! 138: genbuf[0] = 0; ! 139: return (i); ! 140: } ! 141: CP(genindent(i), cp); ! 142: return (i); ! 143: } ! 144: ! 145: filioerr(cp) ! 146: char *cp; ! 147: { ! 148: register int oerrno = errno; ! 149: ! 150: lprintf("\"%s\"", cp); ! 151: errno = oerrno; ! 152: syserror(); ! 153: } ! 154: ! 155: char * ! 156: genindent(indent) ! 157: register int indent; ! 158: { ! 159: register char *cp; ! 160: ! 161: for (cp = genbuf; indent >= value(TABSTOP); indent -= value(TABSTOP)) ! 162: *cp++ = '\t'; ! 163: for (; indent > 0; indent--) ! 164: *cp++ = ' '; ! 165: return (cp); ! 166: } ! 167: ! 168: getDOT() ! 169: { ! 170: ! 171: getline(*dot); ! 172: } ! 173: ! 174: line * ! 175: getmark(c) ! 176: register int c; ! 177: { ! 178: register line *addr; ! 179: ! 180: for (addr = one; addr <= dol; addr++) ! 181: if (names[c - 'a'] == (*addr &~ 01)) { ! 182: return (addr); ! 183: } ! 184: return (0); ! 185: } ! 186: ! 187: getn(cp) ! 188: register char *cp; ! 189: { ! 190: register int i = 0; ! 191: ! 192: while (isdigit(*cp)) ! 193: i = i * 10 + *cp++ - '0'; ! 194: if (*cp) ! 195: return (0); ! 196: return (i); ! 197: } ! 198: ! 199: ignnEOF() ! 200: { ! 201: register int c = ex_getchar(); ! 202: ! 203: if (c == EOF) ! 204: ungetchar(c); ! 205: else if (c=='"') ! 206: comment(); ! 207: } ! 208: ! 209: iswhite(c) ! 210: int c; ! 211: { ! 212: ! 213: return (c == ' ' || c == '\t'); ! 214: } ! 215: ! 216: junk(c) ! 217: register int c; ! 218: { ! 219: ! 220: if (c && !value(BEAUTIFY)) ! 221: return (0); ! 222: if (c >= ' ' && c != TRIM) ! 223: return (0); ! 224: switch (c) { ! 225: ! 226: case '\t': ! 227: case '\n': ! 228: case '\f': ! 229: return (0); ! 230: ! 231: default: ! 232: return (1); ! 233: } ! 234: } ! 235: ! 236: killed() ! 237: { ! 238: ! 239: killcnt(addr2 - addr1 + 1); ! 240: } ! 241: ! 242: killcnt(cnt) ! 243: register int cnt; ! 244: { ! 245: ! 246: if (inopen) { ! 247: notecnt = cnt; ! 248: notenam = notesgn = ""; ! 249: return; ! 250: } ! 251: if (!notable(cnt)) ! 252: return; ! 253: ex_printf("%d lines", cnt); ! 254: if (value(TERSE) == 0) { ! 255: ex_printf(" %c%s", Command[0] | ' ', Command + 1); ! 256: if (Command[strlen(Command) - 1] != 'e') ! 257: ex_putchar('e'); ! 258: ex_putchar('d'); ! 259: } ! 260: putNFL(); ! 261: } ! 262: ! 263: lineno(a) ! 264: line *a; ! 265: { ! 266: ! 267: return (a - zero); ! 268: } ! 269: ! 270: lineDOL() ! 271: { ! 272: ! 273: return (lineno(dol)); ! 274: } ! 275: ! 276: lineDOT() ! 277: { ! 278: ! 279: return (lineno(dot)); ! 280: } ! 281: ! 282: markDOT() ! 283: { ! 284: ! 285: markpr(dot); ! 286: } ! 287: ! 288: markpr(which) ! 289: line *which; ! 290: { ! 291: ! 292: if ((inglobal == 0 || inopen) && which <= endcore) { ! 293: names['z'-'a'+1] = *which & ~01; ! 294: if (inopen) ! 295: ncols['z'-'a'+1] = cursor; ! 296: } ! 297: } ! 298: ! 299: markreg(c) ! 300: register int c; ! 301: { ! 302: ! 303: if (c == '\'' || c == '`') ! 304: return ('z' + 1); ! 305: if (c >= 'a' && c <= 'z') ! 306: return (c); ! 307: return (0); ! 308: } ! 309: ! 310: /* ! 311: * Mesg decodes the terse/verbose strings. Thus ! 312: * 'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy' ! 313: * 'xxx|yyy' -> 'xxx' if terse, else 'yyy' ! 314: * All others map to themselves. ! 315: */ ! 316: char * ! 317: mesg(str) ! 318: register char *str; ! 319: { ! 320: register char *cp; ! 321: ! 322: str = strcpy(genbuf, str); ! 323: for (cp = str; *cp; cp++) ! 324: switch (*cp) { ! 325: ! 326: case '@': ! 327: if (value(TERSE)) ! 328: *cp = 0; ! 329: else ! 330: *cp = ' '; ! 331: break; ! 332: ! 333: case '|': ! 334: if (value(TERSE) == 0) ! 335: return (cp + 1); ! 336: *cp = 0; ! 337: break; ! 338: } ! 339: return (str); ! 340: } ! 341: ! 342: /*VARARGS2*/ ! 343: merror(seekpt, i) ! 344: #ifndef EXSTRINGS ! 345: char *seekpt; ! 346: #else ! 347: # ifdef lint ! 348: char *seekpt; ! 349: # else ! 350: int seekpt; ! 351: # endif ! 352: #endif ! 353: int i; ! 354: { ! 355: register char *cp = linebuf; ! 356: ! 357: if (seekpt == 0) ! 358: return; ! 359: merror1(seekpt); ! 360: if (*cp == '\n') ! 361: putnl(), cp++; ! 362: if (inopen > 0 && CE) ! 363: vclreol(); ! 364: if (SO && SE) ! 365: putpad(SO); ! 366: ex_printf(mesg(cp), i); ! 367: if (SO && SE) ! 368: putpad(SE); ! 369: } ! 370: ! 371: merror1(seekpt) ! 372: #ifndef EXSTRINGS ! 373: char *seekpt; ! 374: #else ! 375: # ifdef lint ! 376: char *seekpt; ! 377: # else ! 378: int seekpt; ! 379: # endif ! 380: #endif ! 381: { ! 382: ! 383: #ifndef EXSTRINGS ! 384: strcpy(linebuf, seekpt); ! 385: #else ! 386: lseek(erfile, (long) seekpt, 0); ! 387: if (read(erfile, linebuf, 128) < 2) ! 388: CP(linebuf, "ERROR"); ! 389: #endif ! 390: } ! 391: ! 392: morelines() ! 393: { ! 394: #ifdef UNIX_SBRK ! 395: char *sbrk(); ! 396: ! 397: if ((int) sbrk(1024 * sizeof (line)) == -1) ! 398: return (-1); ! 399: endcore += 1024; ! 400: return (0); ! 401: #else ! 402: /* ! 403: * We can never be guaranteed that we can get more memory ! 404: * beyond "endcore". So we just punt every time. ! 405: */ ! 406: return -1; ! 407: #endif ! 408: } ! 409: ! 410: nonzero() ! 411: { ! 412: ! 413: if (addr1 == zero) { ! 414: notempty(); ! 415: error("Nonzero address required@on this command"); ! 416: } ! 417: } ! 418: ! 419: notable(i) ! 420: int i; ! 421: { ! 422: ! 423: return (hush == 0 && !inglobal && i > value(REPORT)); ! 424: } ! 425: ! 426: ! 427: notempty() ! 428: { ! 429: ! 430: if (dol == zero) ! 431: error("No lines@in the buffer"); ! 432: } ! 433: ! 434: ! 435: netchHAD(cnt) ! 436: int cnt; ! 437: { ! 438: ! 439: netchange(lineDOL() - cnt); ! 440: } ! 441: ! 442: netchange(i) ! 443: register int i; ! 444: { ! 445: register char *cp; ! 446: ! 447: if (i > 0) ! 448: notesgn = cp = "more "; ! 449: else ! 450: notesgn = cp = "fewer ", i = -i; ! 451: if (inopen) { ! 452: notecnt = i; ! 453: notenam = ""; ! 454: return; ! 455: } ! 456: if (!notable(i)) ! 457: return; ! 458: ex_printf(mesg("%d %slines@in file after %s"), i, cp, Command); ! 459: putNFL(); ! 460: } ! 461: ! 462: putmark(addr) ! 463: line *addr; ! 464: { ! 465: ! 466: putmk1(addr, putline()); ! 467: } ! 468: ! 469: putmk1(addr, n) ! 470: register line *addr; ! 471: int n; ! 472: { ! 473: register line *markp; ! 474: register oldglobmk; ! 475: ! 476: oldglobmk = *addr & 1; ! 477: *addr &= ~1; ! 478: for (markp = (anymarks ? names : &names['z'-'a'+1]); ! 479: markp <= &names['z'-'a'+1]; markp++) ! 480: if (*markp == *addr) ! 481: *markp = n; ! 482: *addr = n | oldglobmk; ! 483: } ! 484: ! 485: char * ! 486: plural(i) ! 487: long i; ! 488: { ! 489: ! 490: return (i == 1 ? "" : "s"); ! 491: } ! 492: ! 493: int qcount(); ! 494: short vcntcol; ! 495: ! 496: qcolumn(lim, gp) ! 497: register char *lim, *gp; ! 498: { ! 499: register int x; ! 500: int (*OO)(); ! 501: ! 502: OO = Outchar; ! 503: Outchar = qcount; ! 504: vcntcol = 0; ! 505: if (lim != NULL) ! 506: x = lim[1], lim[1] = 0; ! 507: pline(0); ! 508: if (lim != NULL) ! 509: lim[1] = x; ! 510: if (gp) ! 511: while (*gp) ! 512: ex_putchar(*gp++); ! 513: Outchar = OO; ! 514: return (vcntcol); ! 515: } ! 516: ! 517: int ! 518: qcount(c) ! 519: int c; ! 520: { ! 521: ! 522: if (c == '\t') { ! 523: vcntcol += value(TABSTOP) - vcntcol % value(TABSTOP); ! 524: return; ! 525: } ! 526: vcntcol++; ! 527: } ! 528: ! 529: reverse(a1, a2) ! 530: register line *a1, *a2; ! 531: { ! 532: register line t; ! 533: ! 534: for (;;) { ! 535: t = *--a2; ! 536: if (a2 <= a1) ! 537: return; ! 538: *a2 = *a1; ! 539: *a1++ = t; ! 540: } ! 541: } ! 542: ! 543: save(a1, a2) ! 544: line *a1; ! 545: register line *a2; ! 546: { ! 547: register int more; ! 548: ! 549: if (!FIXUNDO) ! 550: return; ! 551: #ifdef TRACE ! 552: if (trace) ! 553: vudump("before save"); ! 554: #endif ! 555: undkind = UNDNONE; ! 556: undadot = dot; ! 557: more = (a2 - a1 + 1) - (unddol - dol); ! 558: while (more > (endcore - truedol)) ! 559: if (morelines() < 0) ! 560: #ifdef UNIX_SBRK ! 561: error("Out of memory@saving lines for undo - try using ed"); ! 562: #else ! 563: error("Out of memory@saving lines for undo - try increasing linelimit"); ! 564: #endif ! 565: if (more) ! 566: (*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1, ! 567: (truedol - unddol)); ! 568: unddol += more; ! 569: truedol += more; ! 570: copyw(dol + 1, a1, a2 - a1 + 1); ! 571: undkind = UNDALL; ! 572: unddel = a1 - 1; ! 573: undap1 = a1; ! 574: undap2 = a2 + 1; ! 575: #ifdef TRACE ! 576: if (trace) ! 577: vudump("after save"); ! 578: #endif ! 579: } ! 580: ! 581: save12() ! 582: { ! 583: ! 584: save(addr1, addr2); ! 585: } ! 586: ! 587: saveall() ! 588: { ! 589: ! 590: save(one, dol); ! 591: } ! 592: ! 593: span() ! 594: { ! 595: ! 596: return (addr2 - addr1 + 1); ! 597: } ! 598: ! 599: ex_sync() ! 600: { ! 601: ! 602: chng = 0; ! 603: tchng = 0; ! 604: xchng = 0; ! 605: } ! 606: ! 607: ! 608: skipwh() ! 609: { ! 610: register int wh; ! 611: ! 612: wh = 0; ! 613: while (iswhite(peekchar())) { ! 614: wh++; ! 615: ignchar(); ! 616: } ! 617: return (wh); ! 618: } ! 619: ! 620: /*VARARGS2*/ ! 621: smerror(seekpt, cp) ! 622: #ifdef lint ! 623: char *seekpt; ! 624: #else ! 625: int seekpt; ! 626: #endif ! 627: char *cp; ! 628: { ! 629: ! 630: if (seekpt == 0) ! 631: return; ! 632: merror1(seekpt); ! 633: if (inopen && CE) ! 634: vclreol(); ! 635: if (SO && SE) ! 636: putpad(SO); ! 637: lprintf(mesg(linebuf), cp); ! 638: if (SO && SE) ! 639: putpad(SE); ! 640: } ! 641: ! 642: char * ! 643: strend(cp) ! 644: register char *cp; ! 645: { ! 646: ! 647: while (*cp) ! 648: cp++; ! 649: return (cp); ! 650: } ! 651: ! 652: strcLIN(dp) ! 653: char *dp; ! 654: { ! 655: ! 656: CP(linebuf, dp); ! 657: } ! 658: ! 659: syserror() ! 660: { ! 661: register int e = errno; ! 662: #ifndef vms ! 663: extern int sys_nerr; ! 664: extern char *sys_errlist[]; ! 665: #else ! 666: extern noshare int sys_nerr; ! 667: extern noshare char *sys_errlist[]; ! 668: #endif ! 669: ! 670: dirtcnt = 0; ! 671: ex_putchar(' '); ! 672: if (e >= 0 && e <= sys_nerr) ! 673: error(sys_errlist[e]); ! 674: else ! 675: #ifdef vms ! 676: if (e == EVMSERR) { ! 677: error("VMS system error %d", vaxc$errno); ! 678: perror("vmserror"); ! 679: } ! 680: else ! 681: #endif ! 682: error("System error %d", e); ! 683: } ! 684: ! 685: /* ! 686: * Return the column number that results from being in column col and ! 687: * hitting a tab, where tabs are set every ts columns. Work right for ! 688: * the case where col > COLUMNS, even if ts does not divide COLUMNS. ! 689: */ ! 690: tabcol(col, ts) ! 691: int col, ts; ! 692: { ! 693: int offset, result; ! 694: ! 695: if (col >= COLUMNS) { ! 696: offset = COLUMNS * (col/COLUMNS); ! 697: col -= offset; ! 698: } else ! 699: offset = 0; ! 700: result = col + ts - (col % ts) + offset; ! 701: return (result); ! 702: } ! 703: ! 704: char * ! 705: vfindcol(i) ! 706: int i; ! 707: { ! 708: register char *cp; ! 709: register int (*OO)() = Outchar; ! 710: ! 711: Outchar = qcount; ! 712: ignore(qcolumn(linebuf - 1, NOSTR)); ! 713: for (cp = linebuf; *cp && vcntcol < i; cp++) ! 714: ex_putchar(*cp); ! 715: if (cp != linebuf) ! 716: cp--; ! 717: Outchar = OO; ! 718: return (cp); ! 719: } ! 720: ! 721: char * ! 722: vskipwh(cp) ! 723: register char *cp; ! 724: { ! 725: ! 726: while (iswhite(*cp) && cp[1]) ! 727: cp++; ! 728: return (cp); ! 729: } ! 730: ! 731: ! 732: char * ! 733: vpastwh(cp) ! 734: register char *cp; ! 735: { ! 736: ! 737: while (iswhite(*cp)) ! 738: cp++; ! 739: return (cp); ! 740: } ! 741: ! 742: whitecnt(cp) ! 743: register char *cp; ! 744: { ! 745: register int i; ! 746: ! 747: i = 0; ! 748: for (;;) ! 749: switch (*cp++) { ! 750: ! 751: case '\t': ! 752: i += value(TABSTOP) - i % value(TABSTOP); ! 753: break; ! 754: ! 755: case ' ': ! 756: i++; ! 757: break; ! 758: ! 759: default: ! 760: return (i); ! 761: } ! 762: } ! 763: ! 764: #ifdef lint ! 765: Ignore(a) ! 766: char *a; ! 767: { ! 768: ! 769: a = a; ! 770: } ! 771: ! 772: Ignorf(a) ! 773: int (*a)(); ! 774: { ! 775: ! 776: a = a; ! 777: } ! 778: #endif ! 779: ! 780: markit(addr) ! 781: line *addr; ! 782: { ! 783: ! 784: if (addr != dot && addr >= one && addr <= dol) ! 785: markDOT(); ! 786: } ! 787: ! 788: /* ! 789: * The following code is defensive programming against a bug in the ! 790: * pdp-11 overlay implementation. Sometimes it goes nuts and asks ! 791: * for an overlay with some garbage number, which generates an emt ! 792: * trap. This is a less than elegant solution, but it is somewhat ! 793: * better than core dumping and losing your work, leaving your tty ! 794: * in a weird state, etc. ! 795: */ ! 796: int _ovno; ! 797: onemt() ! 798: { ! 799: signal(SIGEMT, onemt); ! 800: /* 2 and 3 are valid on 11/40 type vi, so */ ! 801: if (_ovno < 0 || _ovno > 3) ! 802: _ovno = 0; ! 803: error("emt trap, _ovno is %d @ - try again"); ! 804: } ! 805: ! 806: /* ! 807: * When a hangup occurs our actions are similar to a preserve ! 808: * command. If the buffer has not been [Modified], then we do ! 809: * nothing but remove the temporary files and exit. ! 810: * Otherwise, we sync the temp file and then attempt a preserve. ! 811: * If the preserve succeeds, we unlink our temp files. ! 812: * If the preserve fails, we leave the temp files as they are ! 813: * as they are a backup even without preservation if they ! 814: * are not removed. ! 815: */ ! 816: onhup() ! 817: { ! 818: ! 819: /* ! 820: * USG tty driver can send multiple HUP's!! ! 821: */ ! 822: signal(SIGINT, SIG_IGN); ! 823: signal(SIGHUP, SIG_IGN); ! 824: if (chng == 0) { ! 825: cleanup(1); ! 826: ex_exit(0); ! 827: } ! 828: if (setexit() == 0) { ! 829: if (preserve()) { ! 830: cleanup(1); ! 831: ex_exit(0); ! 832: } ! 833: } ! 834: ex_exit(1); ! 835: } ! 836: ! 837: /* ! 838: * An interrupt occurred. Drain any output which ! 839: * is still in the output buffering pipeline. ! 840: * Catch interrupts again. Unless we are in visual ! 841: * reset the output state (out of -nl mode, e.g). ! 842: * Then like a normal error (with the \n before Interrupt ! 843: * suppressed in visual mode). ! 844: */ ! 845: onintr() ! 846: { ! 847: ! 848: #ifndef CBREAK ! 849: signal(SIGINT, onintr); ! 850: #else ! 851: signal(SIGINT, inopen ? vintr : onintr); ! 852: #endif ! 853: alarm(0); /* in case we were called from map */ ! 854: draino(); ! 855: if (!inopen) { ! 856: pstop(); ! 857: setlastchar('\n'); ! 858: #ifdef CBREAK ! 859: } ! 860: #else ! 861: } else ! 862: vraw(); ! 863: #endif ! 864: error("\nInterrupt" + inopen); ! 865: } ! 866: ! 867: /* ! 868: * If we are interruptible, enable interrupts again. ! 869: * In some critical sections we turn interrupts off, ! 870: * but not very often. ! 871: */ ! 872: setrupt() ! 873: { ! 874: ! 875: if (ruptible) { ! 876: #ifndef CBREAK ! 877: signal(SIGINT, onintr); ! 878: #else ! 879: signal(SIGINT, inopen ? vintr : onintr); ! 880: #endif ! 881: #ifdef SIGTSTP ! 882: if (dosusp) ! 883: signal(SIGTSTP, onsusp); ! 884: #endif ! 885: } ! 886: } ! 887: ! 888: preserve() ! 889: { ! 890: ! 891: #ifdef VMUNIX ! 892: tflush(); ! 893: #endif ! 894: synctmp(); ! 895: pid = vfork(); ! 896: if (pid < 0) ! 897: return (0); ! 898: if (pid == 0) { ! 899: close(0); ! 900: dup(tfile); ! 901: execl(EXPRESERVE, "expreserve", (char *) 0); ! 902: ex_exit(1); ! 903: } ! 904: waitfor(); ! 905: if (rpid == pid && status == 0) ! 906: return (1); ! 907: return (0); ! 908: } ! 909: ! 910: #ifndef V6 ! 911: ex_exit(i) ! 912: int i; ! 913: { ! 914: ! 915: # ifdef TRACE ! 916: if (trace) ! 917: fclose(trace); ! 918: # endif ! 919: _exit(i); ! 920: } ! 921: #endif ! 922: ! 923: #ifdef SIGTSTP ! 924: /* ! 925: * We have just gotten a susp. Suspend and prepare to resume. ! 926: */ ! 927: onsusp() ! 928: { ! 929: ttymode f; ! 930: struct winsize win; ! 931: ! 932: f = setty(normf); ! 933: vnfl(); ! 934: putpad(TE); ! 935: flush(); ! 936: ! 937: (void) sigsetmask(0); ! 938: signal(SIGTSTP, SIG_DFL); ! 939: kill(0, SIGTSTP); ! 940: ! 941: /* the pc stops here */ ! 942: ! 943: signal(SIGTSTP, onsusp); ! 944: vcontin(0); ! 945: ignore(setty(f)); ! 946: if (!inopen) ! 947: error((char *) 0); ! 948: else { ! 949: #ifdef TIOCGWINSZ ! 950: if (ioctl(0, TIOCGWINSZ, &win) >= 0) ! 951: if (win.ws_row != winsz.ws_row || ! 952: win.ws_col != winsz.ws_col) ! 953: winch(); ! 954: #endif ! 955: if (vcnt < 0) { ! 956: vcnt = -vcnt; ! 957: if (state == VISUAL) ! 958: vclear(); ! 959: else if (state == CRTOPEN) ! 960: vcnt = 0; ! 961: } ! 962: vdirty(0, LINES); ! 963: vrepaint(cursor); ! 964: } ! 965: } ! 966: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.