Annotation of 43BSD/contrib/mh/uip/vmh.c, revision 1.1.1.1

1.1       root        1: /* vmh.c - visual front-end to mh */
                      2: 
                      3: /* TODO:
                      4:        Pass signals to client during execution
                      5: 
                      6:        Get stand-alone SO/SE/CE to work under #ifdef SYS5
                      7: 
                      8:        Figure out a way for the user to say how big the Scan/Display
                      9:        windows should be.
                     10: 
                     11:        If curses ever gets fixed, then XYZ code can be removed
                     12:  */
                     13: 
                     14: #include <curses.h>
                     15: #undef OK                      /* tricky */
                     16: #include "../h/mh.h"
                     17: #include "../h/vmhsbr.h"
                     18: #include <ctype.h>
                     19: #include <errno.h>
                     20: #include <setjmp.h>
                     21: #include <signal.h>
                     22: #ifndef        sigmask
                     23: #define        sigmask(s)      (1 << ((s) - 1))
                     24: #endif not sigmask
                     25: #ifndef        BSD42
                     26: struct iovec {
                     27:     char   *iov_base;
                     28:     int     iov_len;
                     29: };
                     30: #else  BSD42
                     31: #include <sys/types.h>
                     32: #include <sys/uio.h>
                     33: #endif BSD42
                     34: 
                     35: #define        ALARM   ((unsigned int) 10)
                     36: #define        PAUSE   ((unsigned int) 2)
                     37: 
                     38: #define        abs(a)          ((a) > 0 ? (a) : -(a))
                     39: #define        SMALLMOVE       1
                     40: #define        LARGEMOVE       10
                     41: 
                     42: 
                     43: #define        XYZ                     /* XXX */
                     44: 
                     45: /*  */
                     46: 
                     47: static struct swit switches[] = {
                     48: #define        PRMPTSW 0
                     49:     "prompt string", 6,
                     50: 
                     51: #define        PROGSW  1
                     52:     "vmhproc program", 7,
                     53: #define        NPROGSW 2
                     54:     "novmhproc", 9,
                     55: 
                     56: #define        HELPSW  3
                     57:     "help", 4,
                     58: 
                     59:     NULL, NULL
                     60: };
                     61: 
                     62: /*  */
                     63:                                        /* PEERS */
                     64: static int  PEERpid = NOTOK;
                     65: 
                     66: static  jmp_buf PEERctx;
                     67: 
                     68: 
                     69:                                        /* WINDOWS */
                     70: static char *myprompt = "(%s) ";
                     71: 
                     72: static  WINDOW *Scan;
                     73: static  WINDOW *Status;
                     74: static  WINDOW *Display;
                     75: static  WINDOW *Command;
                     76: 
                     77: #define        NWIN    3
                     78: static int numwins;
                     79: WINDOW *windows[NWIN + 1];
                     80: 
                     81: 
                     82:                                        /* LINES */
                     83: 
                     84: struct line {
                     85:     int     l_no;
                     86:     char   *l_buf;
                     87:     struct line *l_prev;
                     88:     struct line *l_next;
                     89: };
                     90: 
                     91: static struct line *lhead = NULL;
                     92: static struct line *ltop = NULL;
                     93: static struct line *ltail = NULL;
                     94: 
                     95: static int did_less = 0;
                     96: static int smallmove = SMALLMOVE;
                     97: static int largemove = LARGEMOVE;
                     98: 
                     99: 
                    100:                                        /* TTYS */
                    101: 
                    102: static int  tty_ready = NOTOK;
                    103: 
                    104: static int  intrc;
                    105: #ifndef        SYS5
                    106: #define        ERASE   sg.sg_erase
                    107: #define        KILL    sg.sg_kill
                    108: static struct sgttyb    sg;
                    109: 
                    110: #define        EOFC    tc.t_eofc
                    111: #define        INTR    tc.t_intrc
                    112: static struct tchars    tc;
                    113: #else  SYS5
                    114: #define        ERASE   sg.c_cc[VERASE]
                    115: #define        KILL    sg.c_cc[VKILL]
                    116: #define        EOFC    sg.c_cc[VEOF]
                    117: #define        INTR    sg.c_cc[VINTR]
                    118: static struct termio    sg;
                    119: #endif SYS5
                    120: 
                    121: #ifndef        TIOCGLTC
                    122: #define        WERASC  ('W' & 037)
                    123: #else  TIOCGLTC
                    124: #define        WERASC  ltc.t_werasc
                    125: static struct ltchars ltc;
                    126: #endif TIOCGLTC
                    127: 
                    128: 
                    129: #ifndef        SYS5
                    130: int    _putchar ();
                    131: #endif not SYS5
                    132: char   *tgoto ();
                    133: 
                    134: 
                    135:                                        /* SIGNALS */
                    136: int     ALRMser (), PIPEser (), SIGser ();
                    137: #ifdef SIGTSTP
                    138: int    TSTPser ();
                    139: #endif SIGTSTP
                    140: 
                    141: 
                    142:                                        /* MISCELLANY */
                    143: extern int  errno;
                    144: extern int  sys_nerr;
                    145: extern char *sys_errlist[];
                    146: 
                    147: void   adorn ();
                    148: 
                    149: /*  */
                    150: 
                    151: /* ARGSUSED */
                    152: 
                    153: main (argc, argv)
                    154: int     argc;
                    155: char   *argv[];
                    156: {
                    157:     int     vecp = 1,
                    158:            nprog = 0;
                    159:     char   *cp,
                    160:             buffer[BUFSIZ],
                    161:           **ap,
                    162:           **argp,
                    163:            *arguments[MAXARGS],
                    164:            *vec[MAXARGS];
                    165: 
                    166:     invo_name = r1bindex (argv[0], '/');
                    167:     if ((cp = m_find (invo_name)) != NULL) {
                    168:        ap = brkstring (cp = getcpy (cp), " ", "\n");
                    169:        ap = copyip (ap, arguments);
                    170:     }
                    171:     else
                    172:        ap = arguments;
                    173:     (void) copyip (argv + 1, ap);
                    174:     argp = arguments;
                    175: 
                    176: /*  */
                    177: 
                    178:     while (cp = *argp++)
                    179:        if (*cp == '-')
                    180:            switch (smatch (++cp, switches)) {
                    181:                case AMBIGSW: 
                    182:                    ambigsw (cp, switches);
                    183:                    done (1);
                    184:                case UNKWNSW: 
                    185:                    vec[vecp++] = --cp;
                    186:                    continue;
                    187:                case HELPSW: 
                    188:                    (void) sprintf (buffer, "%s [switches for vmhproc]",
                    189:                            invo_name);
                    190:                    help (buffer, switches);
                    191:                    done (1);
                    192: 
                    193:                case PRMPTSW:
                    194:                    if (!(myprompt = *argp++) || *myprompt == '-')
                    195:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    196:                    continue;
                    197: 
                    198:                case PROGSW: 
                    199:                    if (!(vmhproc = *argp++) || *vmhproc == '-')
                    200:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    201:                    continue;
                    202:                case NPROGSW:
                    203:                    nprog++;
                    204:                    continue;
                    205:            }
                    206:        else
                    207:            vec[vecp++] = cp;
                    208: 
                    209: /*  */
                    210: 
                    211:     if (TTYinit (nprog) == NOTOK || WINinit (nprog) == NOTOK) {
                    212:        vec[vecp] = NULL;
                    213: 
                    214:        vec[0] = r1bindex (vmhproc, '/');
                    215:        execvp (vmhproc, vec);
                    216:        adios (vmhproc, "unable to exec");
                    217:     }
                    218:     TTYoff ();
                    219:     (void) PEERinit (vecp, vec);
                    220:     TTYon ();
                    221: 
                    222:     vmh ();
                    223: 
                    224:     done (0);
                    225: }
                    226: 
                    227: /*  */
                    228: 
                    229: static  vmh () {
                    230:     char    buffer[BUFSIZ];
                    231: 
                    232:     for (;;) {
                    233:        (void) pLOOP (RC_QRY, NULLCP);
                    234: 
                    235:        wmove (Command, 0, 0);
                    236:        wprintw (Command, myprompt, invo_name);
                    237:        wclrtoeol (Command);
                    238:        wrefresh (Command);
                    239: 
                    240:        switch (WINgetstr (Command, buffer)) {
                    241:            case NOTOK: 
                    242:                break;
                    243: 
                    244:            case OK:
                    245:                done (0);       /* NOTREACHED */
                    246: 
                    247:            default: 
                    248:                if (*buffer)
                    249:                    (void) pLOOP (RC_CMD, buffer);
                    250:                break;
                    251:        }
                    252:     }
                    253: }
                    254: 
                    255: /*    PEERS */
                    256: 
                    257: static int  PEERinit (vecp, vec)
                    258: int    vecp;
                    259: char   *vec[];
                    260: {
                    261:     int            pfd0[2],
                    262:             pfd1[2];
                    263:     char    buf1[BUFSIZ],
                    264:             buf2[BUFSIZ];
                    265: 
                    266:     if (pipe (pfd0) == NOTOK || pipe (pfd1) == NOTOK)
                    267:        adios ("pipe", "unable to");
                    268:     switch (PEERpid = vfork ()) {
                    269:        case NOTOK: 
                    270:            adios ("vfork", "unable to");/* NOTREACHED */
                    271: 
                    272:        case OK: 
                    273:            (void) close (pfd0[0]);
                    274:            (void) close (pfd1[1]);
                    275: 
                    276:            vec[vecp++] = "-vmhread";
                    277:            (void) sprintf (buf1, "%d", pfd1[0]);
                    278:            vec[vecp++] = buf1;
                    279:            vec[vecp++] = "-vmhwrite";
                    280:            (void) sprintf (buf2, "%d", pfd0[1]);
                    281:            vec[vecp++] = buf2;
                    282:            vec[vecp] = NULL;
                    283: 
                    284:            (void) signal (SIGINT, SIG_DFL);
                    285:            (void) signal (SIGQUIT, SIG_DFL);
                    286: 
                    287:            vec[0] = r1bindex (vmhproc, '/');
                    288:            execvp (vmhproc, vec);
                    289:            perror (vmhproc);
                    290:            _exit (-1);         /* NOTREACHED */
                    291: 
                    292:        default: 
                    293:            (void) close (pfd0[1]);
                    294:            (void) close (pfd1[0]);
                    295: 
                    296:            (void) rcinit (pfd0[0], pfd1[1]);
                    297:            return pINI ();
                    298:     }
                    299: }
                    300: 
                    301: /*  */
                    302: 
                    303: static int  pINI () {
                    304:     register char  *bp;
                    305:     char    buffer[BUFSIZ];
                    306:     struct record   rcs;
                    307:     register struct record *rc = &rcs;
                    308:     register    WINDOW **w;
                    309: 
                    310:     initrc (rc);
                    311: 
                    312:     bp = buffer;
                    313:     (void) sprintf (bp, "%d %d", RC_VRSN, numwins);
                    314:     bp += strlen (bp);
                    315:     for (w = windows; *w; w++) {
                    316:        (void) sprintf (bp, " %d", (*w) -> _maxy);
                    317:        bp += strlen (bp);
                    318:     }
                    319: 
                    320:     switch (str2rc (RC_INI, buffer, rc)) {
                    321:        case RC_ACK: 
                    322:            return OK;
                    323: 
                    324:        case RC_ERR: 
                    325:            if (rc -> rc_len)
                    326:                adios (NULLCP, "%s", rc -> rc_data);
                    327:            else
                    328:                adios (NULLCP, "pINI peer error");
                    329: 
                    330:        case RC_XXX: 
                    331:            adios (NULLCP, "%s", rc -> rc_data);
                    332: 
                    333:        default:
                    334:            adios (NULLCP, "pINI protocol screw-up");
                    335:     }
                    336: /* NOTREACHED */
                    337: }
                    338: 
                    339: /*  */
                    340: 
                    341: static int  pLOOP (code, str)
                    342: char   code,
                    343:        *str;
                    344: {
                    345:     int            i;
                    346:     struct record   rcs;
                    347:     register struct record *rc = &rcs;
                    348: 
                    349:     initrc (rc);
                    350: 
                    351:     (void) str2peer (code, str);
                    352:     for (;;)
                    353:        switch (peer2rc (rc)) {
                    354:            case RC_TTY:
                    355:                if (pTTY (rc) == NOTOK)
                    356:                    return NOTOK;
                    357:                break;
                    358: 
                    359:            case RC_WIN:
                    360:                if (sscanf (rc -> rc_data, "%d", &i) != 1
                    361:                        || i <= 0
                    362:                        || i > numwins) {
                    363:                    (void) fmt2peer (RC_ERR, "no such window \"%s\"",
                    364:                                rc -> rc_data);
                    365:                    return NOTOK;
                    366:                }
                    367:                if (pWIN (windows[i - 1]) == NOTOK)
                    368:                    return NOTOK;
                    369:                break;
                    370: 
                    371:            case RC_EOF:
                    372:                return OK;
                    373: 
                    374:            case RC_ERR:
                    375:                if (rc -> rc_len)
                    376:                    adorn (NULLCP, "%s", rc -> rc_data);
                    377:                else
                    378:                    adorn (NULLCP, "pLOOP(%s) peer error",
                    379:                            code == RC_QRY ? "QRY" : "CMD");
                    380:                return NOTOK;
                    381: 
                    382:            case RC_FIN:
                    383:                if (rc -> rc_len)
                    384:                    adorn (NULLCP, "%s", rc -> rc_data);
                    385:                (void) rcdone ();
                    386:                i = pidwait (PEERpid, OK);
                    387:                PEERpid = NOTOK;
                    388:                done (i);
                    389: 
                    390:            case RC_XXX: 
                    391:                adios (NULLCP, "%s", rc -> rc_data);
                    392: 
                    393:            default:
                    394:                adios (NULLCP, "pLOOP(%s) protocol screw-up",
                    395:                        code == RC_QRY ? "QRY" : "CMD");
                    396:        }
                    397: }
                    398: 
                    399: /*  */
                    400: 
                    401: static int  pTTY (r)
                    402: register struct record *r;
                    403: {
                    404:     int     (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
                    405:     struct record   rcs;
                    406:     register struct record *rc = &rcs;
                    407: 
                    408:     initrc (rc);
                    409: 
                    410:     TTYoff ();
                    411: 
                    412:     hstat = signal (SIGHUP, SIG_IGN);
                    413:     istat = signal (SIGINT, SIG_IGN);
                    414:     qstat = signal (SIGQUIT, SIG_IGN);
                    415:     tstat = signal (SIGTERM, SIG_IGN);
                    416: 
                    417:     (void) rc2rc (RC_ACK, 0, NULLCP, rc);
                    418: 
                    419:     (void) signal (SIGHUP, hstat);
                    420:     (void) signal (SIGINT, istat);
                    421:     (void) signal (SIGQUIT, qstat);
                    422:     (void) signal (SIGTERM, tstat);
                    423: 
                    424:     TTYon ();
                    425: 
                    426:     if (r -> rc_len && strcmp (r -> rc_data, "FAST") == 0)
                    427:        goto no_refresh;
                    428: 
                    429: #ifdef SIGTSTP
                    430:     (void) signal (SIGTSTP, SIG_IGN);
                    431: #endif SIGTSTP
                    432: #ifndef        SYS5
                    433:     if (SO)
                    434:        tputs (SO, 0, _putchar);
                    435: #endif not SYS5
                    436:     fprintf (stdout, "Type any key to continue... ");
                    437:     (void) fflush (stdout);
                    438: #ifndef        SYS5
                    439:     if (SE)
                    440:        tputs (SE, 0, _putchar);
                    441: #endif not SYS5
                    442:     (void) getc (stdin);
                    443: #ifdef SIGTSTP
                    444:     (void) signal (SIGTSTP, TSTPser);
                    445: #endif SIGTSTP
                    446: 
                    447:     wrefresh (curscr);
                    448: 
                    449: no_refresh: ;
                    450:     switch (rc -> rc_type) {
                    451:        case RC_EOF: 
                    452:            (void) rc2peer (RC_ACK, 0, NULLCP);
                    453:            return OK;
                    454: 
                    455:        case RC_ERR: 
                    456:            if (rc -> rc_len)
                    457:                adorn (NULLCP, "%s", rc -> rc_data);
                    458:            else
                    459:                adorn (NULLCP, "pTTY peer error");
                    460:            return NOTOK;
                    461: 
                    462:        case RC_XXX: 
                    463:            adios (NULLCP, "%s", rc -> rc_data);
                    464: 
                    465:        default:
                    466:            adios (NULLCP, "pTTY protocol screw-up");
                    467:     }
                    468: /* NOTREACHED */
                    469: }
                    470: 
                    471: /*  */
                    472: 
                    473: static int  pWIN (w)
                    474: register WINDOW *w;
                    475: {
                    476:     int     i;
                    477: 
                    478:     did_less = 0;
                    479:     if ((i = pWINaux (w)) == OK && did_less)
                    480:        (void) WINless (w, 1);
                    481: 
                    482:     lreset ();
                    483: 
                    484:     return i;
                    485: }
                    486: 
                    487: /*  */
                    488: 
                    489: static int  pWINaux (w)
                    490: register WINDOW *w;
                    491: {
                    492:     register int    n;
                    493:     int            eol;
                    494:     register char   c,
                    495:                    *bp;
                    496:     struct record   rcs;
                    497:     register struct record *rc = &rcs;
                    498: 
                    499:     initrc (rc);
                    500: 
                    501:     werase (w);
                    502:     wmove (w, 0, 0);
                    503: #ifdef XYZ
                    504:     if (w == Status)
                    505:        wstandout (w);
                    506: #endif XYZ
                    507: 
                    508:     for (eol = 0;;)
                    509:        switch (rc2rc (RC_ACK, 0, NULLCP, rc)) {
                    510:            case RC_DATA: 
                    511:                if (eol && WINputc (w, '\n') == ERR && WINless (w, 0))
                    512:                    goto flush;
                    513:                for (bp = rc -> rc_data, n = rc -> rc_len; n-- > 0; ) {
                    514:                    if ((c = *bp++) == '\n')
                    515:                        linsert (w);
                    516:                    if (WINputc (w, c) == ERR)
                    517:                        if (n == 0 && c == '\n')
                    518:                            eol++;
                    519:                        else
                    520:                            if (WINless (w, 0)) {
                    521: flush: ;
                    522:                                (void) fmt2peer (RC_ERR, "flush window");
                    523: #ifdef XYZ                     /* should NEVER happen... */
                    524:                                if (w == Status)
                    525:                                    wstandend (w);
                    526: #endif XYZ
                    527:                                wrefresh (w);
                    528:                                return NOTOK;
                    529:                            }
                    530:                }
                    531:                break;
                    532: 
                    533:            case RC_EOF: 
                    534:                (void) rc2peer (RC_ACK, 0, NULLCP);
                    535: #ifdef XYZ
                    536:                if (w == Status)
                    537:                    wstandend (w);
                    538: #endif XYZ
                    539:                wrefresh (w);
                    540:                return OK;
                    541: 
                    542:            case RC_ERR: 
                    543:                if (rc -> rc_len)
                    544:                    adorn (NULLCP, "%s", rc -> rc_data);
                    545:                else
                    546:                    adorn (NULLCP, "pWIN peer error");
                    547:                return NOTOK;
                    548: 
                    549:            case RC_XXX: 
                    550:                adios (NULLCP, "%s", rc -> rc_data);
                    551: 
                    552:            default:
                    553:                adios (NULLCP, "pWIN protocol screw-up");
                    554:        }
                    555: /* NOTREACHED */
                    556: }
                    557: 
                    558: /*  */
                    559: 
                    560: static int  pFIN () {
                    561:     int     status;
                    562: 
                    563:     if (PEERpid <= OK)
                    564:        return OK;
                    565: 
                    566:     (void) rc2peer (RC_FIN, 0, NULLCP);
                    567:     (void) rcdone ();
                    568: 
                    569:     switch (setjmp (PEERctx)) {
                    570:        case OK: 
                    571:            (void) signal (SIGALRM, ALRMser);
                    572:            (void) alarm (ALARM);
                    573: 
                    574:            status = pidwait (PEERpid, OK);
                    575: 
                    576:            (void) alarm (0);
                    577:            break;
                    578: 
                    579:        default: 
                    580:            (void) kill (PEERpid, SIGKILL);
                    581:            status = NOTOK;
                    582:            break;
                    583:     }
                    584:     PEERpid = NOTOK;
                    585: 
                    586:     return status;
                    587: }
                    588: 
                    589: /*    WINDOWS */
                    590: 
                    591: static int  WINinit (nprog) {
                    592:     register int    lines,
                    593:                     top,
                    594:                     bottom;
                    595: 
                    596:     foreground ();
                    597:     if (initscr () == ERR)
                    598:        if (nprog)
                    599:            return NOTOK;
                    600:        else
                    601:            adios (NULLCP, "could not initialize terminal");
                    602: #ifdef SIGTSTP
                    603:     (void) signal (SIGTSTP, SIG_DFL);
                    604: #endif SIGTSTP
                    605:     sideground ();
                    606: 
                    607:     if (CM == NULL)
                    608:        if (nprog)
                    609:            return NOTOK;
                    610:        else
                    611:            adios (NULLCP,
                    612:                    "sorry, your terminal isn't powerful enough to run %s",
                    613:                    invo_name);
                    614: 
                    615: #ifndef        SYS5
                    616:     if (tgetflag ("xt") || tgetnum ("sg") > 0)
                    617:        SO = SE = US = UE = NULL;
                    618: #endif not SYS5
                    619: 
                    620:     if ((lines = LINES - 1) < 11)
                    621:        adios (NULLCP, "screen too small");
                    622:     if ((top = lines / 3 + 1) > LINES / 4 + 2)
                    623:        top--;
                    624:     bottom = lines - top - 2;
                    625: 
                    626:     numwins = 0;
                    627:     Scan = windows[numwins++] = newwin (top, COLS, 0, 0);
                    628:     Status = windows[numwins++] = newwin (1, COLS, top, 0);
                    629: #ifndef        XYZ
                    630:     wstandout (Status);
                    631: #endif XYZ
                    632:     Display = windows[numwins++] = newwin (bottom, COLS, top + 1, 0);
                    633:     Command = newwin (1, COLS - 1, top + 1 + bottom, 0);
                    634:     windows[numwins] = NULL;
                    635: 
                    636:     largemove = Display -> _maxy / 2 + 2;
                    637:     return OK;
                    638: }
                    639: 
                    640: /*  */
                    641: 
                    642: static int WINgetstr (w, buffer)
                    643: register WINDOW *w;
                    644: char   *buffer;
                    645: {
                    646:     register int    c;
                    647:     register char  *bp;
                    648: 
                    649:     bp = buffer;
                    650:     *bp = NULL;
                    651: 
                    652:     for (;;) {
                    653:        switch (c = toascii (wgetch (w))) {
                    654:            case ERR: 
                    655:                adios (NULLCP, "wgetch lost");
                    656: 
                    657:            case '\f':
                    658:                wrefresh (curscr);
                    659:                break;
                    660: 
                    661:            case '\r': 
                    662:            case '\n': 
                    663:                *bp = NULL;
                    664:                if (bp > buffer) {
                    665:                    leaveok (curscr, FALSE);
                    666:                    wmove (w, 0, w -> _curx - (bp - buffer));
                    667:                    wrefresh (w);
                    668:                    leaveok (curscr, TRUE);
                    669:                }
                    670:                return DONE;
                    671: 
                    672:            default: 
                    673:                if (c == intrc) {
                    674:                    wprintw (w, " ");
                    675:                    wstandout (w);
                    676:                    wprintw (w, "Interrupt");
                    677:                    wstandend (w);
                    678:                    wrefresh (w);
                    679:                    *buffer = NULL;
                    680:                    return NOTOK;
                    681:                }
                    682:                if (c == EOFC) {
                    683:                    if (bp <= buffer)
                    684:                        return OK;
                    685:                    break;
                    686:                }
                    687:                if (c == ERASE) {
                    688:                    if (bp <= buffer)
                    689:                        continue;
                    690:                    bp--, w -> _curx--;
                    691:                    wclrtoeol (w);
                    692:                    break;
                    693:                }
                    694:                if (c == KILL) {
                    695:                    if (bp <= buffer)
                    696:                        continue;
                    697:                    w -> _curx -= bp - buffer;
                    698:                    bp = buffer;
                    699:                    wclrtoeol (w);
                    700:                    break;
                    701:                }
                    702:                if (c == WERASC) {
                    703:                    if (bp <= buffer)
                    704:                        continue;
                    705:                    do {
                    706:                        bp--, w -> _curx--;
                    707:                    } while (isspace (*bp) && bp > buffer);
                    708: 
                    709:                    if (bp > buffer) {
                    710:                        do {
                    711:                            bp--, w -> _curx--;
                    712:                        } while (!isspace (*bp) && bp > buffer);
                    713:                        if (isspace (*bp))
                    714:                            bp++, w -> _curx++;
                    715:                    }
                    716:                    wclrtoeol (w);
                    717:                    break;
                    718:                }
                    719:                
                    720:                if (c >= ' ')
                    721:                    (void) waddch (w, *bp++ = c);
                    722:                break;
                    723:        }
                    724: 
                    725:        wrefresh (w);
                    726:     }
                    727: }
                    728: 
                    729: /*  */
                    730: 
                    731: static int  WINwritev (w, iov, n)
                    732: register WINDOW *w;
                    733: register struct iovec   *iov;
                    734: register int     n;
                    735: {
                    736:     register int    i;
                    737: 
                    738:     werase (w);
                    739:     wmove (w, 0, 0);
                    740:     for (i = 0; i < n; i++, iov++)
                    741:        wprintw (w, "%*.*s", iov -> iov_len, iov -> iov_len, iov -> iov_base);
                    742:     wrefresh (w);
                    743: 
                    744:     sleep (PAUSE);
                    745: 
                    746:     return OK;
                    747: }
                    748: 
                    749: /*  */
                    750: 
                    751: static struct {
                    752:     char   *h_msg;
                    753:     int    *h_val;
                    754: }               hlpmsg[] = {
                    755:                     "          forward         backwards", NULL,
                    756:                     "          -------         ---------", NULL,
                    757:                     "next screen       SPACE", NULL,
                    758:                     "next %d line%s    RETURN          y", &smallmove,
                    759:                     "next %d line%s    EOT             u", &largemove,
                    760:                     "go                g               G", NULL,
                    761:                     "", NULL,
                    762:                     "refresh           CTRL-L", NULL,
                    763:                     "quit              q", NULL,
                    764: 
                    765:                     NULL, NULL
                    766: };
                    767: 
                    768: /*  */
                    769: 
                    770: static int  WINless (w, fin)
                    771: register WINDOW *w;
                    772: int    fin;
                    773: {
                    774:     register int    c,
                    775:                     i,
                    776:                     n;
                    777:     int     nfresh,
                    778: #ifdef notdef
                    779:            nlatch,
                    780: #endif notdef
                    781:             nwait;
                    782:     char   *cp;
                    783:     register struct line   *lbottom;
                    784: 
                    785:     did_less++;
                    786: 
                    787:     cp = NULL;
                    788: #ifdef notdef
                    789:     if (fin)
                    790:        ltop = NULL;
                    791: #endif notdef
                    792:     lbottom = NULL;
                    793:     nfresh = 1;
                    794:     nwait = 0;
                    795:     wrefresh (w);
                    796: 
                    797:     for (;;) {
                    798:        if (nfresh || nwait) {
                    799:            nfresh = 0;
                    800: #ifdef notdef
                    801:            nlatch = 1;
                    802: 
                    803: once_only: ;
                    804: #endif notdef
                    805:            werase (w);
                    806:            wmove (w, 0, 0);
                    807: 
                    808:            if (ltop == NULL)
                    809:                if (fin) {
                    810:                    (void) lgo (ltail -> l_no - w -> _maxy + 1);
                    811:                    if (ltop == NULL)
                    812:                        ltop = lhead;
                    813:                }
                    814:                else
                    815:                    ltop = lbottom && lbottom -> l_prev ? lbottom -> l_prev
                    816:                            : lbottom;
                    817: 
                    818:            for (lbottom = ltop; lbottom; lbottom = lbottom -> l_next)
                    819:                if (waddstr (w, lbottom -> l_buf) == ERR
                    820:                        || waddch (w, '\n') == ERR)
                    821:                    break;
                    822:            if (lbottom == NULL)
                    823:                if (fin) {
                    824: #ifdef notdef
                    825:                    if (nlatch && (ltail -> l_no >= w -> _maxy)) {
                    826:                        (void) lgo (ltail -> l_no - w -> _maxy + 1);
                    827:                        nlatch = 0;
                    828:                        goto once_only;
                    829:                    }
                    830: #endif notdef
                    831:                    lbottom = ltail;
                    832:                    while (waddstr (w, "~\n") != ERR)
                    833:                        continue;
                    834:                }
                    835:                else {
                    836:                    wrefresh (w);
                    837:                    return 0;
                    838:                }
                    839: 
                    840:            if (!nwait)
                    841:                wrefresh (w);
                    842:        }
                    843: 
                    844:        wmove (Command, 0, 0);
                    845:        if (cp) {
                    846:            wstandout (Command);
                    847:            wprintw (Command, "%s", cp);
                    848:            wstandend (Command);
                    849:            cp = NULL;
                    850:        }
                    851:        else
                    852:            wprintw (Command, fin ? "top:%d bot:%d end:%d" : "top:%d bot:%d",
                    853:                    ltop -> l_no, lbottom -> l_no, ltail -> l_no);
                    854:        wprintw (Command, ">> ");
                    855:        wclrtoeol (Command);
                    856:        wrefresh (Command);
                    857: 
                    858:        c = toascii (wgetch (Command));
                    859: 
                    860:        werase (Command);
                    861:        wrefresh (Command);
                    862: 
                    863:        if (nwait) {
                    864:            nwait = 0;
                    865:            wrefresh (w);
                    866:        }
                    867: 
                    868:        n = 0;
                    869: again:         ;
                    870:        switch (c) {
                    871:            case ' ': 
                    872:                ltop = lbottom -> l_next;
                    873:                nfresh++;
                    874:                break;
                    875: 
                    876:            case '\r': 
                    877:            case '\n': 
                    878:            case 'e': 
                    879:            case 'j': 
                    880:                if (n)
                    881:                    smallmove = n;
                    882:                if (ladvance (smallmove))
                    883:                    nfresh++;
                    884:                break;
                    885: 
                    886:            case 'y': 
                    887:            case 'k': 
                    888:                if (n)
                    889:                    smallmove = n;
                    890:                if (lretreat (smallmove))
                    891:                    nfresh++;
                    892:                break;
                    893: 
                    894:            case 'd': 
                    895:        eof:    ;
                    896:                if (n)
                    897:                    largemove = n;
                    898:                if (ladvance (largemove))
                    899:                    nfresh++;
                    900:                break;
                    901: 
                    902:            case 'u': 
                    903:                if (n)
                    904:                    largemove = n;
                    905:                if (lretreat (largemove))
                    906:                    nfresh++;
                    907:                break;
                    908: 
                    909:            case 'g': 
                    910:                if (lgo (n ? n : 1))
                    911:                    nfresh++;
                    912:                break;
                    913: 
                    914:            case 'G': 
                    915:                if (lgo (n ? n : ltail -> l_no - w -> _maxy + 1))
                    916:                    nfresh++;
                    917:                break;
                    918: 
                    919:            case '\f': 
                    920:            case 'r': 
                    921:                wrefresh (curscr);
                    922:                break;
                    923: 
                    924:            case 'h': 
                    925:            case '?': 
                    926:                werase (w);
                    927:                wmove (w, 0, 0);
                    928:                for (i = 0; hlpmsg[i].h_msg; i++) {
                    929:                    if (hlpmsg[i].h_val)
                    930:                        wprintw (w, hlpmsg[i].h_msg, *hlpmsg[i].h_val,
                    931:                                *hlpmsg[i].h_val != 1 ? "s" : "");
                    932:                    else
                    933:                        (void) waddstr (w, hlpmsg[i].h_msg);
                    934:                    (void) waddch (w, '\n');
                    935:                }
                    936:                wrefresh (w);
                    937:                nwait++;
                    938:                break;
                    939: 
                    940:            case 'q': 
                    941:                return 1;
                    942: 
                    943:            default: 
                    944:                if (c == EOFC)
                    945:                    goto eof;
                    946: 
                    947:                if (isdigit (c)) {
                    948:                    wmove (Command, 0, 0);
                    949:                    i = 0;
                    950:                    while (isdigit (c)) {
                    951:                        wprintw (Command, "%c", c);
                    952:                        wrefresh (Command);
                    953:                        i = i * 10 + c - '0';
                    954:                        c = toascii (wgetch (Command));
                    955:                    }
                    956:                    werase (Command);
                    957:                    wrefresh (Command);
                    958: 
                    959:                    if (i > 0) {
                    960:                        n = i;
                    961:                        goto again;
                    962:                    }
                    963:                    cp = "bad number";
                    964:                }
                    965:                else
                    966:                    cp = "not understood";
                    967:                break;
                    968:        }
                    969:     }
                    970: }
                    971: 
                    972: /*  */
                    973: 
                    974: static int  WINputc (w, c)
                    975: register WINDOW *w;
                    976: register char c;
                    977: {
                    978:     register int    x,
                    979:                     y;
                    980: 
                    981:     if (w != Scan)
                    982:        return waddch (w, c);
                    983: 
                    984:     if ((x = w -> _curx) < 0 || x >= w -> _maxx
                    985:            || (y = w -> _cury) < 0 || y >= w -> _maxy)
                    986:        return DONE;
                    987: 
                    988:     switch (c) {
                    989:        case '\t': 
                    990:            for (x = 8 - (x & 0x07); x > 0; x--)
                    991:                if (WINputc (w, ' ') == ERR)
                    992:                    return ERR;
                    993:            break;
                    994: 
                    995:        case '\n': 
                    996:            if (++y < w -> _maxy) 
                    997:                (void) waddch (w, c);
                    998:            else
                    999:                wclrtoeol (w);
                   1000:            break;
                   1001: 
                   1002:        default: 
                   1003:            if (++x < w -> _maxx) 
                   1004:                (void) waddch (w, c);
                   1005:            break;
                   1006:     }
                   1007:     return DONE;
                   1008: }
                   1009: 
                   1010: /*    LINES */
                   1011: 
                   1012: static  lreset () {
                   1013:     register struct line   *lp,
                   1014:                            *mp;
                   1015: 
                   1016:     for (lp = lhead; lp; lp = mp) {
                   1017:        mp = lp -> l_next;
                   1018:        free (lp -> l_buf);
                   1019:        free ((char *) lp);
                   1020:     }
                   1021:     lhead = ltop = ltail = NULL;
                   1022: }
                   1023: 
                   1024: 
                   1025: static linsert (w)
                   1026: WINDOW *w;
                   1027: {
                   1028:     register char  *cp;
                   1029:     register struct line   *lp;
                   1030: 
                   1031:     if ((lp = (struct line  *) calloc ((unsigned) 1, sizeof *lp)) == NULL)
                   1032:        adios (NULLCP, "unable to allocate line storage");
                   1033: 
                   1034:     lp -> l_no = (ltail ? ltail -> l_no : 0) + 1;
                   1035:     lp -> l_buf = getcpy (w -> _y[w -> _cury]);
                   1036:     for (cp = lp -> l_buf + strlen (lp -> l_buf) - 1; cp >= lp -> l_buf; cp--)
                   1037:        if (isspace (*cp))
                   1038:            *cp = NULL;
                   1039:        else
                   1040:            break;
                   1041: 
                   1042:     if (lhead == NULL)
                   1043:        lhead = lp;
                   1044:     if (ltop == NULL)
                   1045:        ltop = lp;
                   1046:     if (ltail)
                   1047:        ltail -> l_next = lp;
                   1048:     lp -> l_prev = ltail;
                   1049:     ltail = lp;
                   1050: }
                   1051: 
                   1052: /*  */
                   1053: 
                   1054: static int  ladvance (n)
                   1055: int    n;
                   1056: {
                   1057:     register int    i;
                   1058:     register struct line   *lp;
                   1059: 
                   1060:     for (i = 0, lp = ltop; i < n && lp; i++, lp = lp -> l_next)
                   1061:        continue;
                   1062: 
                   1063:     if (ltop == lp)
                   1064:        return 0;
                   1065: 
                   1066:     ltop = lp;
                   1067:     return 1;
                   1068: }
                   1069: 
                   1070: 
                   1071: static int  lretreat (n)
                   1072: int    n;
                   1073: {
                   1074:     register int    i;
                   1075:     register struct line   *lp;
                   1076: 
                   1077:     for (i = 0, lp = ltop; i < n && lp; i++, lp = lp -> l_prev)
                   1078:        if (!lp -> l_prev)
                   1079:            break;
                   1080: 
                   1081:     if (ltop == lp)
                   1082:        return 0;
                   1083: 
                   1084:     ltop = lp;
                   1085:     return 1;
                   1086: }
                   1087: 
                   1088: /*  */
                   1089: 
                   1090: static int  lgo (n)
                   1091: int    n;
                   1092: {
                   1093:     register int    i,
                   1094:                     j;
                   1095:     register struct line   *lp;
                   1096: 
                   1097:     if ((i = n - (lp = lhead) -> l_no) > (j = abs (n - ltop -> l_no)))
                   1098:        i = j, lp = ltop;
                   1099:     if (i > (j = abs (ltail -> l_no - n)))
                   1100:        i = j, lp = ltail;
                   1101: 
                   1102:     if (n >= lp -> l_no) {
                   1103:        for (; lp; lp = lp -> l_next)
                   1104:            if (lp -> l_no == n)
                   1105:                break;
                   1106:     }
                   1107:     else {
                   1108:        for (; lp; lp = lp -> l_prev)
                   1109:            if (lp -> l_no == n)
                   1110:                break;
                   1111:        if (!lp)
                   1112:            lp = lhead;
                   1113:     }
                   1114: 
                   1115:     if (ltop == lp)
                   1116:        return 0;
                   1117: 
                   1118:     ltop = lp;
                   1119:     return 1;
                   1120: }
                   1121: 
                   1122: /*    TTYS */
                   1123: 
                   1124: static int  TTYinit (nprog) {
                   1125:     if (!isatty (fileno (stdin)) || !isatty (fileno (stdout)))
                   1126:        if (nprog)
                   1127:            return NOTOK;
                   1128:        else
                   1129:            adios (NULLCP, "not a tty");
                   1130: 
                   1131:     foreground ();
                   1132: #ifndef        SYS5
                   1133:     if (ioctl (fileno (stdin), TIOCGETP, (char *) &sg) == NOTOK)
                   1134:        adios ("failed", "ioctl TIOCGETP");
                   1135:     if (ioctl (fileno (stdin), TIOCGETC, (char *) &tc) == NOTOK)
                   1136:        adios ("failed", "ioctl TIOCGETC");
                   1137: #else  SYS5
                   1138:     if (ioctl (fileno (stdin), TCGETA, &sg) == NOTOK)
                   1139:        adios ("failed", "ioctl TCGETA");
                   1140: #endif SYS5
                   1141: #ifdef TIOCGLTC
                   1142:     if (ioctl (fileno (stdin), TIOCGLTC, (char *) &ltc) == NOTOK)
                   1143:        adios ("failed", "ioctl TIOCGLTC");
                   1144: #endif TIOCGLTC
                   1145:     intrc = INTR;
                   1146:     sideground ();
                   1147: 
                   1148:     tty_ready = OK;
                   1149: 
                   1150:     (void) signal (SIGPIPE, PIPEser);
                   1151: 
                   1152:     return OK;
                   1153: }
                   1154: 
                   1155: /*  */
                   1156: 
                   1157: static TTYon () {
                   1158:     if (tty_ready == DONE)
                   1159:        return;
                   1160: 
                   1161:     INTR = NOTOK;
                   1162: #ifndef        SYS5
                   1163:     (void) ioctl (fileno (stdin), TIOCSETC, (char *) &tc);
                   1164: #else  SYS5
                   1165:     (void) ioctl (fileno (stdin), TCSETA, &sg);
                   1166: #endif SYS5
                   1167: 
                   1168:     (void) crmode ();
                   1169:     (void) noecho ();
                   1170:     (void) nonl ();
                   1171:     scrollok (curscr, FALSE);
                   1172: 
                   1173:     discard (stdin);
                   1174: 
                   1175:     tty_ready = DONE;
                   1176: 
                   1177:     (void) signal (SIGHUP, SIGser);
                   1178:     (void) signal (SIGINT, SIGser);
                   1179:     (void) signal (SIGQUIT, SIGser);
                   1180: #ifdef SIGTSTP
                   1181:     (void) signal (SIGTSTP, TSTPser);
                   1182: #endif SIGTSTP
                   1183: }
                   1184: 
                   1185: /*  */
                   1186: 
                   1187: static TTYoff () {
                   1188:     if (tty_ready == NOTOK)
                   1189:        return;
                   1190: 
                   1191:     INTR = intrc;
                   1192: #ifndef        SYS5
                   1193:     (void) ioctl (fileno (stdin), TIOCSETC, (char *) &tc);
                   1194: #else  SYS5
                   1195:     (void) ioctl (fileno (stdin), TCSETA, &sg);
                   1196: #endif SYS5
                   1197: 
                   1198:     leaveok (curscr, TRUE);
                   1199:     mvcur (0, COLS - 1, LINES - 1, 0);
                   1200:     endwin ();
                   1201:     if (tty_ready == DONE) {
                   1202: #ifndef        SYS5
                   1203:        if (CE)
                   1204:            tputs (CE, 0, _putchar);
                   1205:        else
                   1206: #endif SYS5
                   1207:            fprintf (stdout, "\r\n");
                   1208:     }
                   1209:     (void) fflush (stdout);
                   1210: 
                   1211:     tty_ready = NOTOK;
                   1212: 
                   1213:     (void) signal (SIGHUP, SIG_DFL);
                   1214:     (void) signal (SIGINT, SIG_DFL);
                   1215:     (void) signal (SIGQUIT, SIG_DFL);
                   1216: #ifdef SIGTSTP
                   1217:     (void) signal (SIGTSTP, SIG_DFL);
                   1218: #endif SIGTSTP
                   1219: }
                   1220: 
                   1221: /*  */
                   1222: 
                   1223: static  foreground () {
                   1224: #ifdef TIOCGPGRP
                   1225:     int     pgrp,
                   1226:             tpgrp;
                   1227:     int     (*tstat) ();
                   1228: 
                   1229:     if ((pgrp = getpgrp (0)) == NOTOK)
                   1230:        adios ("process group", "unable to determine");
                   1231:     for (;;) {
                   1232:        if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK)
                   1233:            adios ("tty's process group", "unable to determine");
                   1234:        if (pgrp == tpgrp)
                   1235:            break;
                   1236: 
                   1237:        tstat = signal (SIGTTIN, SIG_DFL);
                   1238:        (void) kill (0, SIGTTIN);
                   1239:        (void) signal (SIGTTIN, tstat);
                   1240:     }
                   1241:     
                   1242:     (void) signal (SIGTTIN, SIG_IGN);
                   1243:     (void) signal (SIGTTOU, SIG_IGN);
                   1244:     (void) signal (SIGTSTP, SIG_IGN);
                   1245: #endif TIOCGPGRP
                   1246: }
                   1247: 
                   1248: 
                   1249: sideground () {
                   1250: #ifdef TIOCGPGRP
                   1251:     (void) signal (SIGTTIN, SIG_DFL);
                   1252:     (void) signal (SIGTTOU, SIG_DFL);
                   1253:     (void) signal (SIGTSTP, SIG_DFL);
                   1254: #endif TIOCGPGRP
                   1255: }
                   1256: 
                   1257: /*    SIGNALS */
                   1258: 
                   1259: /* ARGSUSED */
                   1260: 
                   1261: static int  ALRMser (sig)
                   1262: int     sig;
                   1263: {
                   1264:      longjmp (PEERctx, DONE);
                   1265: }
                   1266: 
                   1267: 
                   1268: #ifdef BSD42
                   1269: /* ARGSUSED */
                   1270: #endif BSD42
                   1271: 
                   1272: static int  PIPEser (sig)
                   1273: int    sig;
                   1274: {
                   1275: #ifndef        BSD42
                   1276:     (void) signal (sig, SIG_IGN);
                   1277: #endif BSD42
                   1278: 
                   1279:     adios (NULLCP, "lost peer");
                   1280: }
                   1281: 
                   1282: 
                   1283: #ifdef BSD42
                   1284: /* ARGSUSED */
                   1285: #endif BSD42
                   1286: 
                   1287: static int  SIGser (sig)
                   1288: int     sig;
                   1289: {
                   1290: #ifndef        BSD42
                   1291:     (void) signal (sig, SIG_IGN);
                   1292: #endif BSD42
                   1293: 
                   1294:     done (1);
                   1295: }
                   1296: 
                   1297: 
                   1298: #ifdef SIGTSTP
                   1299: static int  TSTPser (sig)
                   1300: int     sig;
                   1301: {
                   1302:     tputs (tgoto (CM, 0, LINES - 1), 0, _putchar);
                   1303:     (void) fflush (stdout);
                   1304: 
                   1305:     TTYoff ();
                   1306: #ifdef BSD42
                   1307:     (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
                   1308: #endif BSD42
                   1309: 
                   1310:     (void) kill (getpid (), sig);
                   1311: 
                   1312: #ifdef BSD42
                   1313:     (void) sigblock (sigmask (SIGTSTP));
                   1314: #endif BSD42
                   1315:     TTYon ();
                   1316: 
                   1317:     wrefresh (curscr);
                   1318: }
                   1319: #endif SIGTSTP
                   1320: 
                   1321: /*    MISCELLANY */
                   1322: 
                   1323: void   done (status)
                   1324: int    status;
                   1325: {
                   1326:     TTYoff ();
                   1327:     (void) pFIN ();
                   1328: 
                   1329:     exit (status);
                   1330: }
                   1331: 
                   1332: /*  */
                   1333: 
                   1334: /* VARARGS2 */
                   1335: 
                   1336: static void  adorn (what, fmt, a, b, c, d, e, f)
                   1337: char   *what,
                   1338:        *fmt,
                   1339:        *a,
                   1340:        *b,
                   1341:        *c,
                   1342:        *d,
                   1343:        *e,
                   1344:        *f;
                   1345: {
                   1346:     char   *cp = invo_name;
                   1347: 
                   1348:     invo_name = NULL;
                   1349:     advise (what, fmt, a, b, c, d, e, f);
                   1350:     invo_name = cp;
                   1351: }
                   1352: 
                   1353: /*  */
                   1354: 
                   1355: /* VARARGS3 */
                   1356: 
                   1357: void advertise (what, tail, fmt, a, b, c, d, e, f)
                   1358: char   *what,
                   1359:        *tail,
                   1360:        *fmt,
                   1361:        *a,
                   1362:        *b,
                   1363:        *c,
                   1364:        *d,
                   1365:        *e,
                   1366:        *f;
                   1367: {
                   1368:     int            eindex = errno;
                   1369:     char    buffer[BUFSIZ],
                   1370:             err[BUFSIZ];
                   1371:     struct iovec    iob[20];
                   1372:     register struct iovec  *iov = iob;
                   1373: 
                   1374:     (void) fflush (stdout);
                   1375: 
                   1376:     (void) fflush (stderr);
                   1377: 
                   1378:     if (invo_name) {
                   1379:        iov -> iov_len = strlen (iov -> iov_base = invo_name);
                   1380:        iov++;
                   1381:        iov -> iov_len = strlen (iov -> iov_base = ": ");
                   1382:        iov++;
                   1383:     }
                   1384:     
                   1385:     (void) sprintf (buffer, fmt, a, b, c, d, e, f);
                   1386:     iov -> iov_len = strlen (iov -> iov_base = buffer);
                   1387:     iov++;
                   1388:     if (what) {
                   1389:        if (*what) {
                   1390:            iov -> iov_len = strlen (iov -> iov_base = " ");
                   1391:            iov++;
                   1392:            iov -> iov_len = strlen (iov -> iov_base = what);
                   1393:            iov++;
                   1394:            iov -> iov_len = strlen (iov -> iov_base = ": ");
                   1395:            iov++;
                   1396:        }
                   1397:        if (eindex > 0 && eindex < sys_nerr)
                   1398:            iov -> iov_len = strlen (iov -> iov_base = sys_errlist[eindex]);
                   1399:        else {
                   1400:            (void) sprintf (err, "Error %d", eindex);
                   1401:            iov -> iov_len = strlen (iov -> iov_base = err);
                   1402:        }
                   1403:        iov++;
                   1404:     }
                   1405:     if (tail && *tail) {
                   1406:        iov -> iov_len = strlen (iov -> iov_base = ", ");
                   1407:        iov++;
                   1408:        iov -> iov_len = strlen (iov -> iov_base = tail);
                   1409:        iov++;
                   1410:     }
                   1411:     iov -> iov_len = strlen (iov -> iov_base = "\n");
                   1412:     iov++;
                   1413: 
                   1414:     if (tty_ready == DONE)
                   1415:        (void) WINwritev (Display, iob, iov - iob);
                   1416:     else
                   1417:        (void) writev (fileno (stderr), iob, iov - iob);
                   1418: }
                   1419: 
                   1420: /*  */
                   1421: 
                   1422: #ifndef        BSD42
                   1423: static int     writev (fd, iov, n)
                   1424: register int     fd;
                   1425: register struct iovec   *iov;
                   1426: register int     n;
                   1427: {
                   1428:     register int    i,
                   1429:                     j;
                   1430: 
                   1431:     for (i = j = 0; i < n; i++, iov++)
                   1432:        if (write (fd, iov -> iov_base, iov -> iov_len) != iov -> iov_len)
                   1433:            break;
                   1434:        else
                   1435:            j += iov -> iov_len;
                   1436: 
                   1437:     return j;
                   1438: }
                   1439: #endif BSD42

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.