[BACK]Return to unix.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/unix.c, Revision 1.4

1.4     ! downsj      1: /* $OpenBSD: unix.c,v 1.3 1996/10/14 03:55:32 downsj Exp $ */
1.1       downsj      2: /* vi:set ts=4 sw=4:
                      3:  *
                      4:  * VIM - Vi IMproved       by Bram Moolenaar
                      5:  *                OS/2 port by Paul Slootman
                      6:  *
                      7:  * Do ":help uganda"  in Vim to read copying and usage conditions.
                      8:  * Do ":help credits" in Vim to see a list of people who contributed.
                      9:  */
                     10:
                     11: /*
                     12:  * unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
                     13:  *           Also for OS/2, using the excellent EMX package!!!
                     14:  *
                     15:  * A lot of this file was originally written by Juergen Weigert and later
                     16:  * changed beyond recognition.
                     17:  */
                     18:
                     19: /*
                     20:  * Some systems have a prototype for select() that has (int *) instead of
                     21:  * (fd_set *), which is wrong. This define removes that prototype. We include
                     22:  * our own prototype in osdef.h.
                     23:  */
                     24: #define select select_declared_wrong
                     25:
                     26: #include "vim.h"
                     27: #include "globals.h"
                     28: #include "option.h"
                     29: #include "proto.h"
                     30:
                     31: #ifdef HAVE_FCNTL_H
                     32: # include <fcntl.h>
                     33: #endif
                     34:
                     35: #include "unixunix.h"      /* unix includes for unix.c only */
                     36:
                     37: /*
                     38:  * Use this prototype for select, some include files have a wrong prototype
                     39:  */
                     40: #undef select
                     41:
                     42: #if defined(HAVE_SELECT)
                     43: extern int   select __ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
                     44: #endif
                     45:
                     46: /*
                     47:  * end of autoconf section. To be extended...
                     48:  */
                     49:
                     50: /* Are the following #ifdefs still required? And why? Is that for X11? */
                     51:
                     52: #if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
                     53: # ifdef SIGWINCH
                     54: #  undef SIGWINCH
                     55: # endif
                     56: # ifdef TIOCGWINSZ
                     57: #  undef TIOCGWINSZ
                     58: # endif
                     59: #endif
                     60:
                     61: #if defined(SIGWINDOW) && !defined(SIGWINCH)   /* hpux 9.01 has it */
                     62: # define SIGWINCH SIGWINDOW
                     63: #endif
                     64:
                     65: #if defined(HAVE_X11) && defined(WANT_X11)
                     66: # include <X11/Xlib.h>
                     67: # include <X11/Xutil.h>
                     68: # include <X11/Xatom.h>
                     69:
                     70: Window     x11_window = 0;
                     71: Display        *x11_display = NULL;
                     72: int            got_x_error = FALSE;
                     73:
                     74: static int get_x11_windis __ARGS((void));
                     75: static void set_x11_title __ARGS((char_u *));
                     76: static void set_x11_icon __ARGS((char_u *));
                     77: #endif
                     78:
                     79: static int get_x11_title __ARGS((int));
                     80: static int get_x11_icon __ARGS((int));
                     81:
                     82: static void may_core_dump __ARGS((void));
                     83:
                     84: static int Read __ARGS((char_u *, long));
                     85: static int WaitForChar __ARGS((long));
                     86: static int RealWaitForChar __ARGS((int, long));
                     87: static void fill_inbuf __ARGS((int));
                     88:
                     89: #if defined(SIGWINCH)
                     90: static RETSIGTYPE sig_winch __ARGS(SIGPROTOARG);
                     91: #endif
                     92: #if defined(SIGALRM) && defined(HAVE_X11) && defined(WANT_X11)
                     93: static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
                     94: #endif
                     95: static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
                     96:
                     97: static void catch_signals __ARGS((RETSIGTYPE (*func)()));
                     98: #ifndef __EMX__
                     99: static int have_wildcard __ARGS((int, char_u **));
                    100: static int have_dollars __ARGS((int, char_u **));
                    101: #endif
                    102:
                    103: static int     do_resize = FALSE;
                    104: static char_u  *oldtitle = NULL;
                    105: static char_u  *fixedtitle = (char_u *)"Thanks for flying Vim";
                    106: static char_u  *oldicon = NULL;
                    107: #ifndef __EMX__
                    108: static char_u  *extra_shell_arg = NULL;
                    109: static int     show_shell_mess = TRUE;
                    110: #endif
1.3       downsj    111: static int     deadly_signal = 0;          /* The signal we caught */
1.1       downsj    112:
                    113: #ifdef SYS_SIGLIST_DECLARED
                    114: /*
                    115:  * I have seen
                    116:  *     extern char *_sys_siglist[NSIG];
                    117:  * on Irix, Linux, NetBSD and Solaris. It contains a nice list of strings
                    118:  * that describe the signals. That is nearly what we want here.  But
                    119:  * autoconf does only check for sys_siglist (without the underscore), I
                    120:  * do not want to change everything today.... jw.
                    121:  * This is why AC_DECL_SYS_SIGLIST is commented out in configure.in
                    122:  */
                    123: #endif
                    124:
                    125: static struct
                    126: {
                    127:    int     sig;        /* Signal number, eg. SIGSEGV etc */
                    128:    char    *name;      /* Signal name (not char_u!). */
                    129: } signal_info[] =
                    130: {
                    131: #ifdef SIGHUP
1.3       downsj    132:    {SIGHUP,        "HUP"},
1.1       downsj    133: #endif
                    134: #ifdef SIGINT
1.3       downsj    135:    {SIGINT,        "INT"},
1.1       downsj    136: #endif
                    137: #ifdef SIGQUIT
1.3       downsj    138:    {SIGQUIT,       "QUIT"},
1.1       downsj    139: #endif
                    140: #ifdef SIGILL
1.3       downsj    141:    {SIGILL,        "ILL"},
1.1       downsj    142: #endif
                    143: #ifdef SIGTRAP
1.3       downsj    144:    {SIGTRAP,       "TRAP"},
1.1       downsj    145: #endif
                    146: #ifdef SIGABRT
1.3       downsj    147:    {SIGABRT,       "ABRT"},
1.1       downsj    148: #endif
                    149: #ifdef SIGEMT
1.3       downsj    150:    {SIGEMT,        "EMT"},
1.1       downsj    151: #endif
                    152: #ifdef SIGFPE
1.3       downsj    153:    {SIGFPE,        "FPE"},
1.1       downsj    154: #endif
                    155: #ifdef SIGBUS
1.3       downsj    156:    {SIGBUS,        "BUS"},
1.1       downsj    157: #endif
                    158: #ifdef SIGSEGV
1.3       downsj    159:    {SIGSEGV,       "SEGV"},
1.1       downsj    160: #endif
                    161: #ifdef SIGSYS
1.3       downsj    162:    {SIGSYS,        "SYS"},
1.1       downsj    163: #endif
                    164: #ifdef SIGALRM
1.3       downsj    165:    {SIGALRM,       "ALRM"},
1.1       downsj    166: #endif
                    167: #ifdef SIGTERM
1.3       downsj    168:    {SIGTERM,       "TERM"},
1.1       downsj    169: #endif
                    170: #ifdef SIGVTALRM
1.3       downsj    171:    {SIGVTALRM,     "VTALRM"},
1.1       downsj    172: #endif
                    173: #ifdef SIGPROF
1.3       downsj    174:    {SIGPROF,       "PROF"},
1.1       downsj    175: #endif
                    176: #ifdef SIGXCPU
1.3       downsj    177:    {SIGXCPU,       "XCPU"},
1.1       downsj    178: #endif
                    179: #ifdef SIGXFSZ
1.3       downsj    180:    {SIGXFSZ,       "XFSZ"},
1.1       downsj    181: #endif
                    182: #ifdef SIGUSR1
1.3       downsj    183:    {SIGUSR1,       "USR1"},
1.1       downsj    184: #endif
                    185: #ifdef SIGUSR2
1.3       downsj    186:    {SIGUSR2,       "USR2"},
1.1       downsj    187: #endif
1.3       downsj    188:    {-1,            "Unknown!"}
1.1       downsj    189: };
                    190:
                    191:    void
                    192: mch_write(s, len)
                    193:    char_u  *s;
                    194:    int     len;
                    195: {
                    196: #ifdef USE_GUI
                    197:    if (gui.in_use && !gui.dying)
                    198:    {
                    199:        gui_write(s, len);
                    200:        if (p_wd)
                    201:            gui_mch_wait_for_chars(p_wd);
                    202:    }
                    203:    else
                    204: #endif
                    205:    {
                    206:        write(1, (char *)s, len);
                    207:        if (p_wd)           /* Unix is too fast, slow down a bit more */
                    208:            RealWaitForChar(0, p_wd);
                    209:    }
                    210: }
                    211:
                    212: /*
                    213:  * mch_inchar(): low level input funcion.
                    214:  * Get a characters from the keyboard.
                    215:  * Return the number of characters that are available.
                    216:  * If wtime == 0 do not wait for characters.
                    217:  * If wtime == n wait a short time for characters.
                    218:  * If wtime == -1 wait forever for characters.
                    219:  */
                    220:    int
                    221: mch_inchar(buf, maxlen, wtime)
                    222:    char_u  *buf;
                    223:    int     maxlen;
                    224:    long    wtime;          /* don't use "time", MIPS cannot handle it */
                    225: {
                    226:    int         len;
                    227:
                    228: #ifdef USE_GUI
                    229:    if (gui.in_use)
                    230:    {
                    231:        if (!gui_mch_wait_for_chars(wtime))
                    232:            return 0;
                    233:        return Read(buf, (long)maxlen);
                    234:    }
                    235: #endif
                    236:
                    237:    if (wtime >= 0)
                    238:    {
                    239:        while (WaitForChar(wtime) == 0)     /* no character available */
                    240:        {
                    241:            if (!do_resize)         /* return if not interrupted by resize */
                    242:                return 0;
                    243:            set_winsize(0, 0, FALSE);
                    244:            do_resize = FALSE;
                    245:        }
                    246:    }
                    247:    else        /* wtime == -1 */
                    248:    {
                    249:    /*
                    250:     * If there is no character available within 'updatetime' seconds
                    251:     * flush all the swap files to disk
                    252:     * Also done when interrupted by SIGWINCH.
                    253:     */
                    254:        if (WaitForChar(p_ut) == 0)
                    255:            updatescript(0);
                    256:    }
                    257:
                    258:    for (;;)    /* repeat until we got a character */
                    259:    {
                    260:        if (do_resize)      /* window changed size */
                    261:        {
                    262:            set_winsize(0, 0, FALSE);
                    263:            do_resize = FALSE;
                    264:        }
                    265:        /*
                    266:         * we want to be interrupted by the winch signal
                    267:         */
                    268:        WaitForChar(-1L);
                    269:        if (do_resize)      /* interrupted by SIGWINCHsignal */
                    270:            continue;
                    271:
                    272:        /*
                    273:         * For some terminals we only get one character at a time.
                    274:         * We want the get all available characters, so we could keep on
                    275:         * trying until none is available
                    276:         * For some other terminals this is quite slow, that's why we don't do
                    277:         * it.
                    278:         */
                    279:        len = Read(buf, (long)maxlen);
                    280:        if (len > 0)
                    281:        {
                    282: #ifdef OS2
                    283:            int i;
                    284:
                    285:            for (i = 0; i < len; i++)
                    286:                if (buf[i] == 0)
                    287:                    buf[i] = K_NUL;
                    288: #endif
                    289:            return len;
                    290:        }
                    291:    }
                    292: }
                    293:
                    294: /*
                    295:  * return non-zero if a character is available
                    296:  */
                    297:    int
                    298: mch_char_avail()
                    299: {
                    300: #ifdef USE_GUI
                    301:    if (gui.in_use)
                    302:    {
                    303:        gui_mch_update();
                    304:        return !is_input_buf_empty();
                    305:    }
                    306: #endif
                    307:    return WaitForChar(0L);
                    308: }
                    309:
                    310:    long
                    311: mch_avail_mem(special)
                    312:    int special;
                    313: {
                    314: #ifdef __EMX__
                    315:    return ulimit(3, 0L);   /* always 32MB? */
                    316: #else
                    317:    return 0x7fffffff;      /* virtual memory eh */
                    318: #endif
                    319: }
                    320:
                    321:    void
                    322: mch_delay(msec, ignoreinput)
                    323:    long        msec;
                    324:    int         ignoreinput;
                    325: {
                    326:    if (ignoreinput)
                    327: #ifndef HAVE_SELECT
                    328:        poll(NULL, 0, (int)msec);
                    329: #else
                    330: # ifdef __EMX__
                    331:    _sleep2(msec);
                    332: # else
                    333:    {
                    334:        struct timeval tv;
                    335:
                    336:        tv.tv_sec = msec / 1000;
                    337:        tv.tv_usec = (msec % 1000) * 1000;
                    338:        select(0, NULL, NULL, NULL, &tv);
                    339:    }
                    340: # endif    /* __EMX__ */
                    341: #endif /* HAVE_SELECT */
                    342:    else
                    343: #ifdef USE_GUI
                    344:        if (gui.in_use)
                    345:            gui_mch_wait_for_chars(msec);
                    346:        else
                    347: #endif
                    348:            WaitForChar(msec);
                    349: }
                    350:
                    351: #if defined(SIGWINCH)
                    352: /*
                    353:  * We need correct potatotypes, otherwise mean compilers will barf when the
                    354:  * second argument to signal() is ``wrong''.
                    355:  * Let me try it with a few tricky defines from my own osdef.h  (jw).
                    356:  */
                    357:    static RETSIGTYPE
                    358: sig_winch SIGDEFARG(sigarg)
                    359: {
                    360:    /* this is not required on all systems, but it doesn't hurt anybody */
                    361:    signal(SIGWINCH, (RETSIGTYPE (*)())sig_winch);
                    362:    do_resize = TRUE;
                    363:    SIGRETURN;
                    364: }
                    365: #endif
                    366:
                    367: #if defined(SIGALRM) && defined(HAVE_X11) && defined(WANT_X11)
                    368: /*
                    369:  * signal function for alarm().
                    370:  */
                    371:    static RETSIGTYPE
                    372: sig_alarm SIGDEFARG(sigarg)
                    373: {
                    374:    /* doesn't do anything, just to break a system call */
                    375:    SIGRETURN;
                    376: }
                    377: #endif
                    378:
                    379:    void
                    380: mch_resize()
                    381: {
                    382:    do_resize = TRUE;
                    383: }
                    384:
                    385: /*
                    386:  * This function handles deadly signals.
                    387:  * It tries to preserve any swap file and exit properly.
                    388:  * (partly from Elvis).
                    389:  */
                    390:    static RETSIGTYPE
                    391: deathtrap SIGDEFARG(sigarg)
                    392: {
                    393:    static int      entered = 0;
                    394: #ifdef SIGHASARG
                    395:    int     i;
                    396:
1.3       downsj    397:    /* try to find the name of this signal */
                    398:    for (i = 0; signal_info[i].sig != -1; i++)
1.1       downsj    399:        if (sigarg == signal_info[i].sig)
                    400:            break;
1.3       downsj    401:    deadly_signal = sigarg;
1.1       downsj    402: #endif
                    403:
                    404:    /*
                    405:     * If something goes wrong after entering here, we may get here again.
                    406:     * When this happens, give a message and try to exit nicely (resetting the
                    407:     * terminal mode, etc.)
                    408:     * When this happens twice, just exit, don't even try to give a message,
                    409:     * stack may be corrupt or something weird.
                    410:     */
                    411:    if (entered == 2)
                    412:    {
                    413:        may_core_dump();
                    414:        exit(7);
                    415:    }
1.4     ! downsj    416:    if (entered++)
1.1       downsj    417:    {
                    418:        OUTSTR("Vim: Double signal, exiting\n");
                    419:        flushbuf();
                    420:        getout(1);
                    421:    }
                    422:
                    423:    sprintf((char *)IObuff, "Vim: Caught %s %s\n",
                    424: #ifdef SIGHASARG
                    425:                    "deadly signal", signal_info[i].name);
                    426: #else
                    427:                    "some", "deadly signal");
                    428: #endif
                    429:
                    430:    preserve_exit();                /* preserve files and exit */
                    431:
                    432:    SIGRETURN;
                    433: }
                    434:
                    435: /*
                    436:  * If the machine has job control, use it to suspend the program,
                    437:  * otherwise fake it by starting a new shell.
                    438:  * When running the GUI iconify the window.
                    439:  */
                    440:    void
                    441: mch_suspend()
                    442: {
                    443: #ifdef USE_GUI
                    444:    if (gui.in_use)
                    445:    {
                    446:        gui_mch_iconify();
                    447:        return;
                    448:    }
                    449: #endif
                    450: #ifdef SIGTSTP
                    451:    flushbuf();             /* needed to make cursor visible on some systems */
                    452:    settmode(0);
                    453:    flushbuf();             /* needed to disable mouse on some systems */
                    454:    kill(0, SIGTSTP);       /* send ourselves a STOP signal */
                    455:
                    456:    /*
                    457:     * Set oldtitle to NULL, so the current title is obtained again.
                    458:     */
                    459:    if (oldtitle != fixedtitle)
                    460:    {
                    461:        vim_free(oldtitle);
                    462:        oldtitle = NULL;
                    463:    }
                    464:    settmode(1);
                    465: #else
                    466:    MSG_OUTSTR("new shell started\n");
                    467:    (void)call_shell(NULL, SHELL_COOKED);
                    468: #endif
                    469:    need_check_timestamps = TRUE;
                    470: }
                    471:
                    472:    void
                    473: mch_windinit()
                    474: {
                    475:    Columns = 80;
                    476:    Rows = 24;
                    477:
                    478:    flushbuf();
                    479:
                    480:    (void)mch_get_winsize();
                    481:
                    482: #if defined(SIGWINCH)
                    483:    /*
                    484:     * WINDOW CHANGE signal is handled with sig_winch().
                    485:     */
                    486:    signal(SIGWINCH, (RETSIGTYPE (*)())sig_winch);
                    487: #endif
                    488:
                    489:    /*
                    490:     * We want the STOP signal to work, to make mch_suspend() work
                    491:     */
                    492: #ifdef SIGTSTP
                    493:    signal(SIGTSTP, SIG_DFL);
                    494: #endif
                    495:
                    496:    /*
                    497:     * We want to ignore breaking of PIPEs.
                    498:     */
                    499: #ifdef SIGPIPE
                    500:    signal(SIGPIPE, SIG_IGN);
                    501: #endif
                    502:
                    503:    /*
                    504:     * Arrange for other signals to gracefully shutdown Vim.
                    505:     */
                    506:    catch_signals(deathtrap);
                    507: }
                    508:
                    509:    static void
                    510: catch_signals(func)
                    511:    RETSIGTYPE (*func)();
                    512: {
                    513:    int     i;
                    514:
1.3       downsj    515:    for (i = 0; signal_info[i].sig != -1; i++)
1.1       downsj    516:        signal(signal_info[i].sig, func);
                    517: }
                    518:
                    519:    void
                    520: reset_signals()
                    521: {
                    522:    catch_signals(SIG_DFL);
                    523: }
                    524:
                    525: /*
                    526:  * Check_win checks whether we have an interactive window.
                    527:  */
                    528:    int
                    529: mch_check_win(argc, argv)
                    530:    int     argc;
                    531:    char    **argv;
                    532: {
                    533:    if (isatty(1))
                    534:        return OK;
                    535:    return FAIL;
                    536: }
                    537:
                    538:    int
                    539: mch_check_input()
                    540: {
                    541:    if (isatty(0))
                    542:        return OK;
                    543:    return FAIL;
                    544: }
                    545:
                    546: #if defined(HAVE_X11) && defined(WANT_X11)
                    547: /*
                    548:  * X Error handler, otherwise X just exits!  (very rude) -- webb
                    549:  */
                    550:    static int
                    551: x_error_handler(dpy, error_event)
                    552:    Display     *dpy;
                    553:    XErrorEvent *error_event;
                    554: {
                    555:    XGetErrorText(dpy, error_event->error_code, (char *)IObuff, IOSIZE);
                    556:    STRCAT(IObuff, "\nVim: Got X error\n");
                    557:
                    558: #if 1
                    559:    preserve_exit();                /* preserve files and exit */
                    560: #else
                    561:    printf(IObuff);                 /* print error message and continue */
                    562:                                    /* Makes my system hang */
                    563: #endif
                    564:
                    565:    return 0;           /* NOTREACHED */
                    566: }
                    567:
                    568: /*
                    569:  * Another X Error handler, just used to check for errors.
                    570:  */
                    571:    static int
                    572: x_error_check(dpy, error_event)
                    573:    Display *dpy;
                    574:    XErrorEvent *error_event;
                    575: {
                    576:    got_x_error = TRUE;
                    577:    return 0;
                    578: }
                    579:
                    580: /*
                    581:  * try to get x11 window and display
                    582:  *
                    583:  * return FAIL for failure, OK otherwise
                    584:  */
                    585:    static int
                    586: get_x11_windis()
                    587: {
                    588:    char            *winid;
                    589:    XTextProperty   text_prop;
                    590:    int             (*old_handler)();
                    591:    static int      result = -1;
                    592:    static int      x11_display_opened_here = FALSE;
                    593:
                    594:    /* X just exits if it finds an error otherwise! */
                    595:    XSetErrorHandler(x_error_handler);
                    596:
                    597: #ifdef USE_GUI_X11
                    598:    if (gui.in_use)
                    599:    {
                    600:        /*
                    601:         * If the X11 display was opened here before, for the window where Vim
                    602:         * was started, close that one now to avoid a memory leak.
                    603:         */
                    604:        if (x11_display_opened_here && x11_display != NULL)
                    605:        {
                    606:            XCloseDisplay(x11_display);
                    607:            x11_display = NULL;
                    608:            x11_display_opened_here = FALSE;
                    609:        }
                    610:        return gui_get_x11_windis(&x11_window, &x11_display);
                    611:    }
                    612: #endif
                    613:
                    614:    if (result != -1)       /* Have already been here and set this */
                    615:        return result;      /* Don't do all these X calls again */
                    616:
                    617:    /*
                    618:     * If WINDOWID not set, should try another method to find out
                    619:     * what the current window number is. The only code I know for
                    620:     * this is very complicated.
                    621:     * We assume that zero is invalid for WINDOWID.
                    622:     */
                    623:    if (x11_window == 0 && (winid = getenv("WINDOWID")) != NULL)
                    624:        x11_window = (Window)atol(winid);
                    625:    if (x11_window != 0 && x11_display == NULL)
                    626:    {
                    627: #ifdef SIGALRM
                    628:        RETSIGTYPE (*sig_save)();
                    629:
                    630:        /*
                    631:         * Opening the Display may hang if the DISPLAY setting is wrong, or
                    632:         * the network connection is bad.  Set an alarm timer to get out.
                    633:         */
                    634:        sig_save = (RETSIGTYPE (*)())signal(SIGALRM,
                    635:                                                 (RETSIGTYPE (*)())sig_alarm);
                    636:        alarm(2);
                    637: #endif
                    638:        x11_display = XOpenDisplay(NULL);
                    639: #ifdef SIGALRM
                    640:        alarm(0);
                    641:        signal(SIGALRM, (RETSIGTYPE (*)())sig_save);
                    642: #endif
                    643:        if (x11_display != NULL)
                    644:        {
                    645:            /*
                    646:             * Try to get the window title.  I don't actually want it yet, so
                    647:             * there may be a simpler call to use, but this will cause the
                    648:             * error handler x_error_check() to be called if anything is wrong,
                    649:             * such as the window pointer being invalid (as can happen when the
                    650:             * user changes his DISPLAY, but not his WINDOWID) -- webb
                    651:             */
                    652:            old_handler = XSetErrorHandler(x_error_check);
                    653:            got_x_error = FALSE;
                    654:            if (XGetWMName(x11_display, x11_window, &text_prop))
                    655:                XFree((void *)text_prop.value);
                    656:            XSync(x11_display, False);
                    657:            if (got_x_error)
                    658:            {
                    659:                /* Maybe window id is bad */
                    660:                x11_window = 0;
                    661:                XCloseDisplay(x11_display);
                    662:                x11_display = NULL;
                    663:            }
                    664:            else
                    665:                x11_display_opened_here = TRUE;
                    666:            XSetErrorHandler(old_handler);
                    667:        }
                    668:    }
                    669:    if (x11_window == 0 || x11_display == NULL)
                    670:        return (result = FAIL);
                    671:    return (result = OK);
                    672: }
                    673:
                    674: /*
                    675:  * Determine original x11 Window Title
                    676:  */
                    677:    static int
                    678: get_x11_title(test_only)
                    679:    int     test_only;
                    680: {
                    681:    XTextProperty   text_prop;
                    682:    int             retval = FALSE;
                    683:
                    684:    if (get_x11_windis() == OK)
                    685:    {
                    686:            /* Get window name if any */
                    687:        if (XGetWMName(x11_display, x11_window, &text_prop))
                    688:        {
                    689:            if (text_prop.value != NULL)
                    690:            {
                    691:                retval = TRUE;
                    692:                if (!test_only)
                    693:                    oldtitle = strsave((char_u *)text_prop.value);
                    694:            }
                    695:            XFree((void *)text_prop.value);
                    696:        }
                    697:    }
                    698:    if (oldtitle == NULL && !test_only)     /* could not get old title */
                    699:        oldtitle = fixedtitle;
                    700:
                    701:    return retval;
                    702: }
                    703:
                    704: /*
                    705:  * Determine original x11 Window icon
                    706:  */
                    707:
                    708:    static int
                    709: get_x11_icon(test_only)
                    710:    int     test_only;
                    711: {
                    712:    XTextProperty   text_prop;
                    713:    int             retval = FALSE;
                    714:
                    715:    if (get_x11_windis() == OK)
                    716:    {
                    717:            /* Get icon name if any */
                    718:        if (XGetWMIconName(x11_display, x11_window, &text_prop))
                    719:        {
                    720:            if (text_prop.value != NULL)
                    721:            {
                    722:                retval = TRUE;
                    723:                if (!test_only)
                    724:                    oldicon = strsave((char_u *)text_prop.value);
                    725:            }
                    726:            XFree((void *)text_prop.value);
                    727:        }
                    728:    }
                    729:
                    730:        /* could not get old icon, use terminal name */
                    731:    if (oldicon == NULL && !test_only)
                    732:    {
                    733:        if (STRNCMP(term_strings[KS_NAME], "builtin_", 8) == 0)
                    734:            oldicon = term_strings[KS_NAME] + 8;
                    735:        else
                    736:            oldicon = term_strings[KS_NAME];
                    737:    }
                    738:
                    739:    return retval;
                    740: }
                    741:
                    742: /*
                    743:  * Set x11 Window Title
                    744:  *
                    745:  * get_x11_windis() must be called before this and have returned OK
                    746:  */
                    747:     static void
                    748: set_x11_title(title)
                    749:     char_u      *title;
                    750: {
                    751: #if XtSpecificationRelease >= 4
                    752:     XTextProperty text_prop;
                    753:
                    754:     text_prop.value = title;
                    755:     text_prop.nitems = STRLEN(title);
                    756:     text_prop.encoding = XA_STRING;
                    757:     text_prop.format = 8;
                    758:     XSetWMName(x11_display, x11_window, &text_prop);
                    759: #else
                    760:     XStoreName(x11_display, x11_window, (char *)title);
                    761: #endif
                    762:     XFlush(x11_display);
                    763: }
                    764:
                    765: /*
                    766:  * Set x11 Window icon
                    767:  *
                    768:  * get_x11_windis() must be called before this and have returned OK
                    769:  */
                    770:     static void
                    771: set_x11_icon(icon)
                    772:     char_u      *icon;
                    773: {
                    774: #if XtSpecificationRelease >= 4
                    775:     XTextProperty text_prop;
                    776:
                    777:     text_prop.value = icon;
                    778:     text_prop.nitems = STRLEN(icon);
                    779:     text_prop.encoding = XA_STRING;
                    780:     text_prop.format = 8;
                    781:     XSetWMIconName(x11_display, x11_window, &text_prop);
                    782: #else
                    783:     XSetIconName(x11_display, x11_window, (char *)icon);
                    784: #endif
                    785:     XFlush(x11_display);
                    786: }
                    787:
                    788: #else  /* HAVE_X11 && WANT_X11 */
                    789:
                    790:    static int
                    791: get_x11_title(test_only)
                    792:    int     test_only;
                    793: {
                    794:    if (!test_only)
                    795:        oldtitle = fixedtitle;
                    796:    return FALSE;
                    797: }
                    798:
                    799:    static int
                    800: get_x11_icon(test_only)
                    801:    int     test_only;
                    802: {
                    803:    if (!test_only)
                    804:    {
                    805:        if (STRNCMP(term_strings[KS_NAME], "builtin_", 8) == 0)
                    806:            oldicon = term_strings[KS_NAME] + 8;
                    807:        else
                    808:            oldicon = term_strings[KS_NAME];
                    809:    }
                    810:    return FALSE;
                    811: }
                    812:
                    813: #endif /* HAVE_X11 && WANT_X11 */
                    814:
                    815:    int
                    816: mch_can_restore_title()
                    817: {
                    818: #ifdef USE_GUI
                    819:    /*
                    820:     * If GUI is (going to be) used, we can always set the window title.
                    821:     * Saves a bit of time, because the X11 display server does not need to be
                    822:     * contacted.
                    823:     */
                    824:    if (gui.starting || gui.in_use)
                    825:        return TRUE;
                    826: #endif
                    827:    return get_x11_title(TRUE);
                    828: }
                    829:
                    830:    int
                    831: mch_can_restore_icon()
                    832: {
                    833: #ifdef USE_GUI
                    834:    /*
                    835:     * If GUI is (going to be) used, we can always set the icon name.
                    836:     * Saves a bit of time, because the X11 display server does not need to be
                    837:     * contacted.
                    838:     */
                    839:    if (gui.starting || gui.in_use)
                    840:        return TRUE;
                    841: #endif
                    842:    return get_x11_icon(TRUE);
                    843: }
                    844:
                    845: /*
                    846:  * Set the window title and icon.
                    847:  * Currently only works for x11.
                    848:  */
                    849:    void
                    850: mch_settitle(title, icon)
                    851:    char_u *title;
                    852:    char_u *icon;
                    853: {
                    854:    int         type = 0;
                    855:
                    856:    if (term_strings[KS_NAME] == NULL)      /* no terminal name (yet) */
                    857:        return;
                    858:    if (title == NULL && icon == NULL)      /* nothing to do */
                    859:        return;
                    860:
                    861: /*
                    862:  * if the window ID and the display is known, we may use X11 calls
                    863:  */
                    864: #if defined(HAVE_X11) && defined(WANT_X11)
                    865:    if (get_x11_windis() == OK)
                    866:        type = 1;
                    867: #endif
                    868:
                    869:    /*
                    870:     * Note: if terminal is xterm, title is set with escape sequence rather
                    871:     *       than x11 calls, because the x11 calls don't always work
                    872:     */
                    873:    if (is_xterm(term_strings[KS_NAME]))
                    874:        type = 2;
                    875:
                    876:    if (is_iris_ansi(term_strings[KS_NAME]))
                    877:        type = 3;
                    878:
                    879:    if (type)
                    880:    {
                    881:        if (title != NULL)
                    882:        {
                    883:            if (oldtitle == NULL)               /* first call, save title */
                    884:                (void)get_x11_title(FALSE);
                    885:
                    886:            switch(type)
                    887:            {
                    888: #if defined(HAVE_X11) && defined(WANT_X11)
                    889:            case 1: set_x11_title(title);               /* x11 */
                    890:                    break;
                    891: #endif
                    892:            case 2: outstrn((char_u *)"\033]2;");       /* xterm */
                    893:                    outstrn(title);
                    894:                    outchar(Ctrl('G'));
                    895:                    flushbuf();
                    896:                    break;
                    897:
                    898:            case 3: outstrn((char_u *)"\033P1.y");      /* iris-ansi */
                    899:                    outstrn(title);
                    900:                    outstrn((char_u *)"\234");
                    901:                    flushbuf();
                    902:                    break;
                    903:            }
                    904:        }
                    905:
                    906:        if (icon != NULL)
                    907:        {
                    908:            if (oldicon == NULL)                /* first call, save icon */
                    909:                get_x11_icon(FALSE);
                    910:
                    911:            switch(type)
                    912:            {
                    913: #if defined(HAVE_X11) && defined(WANT_X11)
                    914:            case 1: set_x11_icon(icon);                 /* x11 */
                    915:                    break;
                    916: #endif
                    917:            case 2: outstrn((char_u *)"\033]1;");       /* xterm */
                    918:                    outstrn(icon);
                    919:                    outchar(Ctrl('G'));
                    920:                    flushbuf();
                    921:                    break;
                    922:
                    923:            case 3: outstrn((char_u *)"\033P3.y");      /* iris-ansi */
                    924:                    outstrn(icon);
                    925:                    outstrn((char_u *)"\234");
                    926:                    flushbuf();
                    927:                    break;
                    928:            }
                    929:        }
                    930:    }
                    931: }
                    932:
                    933:    int
                    934: is_xterm(name)
                    935:    char_u *name;
                    936: {
                    937:    if (name == NULL)
                    938:        return FALSE;
                    939:    return (vim_strnicmp(name, (char_u *)"xterm", (size_t)5) == 0 ||
                    940:                        STRCMP(name, "builtin_xterm") == 0);
                    941: }
                    942:
                    943:    int
                    944: is_iris_ansi(name)
                    945:    char_u  *name;
                    946: {
                    947:    if (name == NULL)
                    948:        return FALSE;
                    949:    return (vim_strnicmp(name, (char_u *)"iris-ansi", (size_t)9) == 0 ||
                    950:                        STRCMP(name, "builtin_iris-ansi") == 0);
                    951: }
                    952:
                    953: /*
                    954:  * Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
                    955:  * This should include all windowed terminal emulators.
                    956:  */
                    957:    int
                    958: is_fastterm(name)
                    959:    char_u  *name;
                    960: {
                    961:    if (name == NULL)
                    962:        return FALSE;
                    963:    if (is_xterm(name) || is_iris_ansi(name))
                    964:        return TRUE;
                    965:    return (vim_strnicmp(name, (char_u *)"hpterm", (size_t)6) == 0 ||
                    966:            vim_strnicmp(name, (char_u *)"sun-cmd", (size_t)7) == 0 ||
                    967:            vim_strnicmp(name, (char_u *)"screen", (size_t)6) == 0 ||
                    968:            vim_strnicmp(name, (char_u *)"dtterm", (size_t)6) == 0);
                    969: }
                    970:
                    971: /*
                    972:  * Restore the window/icon title.
                    973:  * which is one of:
                    974:  * 1  Just restore title
                    975:  *  2  Just restore icon
                    976:  * 3  Restore title and icon
                    977:  */
                    978:    void
                    979: mch_restore_title(which)
                    980:    int which;
                    981: {
                    982:    mch_settitle((which & 1) ? oldtitle : NULL, (which & 2) ? oldicon : NULL);
                    983: }
                    984:
                    985: /*
                    986:  * Insert user name in s[len].
                    987:  * Return OK if a name found.
                    988:  */
                    989:    int
                    990: mch_get_user_name(s, len)
                    991:    char_u  *s;
                    992:    int     len;
                    993: {
                    994: #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
                    995:    struct passwd   *pw;
                    996: #endif
                    997:    uid_t           uid;
                    998:
                    999:    uid = getuid();
                   1000: #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
                   1001:    if ((pw = getpwuid(uid)) != NULL &&
                   1002:                                   pw->pw_name != NULL && *pw->pw_name != NUL)
                   1003:    {
                   1004:        STRNCPY(s, pw->pw_name, len);
                   1005:        return OK;
                   1006:    }
                   1007: #endif
                   1008:    sprintf((char *)s, "%d", (int)uid);     /* assumes s is long enough */
                   1009:    return FAIL;                            /* a number is not a name */
                   1010: }
                   1011:
                   1012: /*
                   1013:  * Insert host name is s[len].
                   1014:  */
                   1015:
                   1016: #ifdef HAVE_SYS_UTSNAME_H
                   1017:    void
                   1018: mch_get_host_name(s, len)
                   1019:    char_u  *s;
                   1020:    int     len;
                   1021: {
                   1022:     struct utsname vutsname;
                   1023:
                   1024:     uname(&vutsname);
                   1025:     STRNCPY(s, vutsname.nodename, len);
                   1026: }
                   1027: #else /* HAVE_SYS_UTSNAME_H */
                   1028:
                   1029: # ifdef HAVE_SYS_SYSTEMINFO_H
                   1030: #  define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len)
                   1031: # endif
                   1032:
                   1033:    void
                   1034: mch_get_host_name(s, len)
                   1035:    char_u  *s;
                   1036:    int     len;
                   1037: {
                   1038:    gethostname((char *)s, len);
                   1039: }
                   1040: #endif /* HAVE_SYS_UTSNAME_H */
                   1041:
                   1042: /*
                   1043:  * return process ID
                   1044:  */
                   1045:    long
                   1046: mch_get_pid()
                   1047: {
                   1048:    return (long)getpid();
                   1049: }
                   1050:
                   1051: #if !defined(HAVE_STRERROR) && defined(USE_GETCWD)
                   1052: static char *strerror __ARGS((int));
                   1053:
                   1054:    static char *
                   1055: strerror(err)
                   1056:    int err;
                   1057: {
                   1058:    extern int      sys_nerr;
                   1059:    extern char     *sys_errlist[];
                   1060:    static char     er[20];
                   1061:
                   1062:    if (err > 0 && err < sys_nerr)
                   1063:        return (sys_errlist[err]);
                   1064:    sprintf(er, "Error %d", err);
                   1065:    return er;
                   1066: }
                   1067: #endif
                   1068:
                   1069: /*
                   1070:  * Get name of current directory into buffer 'buf' of length 'len' bytes.
                   1071:  * Return OK for success, FAIL for failure.
                   1072:  */
                   1073:    int
                   1074: mch_dirname(buf, len)
                   1075:    char_u  *buf;
                   1076:    int     len;
                   1077: {
                   1078: #if defined(USE_GETCWD)
                   1079:    if (getcwd((char *)buf, len) == NULL)
                   1080:    {
                   1081:        STRCPY(buf, strerror(errno));
                   1082:        return FAIL;
                   1083:    }
                   1084:     return OK;
                   1085: #else
                   1086:    return (getwd((char *)buf) != NULL ? OK : FAIL);
                   1087: #endif
                   1088: }
                   1089:
                   1090: #ifdef __EMX__
                   1091: /*
                   1092:  * Replace all slashes by backslashes.
                   1093:  */
                   1094:    static void
                   1095: slash_adjust(p)
                   1096:    char_u  *p;
                   1097: {
                   1098:    while (*p)
                   1099:    {
                   1100:        if (*p == '/')
                   1101:            *p = '\\';
                   1102:        ++p;
                   1103:    }
                   1104: }
                   1105: #endif
                   1106:
                   1107: /*
                   1108:  * Get absolute filename into buffer 'buf' of length 'len' bytes.
                   1109:  *
                   1110:  * return FAIL for failure, OK for success
                   1111:  */
                   1112:    int
                   1113: FullName(fname, buf, len, force)
                   1114:    char_u *fname, *buf;
                   1115:    int len;
                   1116:    int force;          /* also expand when already absolute path name */
                   1117: {
                   1118:    int     l;
                   1119: #ifdef OS2
                   1120:    int     only_drive; /* only a drive letter is specified in file name */
                   1121: #endif
                   1122: #ifdef HAVE_FCHDIR
                   1123:    int     fd = -1;
                   1124:    static int  dont_fchdir = FALSE;    /* TRUE when fchdir() doesn't work */
                   1125: #endif
                   1126:    char_u  olddir[MAXPATHL];
                   1127:    char_u  *p;
                   1128:    char_u  c;
                   1129:    int     retval = OK;
                   1130:
                   1131:    if (fname == NULL)  /* always fail */
                   1132:    {
                   1133:        *buf = NUL;
                   1134:        return FAIL;
                   1135:    }
                   1136:
                   1137:    *buf = 0;
                   1138:    if (force || !isFullName(fname))    /* if forced or not an absolute path */
                   1139:    {
                   1140:        /*
                   1141:         * If the file name has a path, change to that directory for a moment,
                   1142:         * and then do the getwd() (and get back to where we were).
                   1143:         * This will get the correct path name with "../" things.
                   1144:         */
                   1145: #ifdef OS2
                   1146:        only_drive = 0;
                   1147:        if (((p = vim_strrchr(fname, '/')) != NULL) ||
                   1148:            ((p = vim_strrchr(fname, '\\')) != NULL) ||
                   1149:            (((p = vim_strchr(fname,  ':')) != NULL) && ++only_drive))
                   1150: #else
                   1151:        if ((p = vim_strrchr(fname, '/')) != NULL)
                   1152: #endif
                   1153:        {
                   1154: #ifdef HAVE_FCHDIR
                   1155:            /*
                   1156:             * Use fchdir() if possible, it's said to be faster and more
                   1157:             * reliable.  But on SunOS 4 it might not work.  Check this by
                   1158:             * doing a fchdir() right now.
                   1159:             */
                   1160:            if (!dont_fchdir)
                   1161:            {
                   1162:                fd = open(".", O_RDONLY | O_EXTRA);
                   1163:                if (fd >= 0 && fchdir(fd) < 0)
                   1164:                {
                   1165:                    close(fd);
                   1166:                    fd = -1;
                   1167:                    dont_fchdir = TRUE;     /* don't try again */
                   1168:                }
                   1169:            }
                   1170: #endif
                   1171:            if (
                   1172: #ifdef HAVE_FCHDIR
                   1173:                fd < 0 &&
                   1174: #endif
                   1175:                            mch_dirname(olddir, MAXPATHL) == FAIL)
                   1176:            {
                   1177:                p = NULL;       /* can't get current dir: don't chdir */
                   1178:                retval = FAIL;
                   1179:            }
                   1180:            else
                   1181:            {
                   1182: #ifdef OS2
                   1183:                /*
                   1184:                 * compensate for case where ':' from "D:" was the only
                   1185:                 * path separator detected in the file name; the _next_
                   1186:                 * character has to be removed, and then restored later.
                   1187:                 */
                   1188:                if (only_drive)
                   1189:                    p++;
                   1190: #endif
                   1191:                c = *p;
                   1192:                *p = NUL;
                   1193:                if (vim_chdir((char *)fname))
                   1194:                    retval = FAIL;
                   1195:                else
                   1196:                    fname = p + 1;
                   1197:                *p = c;
                   1198: #ifdef OS2
                   1199:                if (only_drive)
                   1200:                {
                   1201:                    p--;
                   1202:                    if (retval != FAIL)
                   1203:                        fname--;
                   1204:                }
                   1205: #endif
                   1206:            }
                   1207:        }
                   1208:        if (mch_dirname(buf, len) == FAIL)
                   1209:        {
                   1210:            retval = FAIL;
                   1211:            *buf = NUL;
                   1212:        }
                   1213:        l = STRLEN(buf);
                   1214:        if (l && buf[l - 1] != '/')
                   1215:            STRCAT(buf, "/");
                   1216:        if (p != NULL)
                   1217:        {
                   1218: #ifdef HAVE_FCHDIR
                   1219:            if (fd >= 0)
                   1220:            {
                   1221:                fchdir(fd);
                   1222:                close(fd);
                   1223:            }
                   1224:            else
                   1225: #endif
                   1226:                vim_chdir((char *)olddir);
                   1227:        }
                   1228:    }
                   1229:    STRCAT(buf, fname);
                   1230: #ifdef OS2
                   1231:    slash_adjust(buf);
                   1232: #endif
                   1233:    return retval;
                   1234: }
                   1235:
                   1236: /*
                   1237:  * return TRUE is fname is an absolute path name
                   1238:  */
                   1239:    int
                   1240: isFullName(fname)
                   1241:    char_u      *fname;
                   1242: {
                   1243: #ifdef __EMX__
                   1244:    return _fnisabs(fname);
                   1245: #else
                   1246:    return (*fname == '/' || *fname == '~');
                   1247: #endif
                   1248: }
                   1249:
                   1250: /*
                   1251:  * get file permissions for 'name'
                   1252:  */
                   1253:    long
                   1254: getperm(name)
                   1255:    char_u *name;
                   1256: {
                   1257:    struct stat statb;
                   1258:
                   1259:    if (stat((char *)name, &statb))
                   1260:        return -1;
                   1261:    return statb.st_mode;
                   1262: }
                   1263:
                   1264: /*
                   1265:  * set file permission for 'name' to 'perm'
                   1266:  *
                   1267:  * return FAIL for failure, OK otherwise
                   1268:  */
                   1269:    int
                   1270: setperm(name, perm)
                   1271:    char_u *name;
                   1272:    int perm;
                   1273: {
                   1274:    return (chmod((char *)name, (mode_t)perm) == 0 ? OK : FAIL);
                   1275: }
                   1276:
                   1277: /*
                   1278:  * return TRUE if "name" is a directory
                   1279:  * return FALSE if "name" is not a directory
                   1280:  * return FALSE for error
                   1281:  */
                   1282:    int
                   1283: mch_isdir(name)
                   1284:    char_u *name;
                   1285: {
                   1286:    struct stat statb;
                   1287:
                   1288:    if (stat((char *)name, &statb))
                   1289:        return FALSE;
                   1290: #ifdef _POSIX_SOURCE
                   1291:    return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
                   1292: #else
                   1293:    return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
                   1294: #endif
                   1295: }
                   1296:
                   1297:    void
                   1298: mch_windexit(r)
                   1299:    int r;
                   1300: {
                   1301:    settmode(0);
                   1302:    exiting = TRUE;
                   1303:    mch_settitle(oldtitle, oldicon);    /* restore xterm title */
                   1304:    stoptermcap();
1.2       downsj   1305:    outchar('\n');
1.1       downsj   1306:    flushbuf();
                   1307:    ml_close_all(TRUE);                 /* remove all memfiles */
                   1308:    may_core_dump();
                   1309:    exit(r);
                   1310: }
                   1311:
                   1312:    static void
                   1313: may_core_dump()
                   1314: {
1.3       downsj   1315:    if (deadly_signal != 0)
                   1316:    {
                   1317:        signal(deadly_signal, SIG_DFL);
                   1318:        kill(getpid(), deadly_signal);  /* Die using the signal we caught */
                   1319:    }
1.1       downsj   1320: }
                   1321:
                   1322: static int curr_tmode = 0; /* contains current raw/cooked mode (0 = cooked) */
                   1323:
                   1324:    void
                   1325: mch_settmode(raw)
                   1326:    int             raw;
                   1327: {
                   1328:    static int first = TRUE;
                   1329:
                   1330:    /* Why is NeXT excluded here (and not in unixunix.h)? */
                   1331: #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
                   1332:    /* for "new" tty systems */
                   1333: # ifdef HAVE_TERMIOS_H
                   1334:    static struct termios told;
                   1335:           struct termios tnew;
                   1336: # else
                   1337:    static struct termio told;
                   1338:           struct termio tnew;
                   1339: # endif
                   1340:
                   1341: # ifdef TIOCLGET
                   1342:    static unsigned long tty_local;
                   1343: # endif
                   1344:
                   1345:    if (raw)
                   1346:    {
                   1347:        if (first)
                   1348:        {
                   1349:            first = FALSE;
                   1350: # ifdef TIOCLGET
                   1351:            ioctl(0, TIOCLGET, &tty_local);
                   1352: # endif
                   1353: # if defined(HAVE_TERMIOS_H)
                   1354:            tcgetattr(0, &told);
                   1355: # else
                   1356:            ioctl(0, TCGETA, &told);
                   1357: # endif
                   1358:        }
                   1359:        tnew = told;
                   1360:        /*
                   1361:         * ICRNL enables typing ^V^M
                   1362:         */
                   1363:        tnew.c_iflag &= ~ICRNL;
                   1364:        tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
                   1365: # if defined(IEXTEN) && !defined(MINT)
                   1366:                    | IEXTEN        /* IEXTEN enables typing ^V on SOLARIS */
                   1367:                                    /* but it breaks function keys on MINT */
                   1368: # endif
                   1369:                                );
1.2       downsj   1370: # ifdef ONLCR      /* don't map NL -> CR NL, we do it ourselves */
                   1371:        tnew.c_oflag &= ~ONLCR;
                   1372: # endif
1.1       downsj   1373:        tnew.c_cc[VMIN] = 1;            /* return after 1 char */
                   1374:        tnew.c_cc[VTIME] = 0;           /* don't wait */
                   1375: # if defined(HAVE_TERMIOS_H)
                   1376:        tcsetattr(0, TCSANOW, &tnew);
                   1377: # else
                   1378:        ioctl(0, TCSETA, &tnew);
                   1379: # endif
                   1380:    }
                   1381:    else
                   1382:    {
                   1383: # if defined(HAVE_TERMIOS_H)
                   1384:        tcsetattr(0, TCSANOW, &told);
                   1385: # else
                   1386:        ioctl(0, TCSETA, &told);
                   1387: # endif
                   1388: # ifdef TIOCLGET
                   1389:        ioctl(0, TIOCLSET, &tty_local);
                   1390: # endif
                   1391:    }
                   1392: #else
                   1393: # ifndef TIOCSETN
                   1394: #  define TIOCSETN TIOCSETP        /* for hpux 9.0 */
                   1395: # endif
                   1396:    /* for "old" tty systems */
                   1397:    static struct sgttyb ttybold;
                   1398:           struct sgttyb ttybnew;
                   1399:
                   1400:    if (raw)
                   1401:    {
                   1402:        if (first)
                   1403:        {
                   1404:            first = FALSE;
                   1405:            ioctl(0, TIOCGETP, &ttybold);
                   1406:        }
                   1407:        ttybnew = ttybold;
                   1408:        ttybnew.sg_flags &= ~(CRMOD | ECHO);
                   1409:        ttybnew.sg_flags |= RAW;
                   1410:        ioctl(0, TIOCSETN, &ttybnew);
                   1411:    }
                   1412:    else
                   1413:        ioctl(0, TIOCSETN, &ttybold);
                   1414: #endif
                   1415:    curr_tmode = raw;
                   1416: }
                   1417:
                   1418: /*
                   1419:  * Try to get the code for "t_kb" from the stty setting
                   1420:  *
                   1421:  * Even if termcap claims a backspace key, the user's setting *should*
                   1422:  * prevail.  stty knows more about reality than termcap does, and if
                   1423:  * somebody's usual erase key is DEL (which, for most BSD users, it will
                   1424:  * be), they're going to get really annoyed if their erase key starts
                   1425:  * doing forward deletes for no reason. (Eric Fischer)
                   1426:  */
                   1427:    void
                   1428: get_stty()
                   1429: {
                   1430:    char_u  buf[2];
                   1431:    char_u  *p;
                   1432:
                   1433:    /* Why is NeXT excluded here (and not in unixunix.h)? */
                   1434: #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
                   1435:    /* for "new" tty systems */
                   1436: # ifdef HAVE_TERMIOS_H
                   1437:    struct termios keys;
                   1438: # else
                   1439:    struct termio keys;
                   1440: # endif
                   1441:
                   1442: # if defined(HAVE_TERMIOS_H)
                   1443:    if (tcgetattr(0, &keys) != -1)
                   1444: # else
                   1445:    if (ioctl(0, TCGETA, &keys) != -1)
                   1446: # endif
                   1447:    {
                   1448:        buf[0] = keys.c_cc[VERASE];
                   1449: #else
                   1450:    /* for "old" tty systems */
                   1451:    struct sgttyb keys;
                   1452:
                   1453:    if (ioctl(0, TIOCGETP, &keys) != -1)
                   1454:    {
                   1455:        buf[0] = keys.sg_erase;
                   1456: #endif
                   1457:        buf[1] = NUL;
                   1458:        add_termcode((char_u *)"kb", buf);
                   1459:
                   1460:        /*
                   1461:         * If <BS> and <DEL> are now the same, redefine <DEL>.
                   1462:         */
                   1463:        p = find_termcode((char_u *)"kD");
                   1464:        if (p != NULL && p[0] == buf[0] && p[1] == buf[1])
                   1465:            do_fixdel();
                   1466:    }
                   1467: #if 0
                   1468:    }       /* to keep cindent happy */
                   1469: #endif
                   1470: }
                   1471:
                   1472: #ifdef USE_MOUSE
                   1473: /*
                   1474:  * set mouse clicks on or off (only works for xterms)
                   1475:  */
                   1476:    void
                   1477: mch_setmouse(on)
                   1478:    int     on;
                   1479: {
                   1480:    static int  ison = FALSE;
                   1481:
                   1482:    if (on == ison)     /* return quickly if nothing to do */
                   1483:        return;
                   1484:
                   1485:    if (is_xterm(term_strings[KS_NAME]))
                   1486:    {
                   1487:        if (on)
                   1488:            outstrn((char_u *)"\033[?1000h"); /* xterm: enable mouse events */
                   1489:        else
                   1490:            outstrn((char_u *)"\033[?1000l"); /* xterm: disable mouse events */
                   1491:    }
                   1492:    ison = on;
                   1493: }
                   1494: #endif
                   1495:
                   1496: /*
                   1497:  * set screen mode, always fails.
                   1498:  */
                   1499:    int
                   1500: mch_screenmode(arg)
                   1501:    char_u   *arg;
                   1502: {
                   1503:    EMSG("Screen mode setting not supported");
                   1504:    return FAIL;
                   1505: }
                   1506:
                   1507: /*
                   1508:  * Try to get the current window size:
                   1509:  * 1. with an ioctl(), most accurate method
                   1510:  * 2. from the environment variables LINES and COLUMNS
                   1511:  * 3. from the termcap
                   1512:  * 4. keep using the old values
                   1513:  */
                   1514:    int
                   1515: mch_get_winsize()
                   1516: {
                   1517:    int         old_Rows = Rows;
                   1518:    int         old_Columns = Columns;
                   1519:    char_u      *p;
                   1520:
                   1521: #ifdef USE_GUI
                   1522:    if (gui.in_use)
                   1523:        return gui_mch_get_winsize();
                   1524: #endif
                   1525:
                   1526:    Columns = 0;
                   1527:    Rows = 0;
                   1528:
                   1529: /*
                   1530:  * For OS/2 use _scrsize().
                   1531:  */
                   1532: # ifdef __EMX__
                   1533:    {
                   1534:        int s[2];
                   1535:        _scrsize(s);
                   1536:        Columns = s[0];
                   1537:        Rows = s[1];
                   1538:    }
                   1539: # endif
                   1540:
                   1541: /*
                   1542:  * 1. try using an ioctl. It is the most accurate method.
                   1543:  *
                   1544:  * Try using TIOCGWINSZ first, some systems that have it also define TIOCGSIZE
                   1545:  * but don't have a struct ttysize.
                   1546:  */
                   1547: # ifdef TIOCGWINSZ
                   1548:    {
                   1549:        struct winsize  ws;
                   1550:
                   1551:        if (ioctl(0, TIOCGWINSZ, &ws) == 0)
                   1552:        {
                   1553:            Columns = ws.ws_col;
                   1554:            Rows = ws.ws_row;
                   1555:        }
                   1556:    }
                   1557: # else /* TIOCGWINSZ */
                   1558: #  ifdef TIOCGSIZE
                   1559:    {
                   1560:        struct ttysize  ts;
                   1561:
                   1562:        if (ioctl(0, TIOCGSIZE, &ts) == 0)
                   1563:        {
                   1564:            Columns = ts.ts_cols;
                   1565:            Rows = ts.ts_lines;
                   1566:        }
                   1567:    }
                   1568: #  endif /* TIOCGSIZE */
                   1569: # endif /* TIOCGWINSZ */
                   1570:
                   1571: /*
                   1572:  * 2. get size from environment
                   1573:  */
                   1574:    if (Columns == 0 || Rows == 0)
                   1575:    {
                   1576:        if ((p = (char_u *)getenv("LINES")))
                   1577:            Rows = atoi((char *)p);
                   1578:        if ((p = (char_u *)getenv("COLUMNS")))
                   1579:            Columns = atoi((char *)p);
                   1580:    }
                   1581:
                   1582: #ifdef HAVE_TGETENT
                   1583: /*
                   1584:  * 3. try reading the termcap
                   1585:  */
                   1586:    if (Columns == 0 || Rows == 0)
                   1587:        getlinecol();   /* get "co" and "li" entries from termcap */
                   1588: #endif
                   1589:
                   1590: /*
                   1591:  * 4. If everything fails, use the old values
                   1592:  */
                   1593:    if (Columns <= 0 || Rows <= 0)
                   1594:    {
                   1595:        Columns = old_Columns;
                   1596:        Rows = old_Rows;
                   1597:        return FAIL;
                   1598:    }
                   1599:
                   1600:    check_winsize();
                   1601:
                   1602: /* if size changed: screenalloc will allocate new screen buffers */
                   1603:    return OK;
                   1604: }
                   1605:
                   1606:    void
                   1607: mch_set_winsize()
                   1608: {
                   1609:    char_u  string[10];
                   1610:
                   1611: #ifdef USE_GUI
                   1612:    if (gui.in_use)
                   1613:    {
                   1614:        gui_mch_set_winsize();
                   1615:        return;
                   1616:    }
                   1617: #endif
                   1618:
                   1619:    /* try to set the window size to Rows and Columns */
                   1620:    if (is_iris_ansi(term_strings[KS_NAME]))
                   1621:    {
                   1622:        sprintf((char *)string, "\033[203;%ld;%ld/y", Rows, Columns);
                   1623:        outstrn(string);
                   1624:        flushbuf();
                   1625:        screen_start();                 /* don't know where cursor is now */
                   1626:    }
                   1627: }
                   1628:
                   1629:    int
                   1630: call_shell(cmd, options)
                   1631:    char_u  *cmd;
                   1632:    int     options;        /* SHELL_FILTER if called by do_filter() */
                   1633:                            /* SHELL_COOKED if term needs cooked mode */
                   1634:                            /* SHELL_EXPAND if called by ExpandWildCards() */
                   1635: {
                   1636: #ifdef USE_SYSTEM      /* use system() to start the shell: simple but slow */
                   1637:
                   1638:    int     x;
                   1639: #ifndef __EMX__
                   1640:    char_u  newcmd[1024];   /* only needed for unix */
                   1641: #else /* __EMX__ */
                   1642:    /*
                   1643:     * Set the preferred shell in the EMXSHELL environment variable (but
                   1644:     * only if it is different from what is already in the environment).
                   1645:     * Emx then takes care of whether to use "/c" or "-c" in an
                   1646:     * intelligent way. Simply pass the whole thing to emx's system() call.
                   1647:     * Emx also starts an interactive shell if system() is passed an empty
                   1648:     * string.
                   1649:     */
                   1650:    char_u *p, *old;
                   1651:
                   1652:    if (((old = getenv("EMXSHELL")) == NULL) || strcmp(old, p_sh))
                   1653:    {
                   1654:        /* should check HAVE_SETENV, but I know we don't have it. */
                   1655:        p = alloc(10 + strlen(p_sh));
                   1656:        if (p)
                   1657:        {
                   1658:            sprintf(p, "EMXSHELL=%s", p_sh);
                   1659:            putenv(p);  /* don't free the pointer! */
                   1660:        }
                   1661:    }
                   1662: #endif
                   1663:
                   1664:    flushbuf();
                   1665:
                   1666:    if (options & SHELL_COOKED)
                   1667:        settmode(0);                /* set to cooked mode */
                   1668:
                   1669: #ifdef __EMX__
                   1670:    if (cmd == NULL)
                   1671:        x = system(""); /* this starts an interactive shell in emx */
                   1672:    else
                   1673:        x = system(cmd);
                   1674:    if (x == -1) /* system() returns -1 when error occurs in starting shell */
                   1675:    {
                   1676:        MSG_OUTSTR("\nCannot execute shell ");
                   1677:        msg_outstr(p_sh);
                   1678:        msg_outchar('\n');
                   1679:    }
                   1680: #else /* not __EMX__ */
                   1681:    if (cmd == NULL)
                   1682:        x = system(p_sh);
                   1683:    else
                   1684:    {
1.2       downsj   1685:        sprintf(newcmd, "%s %s %s \"%s\"", p_sh,
1.1       downsj   1686:                    extra_shell_arg == NULL ? "" : (char *)extra_shell_arg,
1.2       downsj   1687:                    (char *)p_shcf,
1.1       downsj   1688:                    (char *)cmd);
                   1689:        x = system(newcmd);
                   1690:    }
                   1691:    if (x == 127)
                   1692:    {
                   1693:        MSG_OUTSTR("\nCannot execute shell sh\n");
                   1694:    }
                   1695: #endif /* __EMX__ */
                   1696:    else if (x && !expand_interactively)
                   1697:    {
                   1698:        msg_outchar('\n');
                   1699:        msg_outnum((long)x);
                   1700:        MSG_OUTSTR(" returned\n");
                   1701:    }
                   1702:
                   1703:    settmode(1);                        /* set to raw mode */
                   1704: #ifdef OS2
                   1705:    /* external command may change the window size in OS/2, so check it */
                   1706:    mch_get_winsize();
                   1707: #endif
                   1708:    resettitle();
                   1709:    return (x ? FAIL : OK);
                   1710:
                   1711: #else /* USE_SYSTEM */     /* don't use system(), use fork()/exec() */
                   1712:
                   1713: #define EXEC_FAILED 122        /* Exit code when shell didn't execute.  Don't use
                   1714:                               127, some shell use that already */
                   1715:
                   1716:    char_u  newcmd[1024];
                   1717:    int     pid;
                   1718: #ifdef HAVE_UNION_WAIT
                   1719:    union wait status;
                   1720: #else
                   1721:    int     status = -1;
                   1722: #endif
                   1723:    int     retval = FAIL;
                   1724:    char    **argv = NULL;
                   1725:    int     argc;
                   1726:    int     i;
                   1727:    char_u  *p;
                   1728:    int     inquote;
                   1729: #ifdef USE_GUI
                   1730:    int     pty_master_fd = -1;     /* for pty's */
                   1731:    int     pty_slave_fd = -1;
                   1732:    char    *tty_name;
                   1733:    int     fd_toshell[2];          /* for pipes */
                   1734:    int     fd_fromshell[2];
                   1735:    int     pipe_error = FALSE;
                   1736: # ifdef HAVE_SETENV
                   1737:    char    envbuf[50];
                   1738: # else
                   1739:    static char envbuf_Rows[20];
                   1740:    static char envbuf_Columns[20];
                   1741: # endif
                   1742: #endif
                   1743:    int     did_settmode = FALSE;   /* TRUE when settmode(1) called */
                   1744:
                   1745:    flushbuf();
                   1746:    if (options & SHELL_COOKED)
                   1747:        settmode(0);            /* set to cooked mode */
                   1748:
                   1749:    /*
                   1750:     * 1: find number of arguments
                   1751:     * 2: separate them and built argv[]
                   1752:     */
                   1753:    STRCPY(newcmd, p_sh);
                   1754:    for (i = 0; i < 2; ++i)
                   1755:    {
                   1756:        p = newcmd;
                   1757:        inquote = FALSE;
                   1758:        argc = 0;
                   1759:        for (;;)
                   1760:        {
                   1761:            if (i == 1)
                   1762:                argv[argc] = (char *)p;
                   1763:            ++argc;
                   1764:            while (*p && (inquote || (*p != ' ' && *p != TAB)))
                   1765:            {
                   1766:                if (*p == '"')
                   1767:                    inquote = !inquote;
                   1768:                ++p;
                   1769:            }
                   1770:            if (*p == NUL)
                   1771:                break;
                   1772:            if (i == 1)
                   1773:                *p++ = NUL;
                   1774:            p = skipwhite(p);
                   1775:        }
                   1776:        if (i == 0)
                   1777:        {
                   1778:            argv = (char **)alloc((unsigned)((argc + 4) * sizeof(char *)));
                   1779:            if (argv == NULL)       /* out of memory */
                   1780:                goto error;
                   1781:        }
                   1782:    }
                   1783:    if (cmd != NULL)
                   1784:    {
                   1785:        if (extra_shell_arg != NULL)
                   1786:            argv[argc++] = (char *)extra_shell_arg;
1.2       downsj   1787:        argv[argc++] = (char *)p_shcf;
1.1       downsj   1788:        argv[argc++] = (char *)cmd;
                   1789:    }
                   1790:    argv[argc] = NULL;
                   1791:
                   1792: #ifdef tower32
                   1793:    /*
                   1794:     * reap lost children (seems necessary on NCR Tower,
                   1795:     * although I don't have a clue why...) (Slootman)
                   1796:     */
                   1797:    while (wait(&status) != 0 && errno != ECHILD)
                   1798:        ;   /* do it again, if necessary */
                   1799: #endif
                   1800:
                   1801: #ifdef USE_GUI
                   1802: /*
                   1803:  * First try at using a pseudo-tty to get the stdin/stdout of the executed
                   1804:  * command into the current window for the GUI.
                   1805:  */
                   1806:
                   1807:    if (gui.in_use && show_shell_mess)
                   1808:    {
                   1809:        /*
                   1810:         * Try to open a master pty.
                   1811:         * If this works, open the slave pty.
                   1812:         * If the slave can't be opened, close the master pty.
                   1813:         */
                   1814:        if (p_guipty)
                   1815:        {
                   1816:            pty_master_fd = OpenPTY(&tty_name);     /* open pty */
                   1817:            if (pty_master_fd >= 0 && ((pty_slave_fd =
                   1818:                                       open(tty_name, O_RDWR | O_EXTRA)) < 0))
                   1819:            {
                   1820:                close(pty_master_fd);
                   1821:                pty_master_fd = -1;
                   1822:            }
                   1823:        }
                   1824:        /*
                   1825:         * If opening a pty didn't work, try using pipes.
                   1826:         */
                   1827:        if (pty_master_fd < 0)
                   1828:        {
                   1829:            pipe_error = (pipe(fd_toshell) < 0);
                   1830:            if (!pipe_error)                        /* pipe create OK */
                   1831:            {
                   1832:                pipe_error = (pipe(fd_fromshell) < 0);
                   1833:                if (pipe_error)                     /* pipe create failed */
                   1834:                {
                   1835:                    close(fd_toshell[0]);
                   1836:                    close(fd_toshell[1]);
                   1837:                }
                   1838:            }
                   1839:            if (pipe_error)
                   1840:            {
                   1841:                MSG_OUTSTR("\nCannot create pipes\n");
                   1842:                flushbuf();
                   1843:            }
                   1844:        }
                   1845:    }
                   1846:
                   1847:    if (!pipe_error)                    /* pty or pipe opened or not used */
                   1848: #endif
                   1849:
                   1850:    {
                   1851:        if ((pid = fork()) == -1)       /* maybe we should use vfork() */
                   1852:        {
                   1853:            MSG_OUTSTR("\nCannot fork\n");
                   1854: #ifdef USE_GUI
                   1855:            if (gui.in_use && show_shell_mess)
                   1856:            {
                   1857:                if (pty_master_fd >= 0)         /* close the pseudo tty */
                   1858:                {
                   1859:                    close(pty_master_fd);
                   1860:                    close(pty_slave_fd);
                   1861:                }
                   1862:                else                            /* close the pipes */
                   1863:                {
                   1864:                    close(fd_toshell[0]);
                   1865:                    close(fd_toshell[1]);
                   1866:                    close(fd_fromshell[0]);
                   1867:                    close(fd_fromshell[1]);
                   1868:                }
                   1869:            }
                   1870: #endif
                   1871:        }
                   1872:        else if (pid == 0)      /* child */
                   1873:        {
                   1874:            reset_signals();            /* handle signals normally */
                   1875:            if (!show_shell_mess)
                   1876:            {
                   1877:                int fd;
                   1878:
                   1879:                /*
                   1880:                 * Don't want to show any message from the shell.  Can't just
                   1881:                 * close stdout and stderr though, because some systems will
                   1882:                 * break if you try to write to them after that, so we must
                   1883:                 * use dup() to replace them with something else -- webb
                   1884:                 */
                   1885:                fd = open("/dev/null", O_WRONLY | O_EXTRA);
                   1886:                fclose(stdout);
                   1887:                fclose(stderr);
                   1888:
                   1889:                /*
                   1890:                 * If any of these open()'s and dup()'s fail, we just continue
                   1891:                 * anyway.  It's not fatal, and on most systems it will make
                   1892:                 * no difference at all.  On a few it will cause the execvp()
                   1893:                 * to exit with a non-zero status even when the completion
                   1894:                 * could be done, which is nothing too serious.  If the open()
                   1895:                 * or dup() failed we'd just do the same thing ourselves
                   1896:                 * anyway -- webb
                   1897:                 */
                   1898:                if (fd >= 0)
                   1899:                {
                   1900:                    /* To replace stdout (file descriptor 1) */
                   1901:                    dup(fd);
                   1902:
                   1903:                    /* To replace stderr (file descriptor 2) */
                   1904:                    dup(fd);
                   1905:
                   1906:                    /* Don't need this now that we've duplicated it */
                   1907:                    close(fd);
                   1908:                }
                   1909:            }
                   1910: #ifdef USE_GUI
                   1911:            else if (gui.in_use)
                   1912:            {
                   1913:
                   1914: #ifdef HAVE_SETSID
                   1915:                (void)setsid();
                   1916: #endif
                   1917: #ifdef TIOCSCTTY
                   1918:                /* try to become controlling tty (probably doesn't work,
                   1919:                 * unless run by root) */
                   1920:                ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
                   1921: #endif
                   1922:                /* Simulate to have a dumb terminal (for now) */
                   1923: #ifdef HAVE_SETENV
                   1924:                setenv("TERM", "dumb", 1);
                   1925:                sprintf((char *)envbuf, "%ld", Rows);
                   1926:                setenv("ROWS", (char *)envbuf, 1);
                   1927:                sprintf((char *)envbuf, "%ld", Columns);
                   1928:                setenv("COLUMNS", (char *)envbuf, 1);
                   1929: #else
                   1930:                /*
                   1931:                 * Putenv does not copy the string, it has to remain valid.
                   1932:                 * Use a static array to avoid loosing allocated memory.
                   1933:                 */
                   1934:                putenv("TERM=dumb");
                   1935:                sprintf(envbuf_Rows, "ROWS=%ld", Rows);
                   1936:                putenv(envbuf_Rows);
                   1937:                sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
                   1938:                putenv(envbuf_Columns);
                   1939: #endif
                   1940:
                   1941:                if (pty_master_fd >= 0)
                   1942:                {
                   1943:                    close(pty_master_fd);   /* close master side of pty */
                   1944:
                   1945:                    /* set up stdin/stdout/stderr for the child */
                   1946:                    close(0);
                   1947:                    dup(pty_slave_fd);
                   1948:                    close(1);
                   1949:                    dup(pty_slave_fd);
                   1950:                    close(2);
                   1951:                    dup(pty_slave_fd);
                   1952:
                   1953:                    close(pty_slave_fd);    /* has been dupped, close it now */
                   1954:                }
                   1955:                else
                   1956:                {
                   1957:                    /* set up stdin for the child */
                   1958:                    close(fd_toshell[1]);
                   1959:                    close(0);
                   1960:                    dup(fd_toshell[0]);
                   1961:                    close(fd_toshell[0]);
                   1962:
                   1963:                    /* set up stdout for the child */
                   1964:                    close(fd_fromshell[0]);
                   1965:                    close(1);
                   1966:                    dup(fd_fromshell[1]);
                   1967:                    close(fd_fromshell[1]);
                   1968:
                   1969:                    /* set up stderr for the child */
                   1970:                    close(2);
                   1971:                    dup(1);
                   1972:                }
                   1973:            }
                   1974: #endif
                   1975:            /*
                   1976:             * There is no type cast for the argv, because the type may be
                   1977:             * different on different machines. This may cause a warning
                   1978:             * message with strict compilers, don't worry about it.
                   1979:             */
                   1980:            execvp(argv[0], argv);
                   1981:            exit(EXEC_FAILED);      /* exec failed, return failure code */
                   1982:        }
                   1983:        else                    /* parent */
                   1984:        {
                   1985:            /*
                   1986:             * While child is running, ignore terminating signals.
                   1987:             */
                   1988:            catch_signals(SIG_IGN);
                   1989:
                   1990: #ifdef USE_GUI
                   1991:
                   1992:            /*
                   1993:             * For the GUI we redirect stdin, stdout and stderr to our window.
                   1994:             */
                   1995:            if (gui.in_use && show_shell_mess)
                   1996:            {
                   1997: #define BUFLEN 100             /* length for buffer, pseudo tty limit is 128 */
                   1998:                char_u      buffer[BUFLEN];
                   1999:                int         len;
                   2000:                int         p_more_save;
                   2001:                int         old_State;
                   2002:                int         read_count;
                   2003:                int         c;
                   2004:                int         toshell_fd;
                   2005:                int         fromshell_fd;
                   2006:
                   2007:                if (pty_master_fd >= 0)
                   2008:                {
                   2009:                    close(pty_slave_fd);        /* close slave side of pty */
                   2010:                    fromshell_fd = pty_master_fd;
                   2011:                    toshell_fd = dup(pty_master_fd);
                   2012:                }
                   2013:                else
                   2014:                {
                   2015:                    close(fd_toshell[0]);
                   2016:                    close(fd_fromshell[1]);
                   2017:                    toshell_fd = fd_toshell[1];
                   2018:                    fromshell_fd = fd_fromshell[0];
                   2019:                }
                   2020:
                   2021:                /*
                   2022:                 * Write to the child if there are typed characters.
                   2023:                 * Read from the child if there are characters available.
                   2024:                 *   Repeat the reading a few times if more characters are
                   2025:                 *   available. Need to check for typed keys now and then, but
                   2026:                 *   not too often (delays when no chars are available).
                   2027:                 * This loop is quit if no characters can be read from the pty
                   2028:                 * (WaitForChar detected special condition), or there are no
                   2029:                 * characters available and the child has exited.
                   2030:                 * Only check if the child has exited when there is no more
                   2031:                 * output. The child may exit before all the output has
                   2032:                 * been printed.
                   2033:                 *
                   2034:                 * Currently this busy loops!
                   2035:                 * This can probably dead-lock when the write blocks!
                   2036:                 */
                   2037:                p_more_save = p_more;
                   2038:                p_more = FALSE;
                   2039:                old_State = State;
                   2040:                State = EXTERNCMD;      /* don't redraw at window resize */
                   2041:
                   2042:                for (;;)
                   2043:                {
                   2044:                    /*
                   2045:                     * Check if keys have been typed, write them to the child
                   2046:                     * if there are any.  Don't do this if we are expanding
                   2047:                     * wild cards (would eat typeahead).
                   2048:                     */
                   2049:                    if (!(options & SHELL_EXPAND) &&
                   2050:                              (len = mch_inchar(buffer, BUFLEN - 1, 10)) != 0)
                   2051:                    {
                   2052:                        /*
                   2053:                         * For pipes:
                   2054:                         * Check for CTRL-C: sent interrupt signal to child.
                   2055:                         * Check for CTRL-D: EOF, close pipe to child.
                   2056:                         */
                   2057:                        if (len == 1 && (pty_master_fd < 0 || cmd != NULL))
                   2058:                        {
                   2059: #ifdef SIGINT
                   2060:                            if (buffer[0] == Ctrl('C'))
1.2       downsj   2061:                                /* send SIGINT to all processes in our group */
                   2062:                                kill(0, SIGINT);
1.1       downsj   2063: #endif
                   2064:                            if (pty_master_fd < 0 && toshell_fd >= 0 &&
                   2065:                                                       buffer[0] == Ctrl('D'))
                   2066:                            {
                   2067:                                close(toshell_fd);
                   2068:                                toshell_fd = -1;
                   2069:                            }
                   2070:                        }
                   2071:
                   2072:                        /* replace K_BS by <BS> and K_DEL by <DEL> */
                   2073:                        for (i = 0; i < len; ++i)
                   2074:                        {
                   2075:                            if (buffer[i] == CSI && len - i > 2)
                   2076:                            {
                   2077:                                c = TERMCAP2KEY(buffer[i + 1], buffer[i + 2]);
                   2078:                                if (c == K_DEL || c == K_BS)
                   2079:                                {
                   2080:                                    vim_memmove(buffer + i + 1, buffer + i + 3,
                   2081:                                                       (size_t)(len - i - 2));
                   2082:                                    if (c == K_DEL)
                   2083:                                        buffer[i] = DEL;
                   2084:                                    else
                   2085:                                        buffer[i] = Ctrl('H');
                   2086:                                    len -= 2;
                   2087:                                }
                   2088:                            }
                   2089:                            else if (buffer[i] == '\r')
                   2090:                                buffer[i] = '\n';
                   2091:                        }
                   2092:
                   2093:                        /*
                   2094:                         * For pipes: echo the typed characters.
                   2095:                         * For a pty this does not seem to work.
                   2096:                         */
                   2097:                        if (pty_master_fd < 0)
                   2098:                        {
                   2099:                            for (i = 0; i < len; ++i)
                   2100:                                if (buffer[i] == '\n' || buffer[i] == '\b')
                   2101:                                    msg_outchar(buffer[i]);
                   2102:                                else
                   2103:                                    msg_outtrans_len(buffer + i, 1);
                   2104:                            windgoto(msg_row, msg_col);
                   2105:                            flushbuf();
                   2106:                        }
                   2107:
                   2108:                        /*
                   2109:                         * Write the characters to the child, unless EOF has
                   2110:                         * been typed for pipes.  Ignore errors.
                   2111:                         */
                   2112:                        if (toshell_fd >= 0)
                   2113:                            write(toshell_fd, (char *)buffer, (size_t)len);
                   2114:                    }
                   2115:
                   2116:                    /*
                   2117:                     * Check if the child has any characters to be printed.
                   2118:                     * Read them and write them to our window.
                   2119:                     * Repeat this a few times as long as there is something
                   2120:                     * to do, avoid the 10ms wait for mch_inchar().
                   2121:                     * TODO: This should handle escape sequences.
                   2122:                     */
                   2123:                    for (read_count = 0; read_count < 10 &&
                   2124:                             RealWaitForChar(fromshell_fd, 10); ++read_count)
                   2125:                    {
                   2126:                        len = read(fromshell_fd, (char *)buffer,
1.4     ! downsj   2127:                                                        (size_t)(BUFLEN - 1));
        !          2128:                        if (len <= 0)               /* end of file or error */
1.1       downsj   2129:                            goto finished;
                   2130:                        buffer[len] = NUL;
                   2131:                        msg_outstr(buffer);
                   2132:                        windgoto(msg_row, msg_col);
                   2133:                        cursor_on();
                   2134:                        flushbuf();
                   2135:                    }
                   2136:
                   2137:                    /*
                   2138:                     * Check if the child still exists when we finished
                   2139:                     * outputting all characters.
                   2140:                     */
                   2141:                    if (read_count == 0 &&
                   2142: #ifdef __NeXT__
                   2143:                            wait4(pid, &status, WNOHANG, (struct rusage *) 0) &&
                   2144: #else
                   2145:                            waitpid(pid, &status, WNOHANG) &&
                   2146: #endif
                   2147:                                                            WIFEXITED(status))
                   2148:                        break;
                   2149:                }
                   2150: finished:
                   2151:                p_more = p_more_save;
                   2152:                State = old_State;
                   2153:                if (toshell_fd >= 0)
                   2154:                    close(toshell_fd);
                   2155:                close(fromshell_fd);
                   2156:            }
                   2157: #endif /* USE_GUI */
                   2158:
                   2159:            /*
                   2160:             * Wait until child has exited.
                   2161:             */
                   2162: #ifdef ECHILD
                   2163:            /* Don't stop waiting when a signal (e.g. SIGWINCH) is received. */
                   2164:            while (wait(&status) == -1 && errno != ECHILD)
                   2165:                ;
                   2166: #else
                   2167:            wait(&status);
                   2168: #endif
                   2169:            /*
                   2170:             * Set to raw mode right now, otherwise a CTRL-C after
                   2171:             * catch_signals will kill Vim.
                   2172:             */
                   2173:            settmode(1);
                   2174:            did_settmode = TRUE;
                   2175:            catch_signals(deathtrap);
                   2176:
                   2177:            /*
                   2178:             * Check the window size, in case it changed while executing the
                   2179:             * external command.
                   2180:             */
                   2181:            mch_get_winsize();
                   2182:
                   2183:            if (WIFEXITED(status))
                   2184:            {
                   2185:                i = WEXITSTATUS(status);
                   2186:                if (i)
                   2187:                {
                   2188:                    if (i == EXEC_FAILED)
                   2189:                    {
                   2190:                        MSG_OUTSTR("\nCannot execute shell ");
                   2191:                        msg_outtrans(p_sh);
                   2192:                        msg_outchar('\n');
                   2193:                    }
                   2194:                    else if (!expand_interactively)
                   2195:                    {
                   2196:                        msg_outchar('\n');
                   2197:                        msg_outnum((long)i);
                   2198:                        MSG_OUTSTR(" returned\n");
                   2199:                    }
                   2200:                }
                   2201:                else
                   2202:                    retval = OK;
                   2203:            }
                   2204:            else
                   2205:                MSG_OUTSTR("\nCommand terminated\n");
                   2206:        }
                   2207:    }
                   2208:    vim_free(argv);
                   2209:
                   2210: error:
                   2211:    if (!did_settmode)
                   2212:        settmode(1);                        /* always set to raw mode */
                   2213:    resettitle();
                   2214:
                   2215:    return retval;
                   2216:
                   2217: #endif /* USE_SYSTEM */
                   2218: }
                   2219:
                   2220: /*
                   2221:  * The input characters are buffered to be able to check for a CTRL-C.
                   2222:  * This should be done with signals, but I don't know how to do that in
                   2223:  * a portable way for a tty in RAW mode.
                   2224:  */
                   2225:
                   2226: /*
                   2227:  * Internal typeahead buffer.  Includes extra space for long key code
                   2228:  * descriptions which would otherwise overflow.  The buffer is considered full
                   2229:  * when only this extra space (or part of it) remains.
                   2230:  */
                   2231: #define INBUFLEN 250
                   2232:
                   2233: static char_u  inbuf[INBUFLEN + MAX_KEY_CODE_LEN];
                   2234: static int     inbufcount = 0;     /* number of chars in inbuf[] */
                   2235:
                   2236: /*
                   2237:  * is_input_buf_full(), is_input_buf_empty(), add_to_input_buf(), and
                   2238:  * trash_input_buf() are functions for manipulating the input buffer.  These
                   2239:  * are used by the gui_* calls when a GUI is used to handle keyboard input.
                   2240:  *
                   2241:  * NOTE: These functions will be identical in msdos.c etc, and should probably
                   2242:  * be taken out and put elsewhere, but at the moment inbuf is only local.
                   2243:  */
                   2244:
                   2245:    int
                   2246: is_input_buf_full()
                   2247: {
                   2248:    return (inbufcount >= INBUFLEN);
                   2249: }
                   2250:
                   2251:    int
                   2252: is_input_buf_empty()
                   2253: {
                   2254:    return (inbufcount == 0);
                   2255: }
                   2256:
                   2257: /* Add the given bytes to the input buffer */
                   2258:    void
                   2259: add_to_input_buf(s, len)
                   2260:    char_u  *s;
                   2261:    int     len;
                   2262: {
                   2263:    if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
                   2264:        return;     /* Shouldn't ever happen! */
                   2265:
                   2266:    while (len--)
                   2267:        inbuf[inbufcount++] = *s++;
                   2268: }
                   2269:
                   2270: /* Remove everything from the input buffer.  Called when ^C is found */
                   2271:    void
                   2272: trash_input_buf()
                   2273: {
                   2274:    inbufcount = 0;
                   2275: }
                   2276:
                   2277:    static int
                   2278: Read(buf, maxlen)
                   2279:    char_u  *buf;
                   2280:    long    maxlen;
                   2281: {
                   2282:    if (inbufcount == 0)        /* if the buffer is empty, fill it */
                   2283:        fill_inbuf(TRUE);
                   2284:    if (maxlen > inbufcount)
                   2285:        maxlen = inbufcount;
                   2286:    vim_memmove(buf, inbuf, (size_t)maxlen);
                   2287:    inbufcount -= maxlen;
                   2288:    if (inbufcount)
                   2289:        vim_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
                   2290:    return (int)maxlen;
                   2291: }
                   2292:
                   2293:    void
                   2294: mch_breakcheck()
                   2295: {
                   2296: #ifdef USE_GUI
                   2297:    if (gui.in_use)
                   2298:    {
                   2299:        gui_mch_update();
                   2300:        return;
                   2301:    }
                   2302: #endif /* USE_GUI */
                   2303:
                   2304: /*
                   2305:  * Check for CTRL-C typed by reading all available characters.
                   2306:  * In cooked mode we should get SIGINT, no need to check.
                   2307:  */
                   2308:    if (curr_tmode && RealWaitForChar(0, 0L))   /* if characters available */
                   2309:        fill_inbuf(FALSE);
                   2310: }
                   2311:
                   2312:    static void
                   2313: fill_inbuf(exit_on_error)
                   2314:    int exit_on_error;
                   2315: {
                   2316:    int     len;
                   2317:    int     try;
                   2318:
                   2319: #ifdef USE_GUI
                   2320:    if (gui.in_use)
                   2321:    {
                   2322:        gui_mch_update();
                   2323:        return;
                   2324:    }
                   2325: #endif
                   2326:    if (is_input_buf_full())
                   2327:        return;
                   2328:    /*
                   2329:     * Fill_inbuf() is only called when we really need a character.
                   2330:     * If we can't get any, but there is some in the buffer, just return.
                   2331:     * If we can't get any, and there isn't any in the buffer, we give up and
                   2332:     * exit Vim.
                   2333:     */
                   2334:    for (try = 0; try < 100; ++try)
                   2335:    {
                   2336:        len = read(0, (char *)inbuf + inbufcount,
                   2337:                                             (size_t)(INBUFLEN - inbufcount));
                   2338:        if (len > 0)
                   2339:            break;
                   2340:        if (!exit_on_error)
                   2341:            return;
                   2342:    }
                   2343:    if (len <= 0)
                   2344:    {
                   2345:        windgoto((int)Rows - 1, 0);
                   2346:        fprintf(stderr, "Vim: Error reading input, exiting...\n");
                   2347:        ml_sync_all(FALSE, TRUE);       /* preserve all swap files */
                   2348:        getout(1);
                   2349:    }
                   2350:    while (len-- > 0)
                   2351:    {
                   2352:        /*
                   2353:         * if a CTRL-C was typed, remove it from the buffer and set got_int
                   2354:         */
                   2355:        if (inbuf[inbufcount] == 3)
                   2356:        {
                   2357:            /* remove everything typed before the CTRL-C */
                   2358:            vim_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
                   2359:            inbufcount = 0;
                   2360:            got_int = TRUE;
                   2361:        }
                   2362:        ++inbufcount;
                   2363:    }
                   2364: }
                   2365:
                   2366: /*
                   2367:  * Wait "msec" msec until a character is available from the keyboard or from
                   2368:  * inbuf[]. msec == -1 will block forever.
                   2369:  * When a GUI is being used, this will never get called -- webb
                   2370:  */
                   2371:
                   2372:    static  int
                   2373: WaitForChar(msec)
                   2374:    long    msec;
                   2375: {
                   2376:    if (inbufcount)     /* something in inbuf[] */
                   2377:        return 1;
                   2378:    return RealWaitForChar(0, msec);
                   2379: }
                   2380:
                   2381: /*
                   2382:  * Wait "msec" msec until a character is available from file descriptor "fd".
                   2383:  * Time == -1 will block forever.
                   2384:  * When a GUI is being used, this will not be used for input -- webb
                   2385:  */
                   2386:    static  int
                   2387: RealWaitForChar(fd, msec)
                   2388:    int     fd;
                   2389:    long    msec;
                   2390: {
                   2391: #ifndef HAVE_SELECT
                   2392:    struct pollfd fds;
                   2393:
                   2394:    fds.fd = fd;
                   2395:    fds.events = POLLIN;
                   2396:    return (poll(&fds, 1, (int)msec) > 0);  /* is this correct when fd != 0?? */
                   2397: #else
                   2398:    struct timeval tv;
                   2399:    fd_set rfds, efds;
                   2400:
                   2401: # ifdef __EMX__
                   2402:    /* don't check for incoming chars if not in raw mode, because select()
                   2403:     * always returns TRUE then (in some version of emx.dll) */
                   2404:    if (curr_tmode == 0)
                   2405:        return 0;
                   2406: # endif
                   2407:
                   2408:    if (msec >= 0)
                   2409:     {
                   2410:            tv.tv_sec = msec / 1000;
                   2411:        tv.tv_usec = (msec % 1000) * (1000000/1000);
                   2412:     }
                   2413:
                   2414:    /*
                   2415:     * Select on ready for reading and exceptional condition (end of file).
                   2416:     */
                   2417:    FD_ZERO(&rfds); /* calls bzero() on a sun */
                   2418:    FD_ZERO(&efds);
                   2419:    FD_SET(fd, &rfds);
1.3       downsj   2420: #ifndef __QNX__
                   2421:    /* For QNX select() always returns 1 if this is set.  Why? */
1.1       downsj   2422:    FD_SET(fd, &efds);
1.3       downsj   2423: #endif
1.1       downsj   2424:    return (select(fd + 1, &rfds, NULL, &efds, (msec >= 0) ? &tv : NULL) > 0);
                   2425: #endif
                   2426: }
                   2427:
                   2428: /*
                   2429:  * ExpandWildCards() - this code does wild-card pattern matching using the shell
                   2430:  *
                   2431:  * return OK for success, FAIL for error (you may lose some memory) and put
                   2432:  * an error message in *file.
                   2433:  *
                   2434:  * num_pat is number of input patterns
                   2435:  * pat is array of pointers to input patterns
                   2436:  * num_file is pointer to number of matched file names
                   2437:  * file is pointer to array of pointers to matched file names
                   2438:  * On Unix we do not check for files only yet
                   2439:  * list_notfound is ignored
                   2440:  */
                   2441:
                   2442: #ifndef SEEK_SET
                   2443: # define SEEK_SET 0
                   2444: #endif
                   2445: #ifndef SEEK_END
                   2446: # define SEEK_END 2
                   2447: #endif
                   2448:
                   2449:    int
                   2450: ExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
                   2451:    int             num_pat;
                   2452:    char_u        **pat;
                   2453:    int            *num_file;
                   2454:    char_u       ***file;
                   2455:    int             files_only;
                   2456:    int             list_notfound;
                   2457: {
                   2458:    int     i;
                   2459:    size_t  len;
                   2460:    char_u  *p;
                   2461: #ifdef __EMX__
                   2462: # define EXPL_ALLOC_INC    16
                   2463:    char_u  **expl_files;
                   2464:    size_t  files_alloced, files_free;
1.2       downsj   2465:    char_u  *buf;
                   2466:    int     has_wildcard;
1.1       downsj   2467:
                   2468:    *num_file = 0;      /* default: no files found */
                   2469:    files_alloced = EXPL_ALLOC_INC; /* how much space is allocated */
                   2470:    files_free = EXPL_ALLOC_INC;    /* how much space is not used  */
                   2471:    *file = (char_u **) alloc(sizeof(char_u **) * files_alloced);
1.2       downsj   2472:    if (*file == NULL)
1.1       downsj   2473:        return FAIL;
                   2474:
                   2475:    for (; num_pat > 0; num_pat--, pat++)
                   2476:    {
                   2477:        expl_files = NULL;
                   2478:        if (vim_strchr(*pat, '$') || vim_strchr(*pat, '~'))
                   2479:        {
                   2480:            /* expand environment var or home dir */
1.2       downsj   2481:            buf = alloc(MAXPATHL);
                   2482:            if (buf == NULL)
1.1       downsj   2483:                return FAIL;
1.2       downsj   2484:            expand_env(*pat, buf, MAXPATHL);
1.1       downsj   2485:        }
                   2486:        else
                   2487:        {
1.2       downsj   2488:            buf = strsave(*pat);
                   2489:        }
                   2490:         expl_files = NULL;
                   2491:        has_wildcard = mch_has_wildcard(buf);  /* (still) wildcards in there? */
                   2492:        if (has_wildcard)   /* yes, so expand them */
                   2493:            expl_files = (char_u **)_fnexplode(buf);
                   2494:         /*
                   2495:          * return value of buf if no wildcards left,
                   2496:          * OR if no match AND list_notfound is true.
                   2497:          */
                   2498:        if (!has_wildcard || (expl_files == NULL && list_notfound))
                   2499:        {   /* simply save the current contents of *buf */
                   2500:            expl_files = (char_u **)alloc(sizeof(char_u **) * 2);
                   2501:            if (expl_files != NULL)
1.1       downsj   2502:            {
1.2       downsj   2503:                expl_files[0] = strsave(buf);
1.1       downsj   2504:                expl_files[1] = NULL;
                   2505:            }
                   2506:        }
1.2       downsj   2507:         vim_free(buf);
                   2508:
1.1       downsj   2509:        /*
                   2510:         * Count number of names resulting from expansion,
1.2       downsj   2511:         * At the same time add a backslash to the end of names that happen to
                   2512:         * be directories, and replace slashes with backslashes.
1.1       downsj   2513:         */
1.2       downsj   2514:        if (expl_files)
1.1       downsj   2515:        {
1.2       downsj   2516:            for (i = 0; (p = expl_files[i]) != NULL; i++, (*num_file)++)
1.1       downsj   2517:            {
1.2       downsj   2518:                if (--files_free == 0)
                   2519:                {
                   2520:                    /* need more room in table of pointers */
                   2521:                    files_alloced += EXPL_ALLOC_INC;
                   2522:                    *file = (char_u **) realloc(*file,
                   2523:                                                sizeof(char_u **) * files_alloced);
                   2524:                    if (*file == NULL)
                   2525:                    {
                   2526:                        emsg(e_outofmem);
                   2527:                        *num_file = 0;
                   2528:                        return FAIL;
                   2529:                    }
                   2530:                    files_free = EXPL_ALLOC_INC;
                   2531:                }
                   2532:                slash_adjust(p);
                   2533:                if (mch_isdir(p))
                   2534:                {
                   2535:                    len = strlen(p);
                   2536:                    if (((*file)[*num_file] = alloc(len + 2)) != NULL)
                   2537:                    {
                   2538:                        strcpy((*file)[*num_file], p);
                   2539:                        (*file)[*num_file][len] = '\\';
                   2540:                        (*file)[*num_file][len+1] = 0;
                   2541:                    }
                   2542:                }
                   2543:                else
1.1       downsj   2544:                {
1.2       downsj   2545:                    (*file)[*num_file] = strsave(p);
1.1       downsj   2546:                }
1.2       downsj   2547:
                   2548:                /*
                   2549:                 * Error message already given by either alloc or strsave.
                   2550:                 * Should return FAIL, but returning OK works also.
                   2551:                 */
                   2552:                if ((*file)[*num_file] == NULL)
                   2553:                    break;
1.1       downsj   2554:            }
1.2       downsj   2555:        _fnexplodefree((char **)expl_files);
1.1       downsj   2556:        }
                   2557:    }
                   2558:    return OK;
                   2559:
                   2560: #else /* __EMX__ */
                   2561:
                   2562:    int     dir;
1.2       downsj   2563:    char_u  *tempname;
1.1       downsj   2564:    char_u  *command;
                   2565:    FILE    *fd;
                   2566:    char_u  *buffer;
                   2567:    int     use_glob = FALSE;
                   2568:
                   2569:    *num_file = 0;      /* default: no files found */
                   2570:    *file = (char_u **)"";
                   2571:
                   2572:    /*
                   2573:     * If there are no wildcards, just copy the names to allocated memory.
                   2574:     * Saves a lot of time, because we don't have to start a new shell.
                   2575:     */
                   2576:    if (!have_wildcard(num_pat, pat))
                   2577:    {
                   2578:        *file = (char_u **)alloc(num_pat * sizeof(char_u *));
                   2579:        if (*file == NULL)
                   2580:        {
                   2581:            *file = (char_u **)"";
                   2582:            return FAIL;
                   2583:        }
                   2584:        for (i = 0; i < num_pat; i++)
                   2585:            (*file)[i] = strsave(pat[i]);
                   2586:        *num_file = num_pat;
                   2587:        return OK;
                   2588:    }
                   2589:
                   2590: /*
                   2591:  * get a name for the temp file
                   2592:  */
1.2       downsj   2593:    if ((tempname = vim_tempname('o')) == NULL)
1.1       downsj   2594:    {
                   2595:        emsg(e_notmp);
                   2596:        return FAIL;
                   2597:    }
                   2598:
                   2599: /*
                   2600:  * let the shell expand the patterns and write the result into the temp file
                   2601:  * If we use csh, glob will work better than echo.
                   2602:  */
                   2603:    if ((len = STRLEN(p_sh)) >= 3 && STRCMP(p_sh + len - 3, "csh") == 0)
                   2604:        use_glob = TRUE;
                   2605:
1.2       downsj   2606:    len = STRLEN(tempname) + 12;
1.1       downsj   2607:    for (i = 0; i < num_pat; ++i)       /* count the length of the patterns */
                   2608:        len += STRLEN(pat[i]) + 3;
                   2609:    command = alloc(len);
                   2610:    if (command == NULL)
1.2       downsj   2611:    {
                   2612:        vim_free(tempname);
1.1       downsj   2613:        return FAIL;
1.2       downsj   2614:    }
1.1       downsj   2615:    if (use_glob)
                   2616:        STRCPY(command, "glob >");      /* build the shell command */
                   2617:    else
                   2618:        STRCPY(command, "echo >");      /* build the shell command */
1.2       downsj   2619:    STRCAT(command, tempname);
1.1       downsj   2620:    for (i = 0; i < num_pat; ++i)
                   2621:    {
                   2622: #ifdef USE_SYSTEM
                   2623:        STRCAT(command, " \"");             /* need extra quotes because we */
                   2624:        STRCAT(command, pat[i]);            /*   start the shell twice */
                   2625:        STRCAT(command, "\"");
                   2626: #else
                   2627:        STRCAT(command, " ");
                   2628:        STRCAT(command, pat[i]);
                   2629: #endif
                   2630:    }
                   2631:    if (expand_interactively)
                   2632:        show_shell_mess = FALSE;
                   2633:    /*
                   2634:     * If we use -f then shell variables set in .cshrc won't get expanded.
                   2635:     * vi can do it, so we will too, but it is only necessary if there is a "$"
                   2636:     * in one of the patterns, otherwise we can still use the fast option.
                   2637:     */
                   2638:    if (use_glob && !have_dollars(num_pat, pat))    /* Use csh fast option */
                   2639:        extra_shell_arg = (char_u *)"-f";
                   2640:    i = call_shell(command, SHELL_EXPAND);      /* execute it */
                   2641:    extra_shell_arg = NULL;
                   2642:    show_shell_mess = TRUE;
                   2643:    vim_free(command);
                   2644:    if (i == FAIL)                          /* call_shell failed */
                   2645:    {
1.2       downsj   2646:        vim_remove(tempname);
                   2647:        vim_free(tempname);
1.1       downsj   2648:        /*
                   2649:         * With interactive completion, the error message is not printed.
                   2650:         * However with USE_SYSTEM, I don't know how to turn off error messages
                   2651:         * from the shell, so screen may still get messed up -- webb.
                   2652:         */
                   2653: #ifndef USE_SYSTEM
                   2654:        if (!expand_interactively)
                   2655: #endif
                   2656:        {
                   2657:            must_redraw = CLEAR;            /* probably messed up screen */
                   2658:            msg_outchar('\n');              /* clear bottom line quickly */
                   2659:            cmdline_row = Rows - 1;         /* continue on last line */
                   2660:        }
                   2661:        return FAIL;
                   2662:    }
                   2663:
                   2664: /*
                   2665:  * read the names from the file into memory
                   2666:  */
1.2       downsj   2667:    fd = fopen((char *)tempname, "r");
1.1       downsj   2668:    if (fd == NULL)
                   2669:    {
1.2       downsj   2670:        emsg2(e_notopen, tempname);
                   2671:        vim_free(tempname);
1.1       downsj   2672:        return FAIL;
                   2673:    }
                   2674:    fseek(fd, 0L, SEEK_END);
                   2675:    len = ftell(fd);                /* get size of temp file */
                   2676:    fseek(fd, 0L, SEEK_SET);
                   2677:    buffer = alloc(len + 1);
                   2678:    if (buffer == NULL)
                   2679:    {
1.2       downsj   2680:        vim_remove(tempname);
                   2681:        vim_free(tempname);
1.1       downsj   2682:        fclose(fd);
                   2683:        return FAIL;
                   2684:    }
                   2685:    i = fread((char *)buffer, 1, len, fd);
                   2686:    fclose(fd);
1.2       downsj   2687:    vim_remove(tempname);
1.1       downsj   2688:    if (i != len)
                   2689:    {
1.2       downsj   2690:        emsg2(e_notread, tempname);
                   2691:        vim_free(tempname);
1.1       downsj   2692:        vim_free(buffer);
                   2693:        return FAIL;
                   2694:    }
1.2       downsj   2695:    vim_free(tempname);
1.1       downsj   2696:
                   2697:    if (use_glob)       /* file names are separated with NUL */
                   2698:    {
                   2699:        buffer[len] = NUL;              /* make sure the buffers ends in NUL */
                   2700:        i = 0;
                   2701:        for (p = buffer; p < buffer + len; ++p)
                   2702:            if (*p == NUL)              /* count entry */
                   2703:                ++i;
                   2704:        if (len)
                   2705:            ++i;                        /* count last entry */
                   2706:    }
                   2707:    else                /* file names are separated with SPACE */
                   2708:    {
                   2709:        buffer[len] = '\n';             /* make sure the buffers ends in NL */
                   2710:        p = buffer;
                   2711:        for (i = 0; *p != '\n'; ++i)    /* count number of entries */
                   2712:        {
                   2713:            while (*p != ' ' && *p != '\n') /* skip entry */
                   2714:                ++p;
                   2715:            p = skipwhite(p);           /* skip to next entry */
                   2716:        }
                   2717:    }
                   2718:    if (i == 0)
                   2719:    {
                   2720:        /*
                   2721:         * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
                   2722:         * /bin/sh will happily expand it to nothing rather than returning an
                   2723:         * error; and hey, it's good to check anyway -- webb.
                   2724:         */
                   2725:        vim_free(buffer);
                   2726:        *file = (char_u **)"";
                   2727:        return FAIL;
                   2728:    }
                   2729:    *num_file = i;
                   2730:    *file = (char_u **)alloc(sizeof(char_u *) * i);
                   2731:    if (*file == NULL)
                   2732:    {
                   2733:        vim_free(buffer);
                   2734:        *file = (char_u **)"";
                   2735:        return FAIL;
                   2736:    }
                   2737:
                   2738:    /*
                   2739:     * Isolate the individual file names.
                   2740:     */
                   2741:    p = buffer;
                   2742:    for (i = 0; i < *num_file; ++i)
                   2743:    {
                   2744:        (*file)[i] = p;
                   2745:        if (use_glob)
                   2746:        {
                   2747:            while (*p && p < buffer + len)      /* skip entry */
                   2748:                ++p;
                   2749:            ++p;                                /* skip NUL */
                   2750:        }
                   2751:        else
                   2752:        {
                   2753:            while (*p != ' ' && *p != '\n')     /* skip entry */
                   2754:                ++p;
                   2755:            if (*p == '\n')                     /* last entry */
                   2756:                *p = NUL;
                   2757:            else
                   2758:            {
                   2759:                *p++ = NUL;
                   2760:                p = skipwhite(p);               /* skip to next entry */
                   2761:            }
                   2762:        }
                   2763:    }
                   2764:
                   2765:    /*
                   2766:     * Move the file names to allocated memory.
                   2767:     */
                   2768:    for (i = 0; i < *num_file; ++i)
                   2769:    {
                   2770:        /* Require the files to exist.  Helps when using /bin/sh */
                   2771:        if (expand_interactively)
                   2772:        {
                   2773:            struct stat     st;
                   2774:            int             j;
                   2775:
                   2776:            if (stat((char *)((*file)[i]), &st) < 0)
                   2777:            {
                   2778:                for (j = i; j + 1 < *num_file; ++j)
                   2779:                    (*file)[j] = (*file)[j + 1];
                   2780:                --*num_file;
                   2781:                --i;
                   2782:                continue;
                   2783:            }
                   2784:        }
                   2785:
                   2786:        /* if file doesn't exist don't add '/' */
                   2787:        dir = (mch_isdir((*file)[i]));
                   2788:        p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
                   2789:        if (p)
                   2790:        {
                   2791:            STRCPY(p, (*file)[i]);
                   2792:            if (dir)
                   2793:                STRCAT(p, "/");
                   2794:        }
                   2795:        (*file)[i] = p;
                   2796:    }
                   2797:    vim_free(buffer);
                   2798:
                   2799:    if (*num_file == 0)     /* rejected all entries */
                   2800:    {
                   2801:        vim_free(*file);
                   2802:        *file = (char_u **)"";
                   2803:        return FAIL;
                   2804:    }
                   2805:
                   2806:    return OK;
                   2807:
                   2808: #endif /* __EMX__ */
                   2809: }
                   2810:
                   2811:    int
                   2812: mch_has_wildcard(p)
                   2813:    char_u  *p;
                   2814: {
                   2815:    for ( ; *p; ++p)
                   2816:    {
                   2817:        if (*p == '\\' && p[1] != NUL)
                   2818:            ++p;
                   2819:        else if (vim_strchr((char_u *)"*?[{`~$", *p) != NULL)
                   2820:            return TRUE;
                   2821:    }
                   2822:    return FALSE;
                   2823: }
                   2824:
                   2825: #ifndef __EMX__
                   2826:    static int
                   2827: have_wildcard(num, file)
                   2828:    int     num;
                   2829:    char_u  **file;
                   2830: {
                   2831:    register int i;
                   2832:
                   2833:    for (i = 0; i < num; i++)
                   2834:        if (mch_has_wildcard(file[i]))
                   2835:            return 1;
                   2836:    return 0;
                   2837: }
                   2838:
                   2839:    static int
                   2840: have_dollars(num, file)
                   2841:    int     num;
                   2842:    char_u  **file;
                   2843: {
                   2844:    register int i;
                   2845:
                   2846:    for (i = 0; i < num; i++)
                   2847:        if (vim_strchr(file[i], '$') != NULL)
                   2848:            return TRUE;
                   2849:    return FALSE;
                   2850: }
                   2851: #endif /* ifndef __EMX__ */
                   2852:
                   2853: #ifndef HAVE_RENAME
                   2854: /*
                   2855:  * Scaled-down version of rename, which is missing in Xenix.
                   2856:  * This version can only move regular files and will fail if the
                   2857:  * destination exists.
                   2858:  */
                   2859:    int
                   2860: rename(src, dest)
                   2861:    const char *src, *dest;
                   2862: {
                   2863:    struct stat     st;
                   2864:
                   2865:    if (stat(dest, &st) >= 0)       /* fail if destination exists */
                   2866:        return -1;
                   2867:    if (link(src, dest) != 0)       /* link file to new name */
                   2868:        return -1;
                   2869:    if (vim_remove(src) == 0)       /* delete link to old name */
                   2870:        return 0;
                   2871:    return -1;
                   2872: }
                   2873: #endif /* !HAVE_RENAME */