[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.3

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