xref: /vim-8.2.3635/src/os_unix.c (revision 843ee41e)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *	      OS/2 port by Paul Slootman
5  *	      VMS merge by Zoltan Arpadffy
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  * See README.txt for an overview of the Vim source code.
10  */
11 
12 /*
13  * os_unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
14  *	     Also for OS/2, using the excellent EMX package!!!
15  *	     Also for BeOS and Atari MiNT.
16  *
17  * A lot of this file was originally written by Juergen Weigert and later
18  * changed beyond recognition.
19  */
20 
21 /*
22  * Some systems have a prototype for select() that has (int *) instead of
23  * (fd_set *), which is wrong. This define removes that prototype. We define
24  * our own prototype below.
25  * Don't use it for the Mac, it causes a warning for precompiled headers.
26  * TODO: use a configure check for precompiled headers?
27  */
28 #ifndef __APPLE__
29 # define select select_declared_wrong
30 #endif
31 
32 #include "vim.h"
33 
34 #ifdef HAVE_FCNTL_H
35 # include <fcntl.h>
36 #endif
37 
38 #include "os_unixx.h"	    /* unix includes for os_unix.c only */
39 
40 #ifdef USE_XSMP
41 # include <X11/SM/SMlib.h>
42 #endif
43 
44 /*
45  * Use this prototype for select, some include files have a wrong prototype
46  */
47 #undef select
48 #ifdef __BEOS__
49 # define select	beos_select
50 #endif
51 
52 #if defined(HAVE_SELECT)
53 extern int   select __ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
54 #endif
55 
56 #ifdef FEAT_MOUSE_GPM
57 # include <gpm.h>
58 /* <linux/keyboard.h> contains defines conflicting with "keymap.h",
59  * I just copied relevant defines here. A cleaner solution would be to put gpm
60  * code into separate file and include there linux/keyboard.h
61  */
62 /* #include <linux/keyboard.h> */
63 # define KG_SHIFT	0
64 # define KG_CTRL	2
65 # define KG_ALT		3
66 # define KG_ALTGR	1
67 # define KG_SHIFTL	4
68 # define KG_SHIFTR	5
69 # define KG_CTRLL	6
70 # define KG_CTRLR	7
71 # define KG_CAPSSHIFT	8
72 
73 static void gpm_close __ARGS((void));
74 static int gpm_open __ARGS((void));
75 static int mch_gpm_process __ARGS((void));
76 #endif
77 
78 /*
79  * end of autoconf section. To be extended...
80  */
81 
82 /* Are the following #ifdefs still required? And why? Is that for X11? */
83 
84 #if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
85 # ifdef SIGWINCH
86 #  undef SIGWINCH
87 # endif
88 # ifdef TIOCGWINSZ
89 #  undef TIOCGWINSZ
90 # endif
91 #endif
92 
93 #if defined(SIGWINDOW) && !defined(SIGWINCH)	/* hpux 9.01 has it */
94 # define SIGWINCH SIGWINDOW
95 #endif
96 
97 #ifdef FEAT_X11
98 # include <X11/Xlib.h>
99 # include <X11/Xutil.h>
100 # include <X11/Xatom.h>
101 # ifdef FEAT_XCLIPBOARD
102 #  include <X11/Intrinsic.h>
103 #  include <X11/Shell.h>
104 #  include <X11/StringDefs.h>
105 static Widget	xterm_Shell = (Widget)0;
106 static void xterm_update __ARGS((void));
107 # endif
108 
109 # if defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE)
110 Window	    x11_window = 0;
111 # endif
112 Display	    *x11_display = NULL;
113 
114 # ifdef FEAT_TITLE
115 static int  get_x11_windis __ARGS((void));
116 static void set_x11_title __ARGS((char_u *));
117 static void set_x11_icon __ARGS((char_u *));
118 # endif
119 #endif
120 
121 #ifdef FEAT_TITLE
122 static int get_x11_title __ARGS((int));
123 static int get_x11_icon __ARGS((int));
124 
125 static char_u	*oldtitle = NULL;
126 static int	did_set_title = FALSE;
127 static char_u	*oldicon = NULL;
128 static int	did_set_icon = FALSE;
129 #endif
130 
131 static void may_core_dump __ARGS((void));
132 
133 static int  WaitForChar __ARGS((long));
134 #if defined(__BEOS__)
135 int  RealWaitForChar __ARGS((int, long, int *));
136 #else
137 static int  RealWaitForChar __ARGS((int, long, int *));
138 #endif
139 
140 #ifdef FEAT_XCLIPBOARD
141 static int do_xterm_trace __ARGS((void));
142 #define XT_TRACE_DELAY	50	/* delay for xterm tracing */
143 #endif
144 
145 static void handle_resize __ARGS((void));
146 
147 #if defined(SIGWINCH)
148 static RETSIGTYPE sig_winch __ARGS(SIGPROTOARG);
149 #endif
150 #if defined(SIGINT)
151 static RETSIGTYPE catch_sigint __ARGS(SIGPROTOARG);
152 #endif
153 #if defined(SIGPWR)
154 static RETSIGTYPE catch_sigpwr __ARGS(SIGPROTOARG);
155 #endif
156 #if defined(SIGALRM) && defined(FEAT_X11) \
157 	&& defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK)
158 # define SET_SIG_ALARM
159 static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
160 static int sig_alarm_called;
161 #endif
162 static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
163 
164 static void set_signals __ARGS((void));
165 static void catch_signals __ARGS((RETSIGTYPE (*func_deadly)(), RETSIGTYPE (*func_other)()));
166 #ifndef __EMX__
167 static int  have_wildcard __ARGS((int, char_u **));
168 static int  have_dollars __ARGS((int, char_u **));
169 #endif
170 
171 #ifndef NO_EXPANDPATH
172 static int	pstrcmp __ARGS((const void *, const void *));
173 static int	unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags));
174 #endif
175 
176 #ifndef __EMX__
177 static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file));
178 #endif
179 
180 #ifndef SIG_ERR
181 # define SIG_ERR	((RETSIGTYPE (*)())-1)
182 #endif
183 
184 static int	do_resize = FALSE;
185 #ifndef __EMX__
186 static char_u	*extra_shell_arg = NULL;
187 static int	show_shell_mess = TRUE;
188 #endif
189 static int	deadly_signal = 0;	    /* The signal we caught */
190 
191 static int curr_tmode = TMODE_COOK;	/* contains current terminal mode */
192 
193 #ifdef USE_XSMP
194 typedef struct
195 {
196     SmcConn smcconn;	    /* The SM connection ID */
197     IceConn iceconn;	    /* The ICE connection ID */
198     Bool save_yourself;     /* If we're in the middle of a save_yourself */
199     Bool shutdown;	    /* If we're in shutdown mode */
200 } xsmp_config_T;
201 
202 static xsmp_config_T xsmp;
203 #endif
204 
205 #ifdef SYS_SIGLIST_DECLARED
206 /*
207  * I have seen
208  *  extern char *_sys_siglist[NSIG];
209  * on Irix, Linux, NetBSD and Solaris. It contains a nice list of strings
210  * that describe the signals. That is nearly what we want here.  But
211  * autoconf does only check for sys_siglist (without the underscore), I
212  * do not want to change everything today.... jw.
213  * This is why AC_DECL_SYS_SIGLIST is commented out in configure.in
214  */
215 #endif
216 
217 static struct signalinfo
218 {
219     int	    sig;	/* Signal number, eg. SIGSEGV etc */
220     char    *name;	/* Signal name (not char_u!). */
221     char    deadly;	/* Catch as a deadly signal? */
222 } signal_info[] =
223 {
224 #ifdef SIGHUP
225     {SIGHUP,	    "HUP",	TRUE},
226 #endif
227 #ifdef SIGQUIT
228     {SIGQUIT,	    "QUIT",	TRUE},
229 #endif
230 #ifdef SIGILL
231     {SIGILL,	    "ILL",	TRUE},
232 #endif
233 #ifdef SIGTRAP
234     {SIGTRAP,	    "TRAP",	TRUE},
235 #endif
236 #ifdef SIGABRT
237     {SIGABRT,	    "ABRT",	TRUE},
238 #endif
239 #ifdef SIGEMT
240     {SIGEMT,	    "EMT",	TRUE},
241 #endif
242 #ifdef SIGFPE
243     {SIGFPE,	    "FPE",	TRUE},
244 #endif
245 #ifdef SIGBUS
246     {SIGBUS,	    "BUS",	TRUE},
247 #endif
248 #ifdef SIGSEGV
249     {SIGSEGV,	    "SEGV",	TRUE},
250 #endif
251 #ifdef SIGSYS
252     {SIGSYS,	    "SYS",	TRUE},
253 #endif
254 #ifdef SIGALRM
255     {SIGALRM,	    "ALRM",	FALSE},	/* Perl's alarm() can trigger it */
256 #endif
257 #ifdef SIGTERM
258     {SIGTERM,	    "TERM",	TRUE},
259 #endif
260 #ifdef SIGVTALRM
261     {SIGVTALRM,	    "VTALRM",	TRUE},
262 #endif
263 #ifdef SIGPROF
264     {SIGPROF,	    "PROF",	TRUE},
265 #endif
266 #ifdef SIGXCPU
267     {SIGXCPU,	    "XCPU",	TRUE},
268 #endif
269 #ifdef SIGXFSZ
270     {SIGXFSZ,	    "XFSZ",	TRUE},
271 #endif
272 #ifdef SIGUSR1
273     {SIGUSR1,	    "USR1",	TRUE},
274 #endif
275 #ifdef SIGUSR2
276     {SIGUSR2,	    "USR2",	TRUE},
277 #endif
278 #ifdef SIGINT
279     {SIGINT,	    "INT",	FALSE},
280 #endif
281 #ifdef SIGWINCH
282     {SIGWINCH,	    "WINCH",	FALSE},
283 #endif
284 #ifdef SIGTSTP
285     {SIGTSTP,	    "TSTP",	FALSE},
286 #endif
287 #ifdef SIGPIPE
288     {SIGPIPE,	    "PIPE",	FALSE},
289 #endif
290     {-1,	    "Unknown!", FALSE}
291 };
292 
293     void
294 mch_write(s, len)
295     char_u	*s;
296     int		len;
297 {
298     write(1, (char *)s, len);
299     if (p_wd)		/* Unix is too fast, slow down a bit more */
300 	RealWaitForChar(read_cmd_fd, p_wd, NULL);
301 }
302 
303 /*
304  * mch_inchar(): low level input funcion.
305  * Get a characters from the keyboard.
306  * Return the number of characters that are available.
307  * If wtime == 0 do not wait for characters.
308  * If wtime == n wait a short time for characters.
309  * If wtime == -1 wait forever for characters.
310  */
311     int
312 mch_inchar(buf, maxlen, wtime, tb_change_cnt)
313     char_u	*buf;
314     int		maxlen;
315     long	wtime;	    /* don't use "time", MIPS cannot handle it */
316     int		tb_change_cnt;
317 {
318     int		len;
319 #ifdef FEAT_AUTOCMD
320     static int	once_already = 0;
321 #endif
322 
323     /* Check if window changed size while we were busy, perhaps the ":set
324      * columns=99" command was used. */
325     while (do_resize)
326 	handle_resize();
327 
328     if (wtime >= 0)
329     {
330 	while (WaitForChar(wtime) == 0)		/* no character available */
331 	{
332 	    if (!do_resize)	/* return if not interrupted by resize */
333 	    {
334 #ifdef FEAT_AUTOCMD
335 		once_already = 0;
336 #endif
337 		return 0;
338 	    }
339 	    handle_resize();
340 	}
341     }
342     else	/* wtime == -1 */
343     {
344 #ifdef FEAT_AUTOCMD
345 	if (once_already == 2)
346 	    updatescript(0);
347 	else if (once_already == 1)
348 	{
349 	    setcursor();
350 	    once_already = 2;
351 	    return 0;
352 	}
353 	else
354 #endif
355 	/*
356 	 * If there is no character available within 'updatetime' seconds
357 	 * flush all the swap files to disk
358 	 * Also done when interrupted by SIGWINCH.
359 	 */
360 	if (WaitForChar(p_ut) == 0)
361 	{
362 #ifdef FEAT_AUTOCMD
363 	    if (has_cursorhold() && get_real_state() == NORMAL_BUSY)
364 	    {
365 		apply_autocmds(EVENT_CURSORHOLD, NULL, NULL, FALSE, curbuf);
366 		update_screen(VALID);
367 		once_already = 1;
368 		return 0;
369 	    }
370 	    else
371 #endif
372 		updatescript(0);
373 	}
374     }
375 
376     for (;;)	/* repeat until we got a character */
377     {
378 	while (do_resize)    /* window changed size */
379 	    handle_resize();
380 	/*
381 	 * we want to be interrupted by the winch signal
382 	 */
383 	WaitForChar(-1L);
384 	if (do_resize)	    /* interrupted by SIGWINCH signal */
385 	    continue;
386 
387 	/* If input was put directly in typeahead buffer bail out here. */
388 	if (typebuf_changed(tb_change_cnt))
389 	    return 0;
390 
391 	/*
392 	 * For some terminals we only get one character at a time.
393 	 * We want the get all available characters, so we could keep on
394 	 * trying until none is available
395 	 * For some other terminals this is quite slow, that's why we don't do
396 	 * it.
397 	 */
398 	len = read_from_input_buf(buf, (long)maxlen);
399 	if (len > 0)
400 	{
401 #ifdef OS2
402 	    int i;
403 
404 	    for (i = 0; i < len; i++)
405 		if (buf[i] == 0)
406 		    buf[i] = K_NUL;
407 #endif
408 #ifdef FEAT_AUTOCMD
409 	    once_already = 0;
410 #endif
411 	    return len;
412 	}
413     }
414 }
415 
416     static void
417 handle_resize()
418 {
419     do_resize = FALSE;
420     shell_resized();
421 }
422 
423 /*
424  * return non-zero if a character is available
425  */
426     int
427 mch_char_avail()
428 {
429     return WaitForChar(0L);
430 }
431 
432 #if defined(HAVE_TOTAL_MEM) || defined(PROTO)
433 # ifdef HAVE_SYS_RESOURCE_H
434 #  include <sys/resource.h>
435 # endif
436 # if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTL)
437 #  include <sys/sysctl.h>
438 # endif
439 # if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
440 #  include <sys/sysinfo.h>
441 # endif
442 
443 /*
444  * Return total amount of memory available.  Doesn't change when memory has
445  * been allocated.
446  */
447 /* ARGSUSED */
448     long_u
449 mch_total_mem(special)
450     int special;
451 {
452 # ifdef __EMX__
453     return ulimit(3, 0L);   /* always 32MB? */
454 # else
455     long_u	mem = 0;
456 
457 #  ifdef HAVE_SYSCTL
458     int		mib[2], physmem;
459     size_t	len;
460 
461     /* BSD way of getting the amount of RAM available. */
462     mib[0] = CTL_HW;
463     mib[1] = HW_USERMEM;
464     len = sizeof(physmem);
465     if (sysctl(mib, 2, &physmem, &len, NULL, 0) == 0)
466 	mem = (long_u)physmem;
467 #  endif
468 
469 #  if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
470     if (mem == 0)
471     {
472 	struct sysinfo sinfo;
473 
474 	/* Linux way of getting amount of RAM available */
475 	if (sysinfo(&sinfo) == 0)
476 	    mem = sinfo.totalram;
477     }
478 #  endif
479 
480 #  ifdef HAVE_SYSCONF
481     if (mem == 0)
482     {
483 	long	    pagesize, pagecount;
484 
485 	/* Solaris way of getting amount of RAM available */
486 	pagesize = sysconf(_SC_PAGESIZE);
487 	pagecount = sysconf(_SC_PHYS_PAGES);
488 	if (pagesize > 0 && pagecount > 0)
489 	    mem = (long_u)pagesize * pagecount;
490     }
491 #  endif
492 
493     /* Return the minimum of the physical memory and the user limit, because
494      * using more than the user limit may cause Vim to be terminated. */
495 #  if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)
496     {
497 	struct rlimit	rlp;
498 
499 	if (getrlimit(RLIMIT_DATA, &rlp) == 0
500 		&& rlp.rlim_cur < ((rlim_t)1 << (sizeof(long_u) * 8 - 1))
501 #   ifdef RLIM_INFINITY
502 		&& rlp.rlim_cur != RLIM_INFINITY
503 #   endif
504 		&& (long_u)rlp.rlim_cur < mem
505 	   )
506 	    return (long_u)rlp.rlim_cur;
507     }
508 #  endif
509 
510     if (mem > 0)
511 	return mem;
512     return (long_u)0x7fffffff;
513 # endif
514 }
515 #endif
516 
517     void
518 mch_delay(msec, ignoreinput)
519     long	msec;
520     int		ignoreinput;
521 {
522     int		old_tmode;
523 
524     if (ignoreinput)
525     {
526 	/* Go to cooked mode without echo, to allow SIGINT interrupting us
527 	 * here */
528 	old_tmode = curr_tmode;
529 	if (curr_tmode == TMODE_RAW)
530 	    settmode(TMODE_SLEEP);
531 
532 	/*
533 	 * Everybody sleeps in a different way...
534 	 * Prefer nanosleep(), some versions of usleep() can only sleep up to
535 	 * one second.
536 	 */
537 #ifdef HAVE_NANOSLEEP
538 	{
539 	    struct timespec ts;
540 
541 	    ts.tv_sec = msec / 1000;
542 	    ts.tv_nsec = (msec % 1000) * 1000000;
543 	    (void)nanosleep(&ts, NULL);
544 	}
545 #else
546 # ifdef HAVE_USLEEP
547 	while (msec >= 1000)
548 	{
549 	    usleep((unsigned int)(999 * 1000));
550 	    msec -= 999;
551 	}
552 	usleep((unsigned int)(msec * 1000));
553 # else
554 #  ifndef HAVE_SELECT
555 	poll(NULL, 0, (int)msec);
556 #  else
557 #   ifdef __EMX__
558 	_sleep2(msec);
559 #   else
560 	{
561 	    struct timeval tv;
562 
563 	    tv.tv_sec = msec / 1000;
564 	    tv.tv_usec = (msec % 1000) * 1000;
565 	    /*
566 	     * NOTE: Solaris 2.6 has a bug that makes select() hang here.  Get
567 	     * a patch from Sun to fix this.  Reported by Gunnar Pedersen.
568 	     */
569 	    select(0, NULL, NULL, NULL, &tv);
570 	}
571 #   endif /* __EMX__ */
572 #  endif /* HAVE_SELECT */
573 # endif /* HAVE_NANOSLEEP */
574 #endif /* HAVE_USLEEP */
575 
576 	settmode(old_tmode);
577     }
578     else
579 	WaitForChar(msec);
580 }
581 
582 #if defined(HAVE_GETRLIMIT) \
583 	|| (!defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGSTACK))
584 # define HAVE_CHECK_STACK_GROWTH
585 /*
586  * Support for checking for an almost-out-of-stack-space situation.
587  */
588 
589 /*
590  * Return a pointer to an item on the stack.  Used to find out if the stack
591  * grows up or down.
592  */
593 static void check_stack_growth __ARGS((char *p));
594 static int stack_grows_downwards;
595 
596 /*
597  * Find out if the stack grows upwards or downwards.
598  * "p" points to a variable on the stack of the caller.
599  */
600     static void
601 check_stack_growth(p)
602     char	*p;
603 {
604     int		i;
605 
606     stack_grows_downwards = (p > (char *)&i);
607 }
608 #endif
609 
610 #if defined(HAVE_GETRLIMIT) || defined(PROTO)
611 static char *stack_limit = NULL;
612 
613 #if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H)
614 # include <pthread.h>
615 # include <pthread_np.h>
616 #endif
617 
618 /*
619  * Find out until how var the stack can grow without getting into trouble.
620  * Called when starting up and when switching to the signal stack in
621  * deathtrap().
622  */
623     static void
624 get_stack_limit()
625 {
626     struct rlimit	rlp;
627     int			i;
628     long		lim;
629 
630     /* Set the stack limit to 15/16 of the allowable size.  Skip this when the
631      * limit doesn't fit in a long (rlim_cur might be "long long"). */
632     if (getrlimit(RLIMIT_STACK, &rlp) == 0
633 	    && rlp.rlim_cur < ((rlim_t)1 << (sizeof(long_u) * 8 - 1))
634 #  ifdef RLIM_INFINITY
635 	    && rlp.rlim_cur != RLIM_INFINITY
636 #  endif
637        )
638     {
639 	lim = (long)rlp.rlim_cur;
640 #if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H)
641 	{
642 	    pthread_attr_t  attr;
643 	    size_t	    size;
644 
645 	    /* On FreeBSD the initial thread always has a fixed stack size, no
646 	     * matter what the limits are set to.  Normally it's 1 Mbyte. */
647 	    pthread_attr_init(&attr);
648 	    if (pthread_attr_get_np(pthread_self(), &attr) == 0)
649 	    {
650 		pthread_attr_getstacksize(&attr, &size);
651 		if (lim > (long)size)
652 		    lim = (long)size;
653 	    }
654 	    pthread_attr_destroy(&attr);
655 	}
656 #endif
657 	if (stack_grows_downwards)
658 	{
659 	    stack_limit = (char *)((long)&i - (lim / 16L * 15L));
660 	    if (stack_limit >= (char *)&i)
661 		/* overflow, set to 1/16 of current stack position */
662 		stack_limit = (char *)((long)&i / 16L);
663 	}
664 	else
665 	{
666 	    stack_limit = (char *)((long)&i + (lim / 16L * 15L));
667 	    if (stack_limit <= (char *)&i)
668 		stack_limit = NULL;	/* overflow */
669 	}
670     }
671 }
672 
673 /*
674  * Return FAIL when running out of stack space.
675  * "p" must point to any variable local to the caller that's on the stack.
676  */
677     int
678 mch_stackcheck(p)
679     char	*p;
680 {
681     if (stack_limit != NULL)
682     {
683 	if (stack_grows_downwards)
684 	{
685 	    if (p < stack_limit)
686 		return FAIL;
687 	}
688 	else if (p > stack_limit)
689 	    return FAIL;
690     }
691     return OK;
692 }
693 #endif
694 
695 #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
696 /*
697  * Support for using the signal stack.
698  * This helps when we run out of stack space, which causes a SIGSEGV.  The
699  * signal handler then must run on another stack, since the normal stack is
700  * completely full.
701  */
702 
703 #ifndef SIGSTKSZ
704 # define SIGSTKSZ 8000    /* just a guess of how much stack is needed... */
705 #endif
706 
707 # ifdef HAVE_SIGALTSTACK
708 static stack_t sigstk;			/* for sigaltstack() */
709 # else
710 static struct sigstack sigstk;		/* for sigstack() */
711 # endif
712 
713 static void init_signal_stack __ARGS((void));
714 static char *signal_stack;
715 
716     static void
717 init_signal_stack()
718 {
719     if (signal_stack != NULL)
720     {
721 # ifdef HAVE_SIGALTSTACK
722 #  ifdef __APPLE__
723 	/* missing prototype.  Adding it to osdef?.h.in doesn't work, because
724 	 * "struct sigaltstack" needs to be declared. */
725 	extern int sigaltstack __ARGS((const struct sigaltstack *ss, struct sigaltstack *oss));
726 #  endif
727 
728 #  ifdef HAVE_SS_BASE
729 	sigstk.ss_base = signal_stack;
730 #  else
731 	sigstk.ss_sp = signal_stack;
732 #  endif
733 	sigstk.ss_size = SIGSTKSZ;
734 	sigstk.ss_flags = 0;
735 	(void)sigaltstack(&sigstk, NULL);
736 # else
737 	sigstk.ss_sp = signal_stack;
738 	if (stack_grows_downwards)
739 	    sigstk.ss_sp += SIGSTKSZ - 1;
740 	sigstk.ss_onstack = 0;
741 	(void)sigstack(&sigstk, NULL);
742 # endif
743     }
744 }
745 #endif
746 
747 /*
748  * We need correct potatotypes for a signal function, otherwise mean compilers
749  * will barf when the second argument to signal() is ``wrong''.
750  * Let me try it with a few tricky defines from my own osdef.h	(jw).
751  */
752 #if defined(SIGWINCH)
753 /* ARGSUSED */
754     static RETSIGTYPE
755 sig_winch SIGDEFARG(sigarg)
756 {
757     /* this is not required on all systems, but it doesn't hurt anybody */
758     signal(SIGWINCH, (RETSIGTYPE (*)())sig_winch);
759     do_resize = TRUE;
760     SIGRETURN;
761 }
762 #endif
763 
764 #if defined(SIGINT)
765 /* ARGSUSED */
766     static RETSIGTYPE
767 catch_sigint SIGDEFARG(sigarg)
768 {
769     /* this is not required on all systems, but it doesn't hurt anybody */
770     signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
771     got_int = TRUE;
772     SIGRETURN;
773 }
774 #endif
775 
776 #if defined(SIGPWR)
777 /* ARGSUSED */
778     static RETSIGTYPE
779 catch_sigpwr SIGDEFARG(sigarg)
780 {
781     /*
782      * I'm not sure we get the SIGPWR signal when the system is really going
783      * down or when the batteries are almost empty.  Just preserve the swap
784      * files and don't exit, that can't do any harm.
785      */
786     ml_sync_all(FALSE, FALSE);
787     SIGRETURN;
788 }
789 #endif
790 
791 #ifdef SET_SIG_ALARM
792 /*
793  * signal function for alarm().
794  */
795 /* ARGSUSED */
796     static RETSIGTYPE
797 sig_alarm SIGDEFARG(sigarg)
798 {
799     /* doesn't do anything, just to break a system call */
800     sig_alarm_called = TRUE;
801     SIGRETURN;
802 }
803 #endif
804 
805 #if defined(HAVE_SETJMP_H) || defined(PROTO)
806 /*
807  * A simplistic version of setjmp() that only allows one level of using.
808  * Don't call twice before calling mch_endjmp()!.
809  * Usage:
810  *	mch_startjmp();
811  *	if (SETJMP(lc_jump_env) != 0)
812  *	{
813  *	    mch_didjmp();
814  *	    EMSG("crash!");
815  *	}
816  *	else
817  *	{
818  *	    do_the_work;
819  *	    mch_endjmp();
820  *	}
821  * Note: Can't move SETJMP() here, because a function calling setjmp() must
822  * not return before the saved environment is used.
823  * Returns OK for normal return, FAIL when the protected code caused a
824  * problem and LONGJMP() was used.
825  */
826     void
827 mch_startjmp()
828 {
829 #ifdef SIGHASARG
830     lc_signal = 0;
831 #endif
832     lc_active = TRUE;
833 }
834 
835     void
836 mch_endjmp()
837 {
838     lc_active = FALSE;
839 }
840 
841     void
842 mch_didjmp()
843 {
844 # if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
845     /* On FreeBSD the signal stack has to be reset after using siglongjmp(),
846      * otherwise catching the signal only works once. */
847     init_signal_stack();
848 # endif
849 }
850 #endif
851 
852 /*
853  * This function handles deadly signals.
854  * It tries to preserve any swap file and exit properly.
855  * (partly from Elvis).
856  */
857     static RETSIGTYPE
858 deathtrap SIGDEFARG(sigarg)
859 {
860     static int	entered = 0;	    /* count the number of times we got here.
861 				       Note: when memory has been corrupted
862 				       this may get an arbitrary value! */
863 #ifdef SIGHASARG
864     int		i;
865 #endif
866 
867 #if defined(HAVE_SETJMP_H)
868     /*
869      * Catch a crash in protected code.
870      * Restores the environment saved in lc_jump_env, which looks like
871      * SETJMP() returns 1.
872      */
873     if (lc_active)
874     {
875 # if defined(SIGHASARG)
876 	lc_signal = sigarg;
877 # endif
878 	lc_active = FALSE;	/* don't jump again */
879 	LONGJMP(lc_jump_env, 1);
880 	/* NOTREACHED */
881     }
882 #endif
883 
884     /* Remember how often we have been called. */
885     ++entered;
886 
887 #ifdef FEAT_EVAL
888     /* Set the v:dying variable. */
889     set_vim_var_nr(VV_DYING, (long)entered);
890 #endif
891 
892 #ifdef HAVE_GETRLIMIT
893     /* Since we are now using the signal stack, need to reset the stack
894      * limit.  Otherwise using a regexp will fail. */
895     get_stack_limit();
896 #endif
897 
898 #ifdef SIGHASARG
899     /* try to find the name of this signal */
900     for (i = 0; signal_info[i].sig != -1; i++)
901 	if (sigarg == signal_info[i].sig)
902 	    break;
903     deadly_signal = sigarg;
904 #endif
905 
906     full_screen = FALSE;	/* don't write message to the GUI, it might be
907 				 * part of the problem... */
908     /*
909      * If something goes wrong after entering here, we may get here again.
910      * When this happens, give a message and try to exit nicely (resetting the
911      * terminal mode, etc.)
912      * When this happens twice, just exit, don't even try to give a message,
913      * stack may be corrupt or something weird.
914      * When this still happens again (or memory was corrupted in such a way
915      * that "entered" was clobbered) use _exit(), don't try freeing resources.
916      */
917     if (entered >= 3)
918     {
919 	reset_signals();	/* don't catch any signals anymore */
920 	may_core_dump();
921 	if (entered >= 4)
922 	    _exit(8);
923 	exit(7);
924     }
925     if (entered == 2)
926     {
927 	OUT_STR(_("Vim: Double signal, exiting\n"));
928 	out_flush();
929 	getout(1);
930     }
931 
932 #ifdef SIGHASARG
933     sprintf((char *)IObuff, _("Vim: Caught deadly signal %s\n"),
934 							 signal_info[i].name);
935 #else
936     sprintf((char *)IObuff, _("Vim: Caught deadly signal\n"));
937 #endif
938     preserve_exit();		    /* preserve files and exit */
939 
940     SIGRETURN;
941 }
942 
943 #ifdef _REENTRANT
944 /*
945  * On Solaris with multi-threading, suspending might not work immediately.
946  * Catch the SIGCONT signal, which will be used as an indication whether the
947  * suspending has been done or not.
948  */
949 static int sigcont_received;
950 static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG);
951 
952 /*
953  * signal handler for SIGCONT
954  */
955 /* ARGSUSED */
956     static RETSIGTYPE
957 sigcont_handler SIGDEFARG(sigarg)
958 {
959     sigcont_received = TRUE;
960     SIGRETURN;
961 }
962 #endif
963 
964 /*
965  * If the machine has job control, use it to suspend the program,
966  * otherwise fake it by starting a new shell.
967  */
968     void
969 mch_suspend()
970 {
971     /* BeOS does have SIGTSTP, but it doesn't work. */
972 #if defined(SIGTSTP) && !defined(__BEOS__)
973     out_flush();	    /* needed to make cursor visible on some systems */
974     settmode(TMODE_COOK);
975     out_flush();	    /* needed to disable mouse on some systems */
976 
977 # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
978     /* Since we are going to sleep, we can't respond to requests for the X
979      * selections.  Lose them, otherwise other applications will hang.  But
980      * first copy the text to cut buffer 0. */
981     if (clip_star.owned || clip_plus.owned)
982     {
983 	x11_export_final_selection();
984 	if (clip_star.owned)
985 	    clip_lose_selection(&clip_star);
986 	if (clip_plus.owned)
987 	    clip_lose_selection(&clip_plus);
988 	if (x11_display != NULL)
989 	    XFlush(x11_display);
990     }
991 # endif
992 
993 # ifdef _REENTRANT
994     sigcont_received = FALSE;
995 # endif
996     kill(0, SIGTSTP);	    /* send ourselves a STOP signal */
997 # ifdef _REENTRANT
998     /* When we didn't suspend immediately in the kill(), do it now.  Happens
999      * on multi-threaded Solaris. */
1000     if (!sigcont_received)
1001 	pause();
1002 # endif
1003 
1004 # ifdef FEAT_TITLE
1005     /*
1006      * Set oldtitle to NULL, so the current title is obtained again.
1007      */
1008     vim_free(oldtitle);
1009     oldtitle = NULL;
1010 # endif
1011     settmode(TMODE_RAW);
1012     need_check_timestamps = TRUE;
1013     did_check_timestamps = FALSE;
1014 #else
1015     suspend_shell();
1016 #endif
1017 }
1018 
1019     void
1020 mch_init()
1021 {
1022     Columns = 80;
1023     Rows = 24;
1024 
1025     out_flush();
1026     set_signals();
1027 }
1028 
1029     static void
1030 set_signals()
1031 {
1032 #if defined(SIGWINCH)
1033     /*
1034      * WINDOW CHANGE signal is handled with sig_winch().
1035      */
1036     signal(SIGWINCH, (RETSIGTYPE (*)())sig_winch);
1037 #endif
1038 
1039     /*
1040      * We want the STOP signal to work, to make mch_suspend() work.
1041      * For "rvim" the STOP signal is ignored.
1042      */
1043 #ifdef SIGTSTP
1044     signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
1045 #endif
1046 #ifdef _REENTRANT
1047     signal(SIGCONT, sigcont_handler);
1048 #endif
1049 
1050     /*
1051      * We want to ignore breaking of PIPEs.
1052      */
1053 #ifdef SIGPIPE
1054     signal(SIGPIPE, SIG_IGN);
1055 #endif
1056 
1057     /*
1058      * We want to catch CTRL-C (only works while in Cooked mode).
1059      */
1060 #ifdef SIGINT
1061     signal(SIGINT, (RETSIGTYPE (*)())catch_sigint);
1062 #endif
1063 
1064     /*
1065      * Ignore alarm signals (Perl's alarm() generates it).
1066      */
1067 #ifdef SIGALRM
1068     signal(SIGALRM, SIG_IGN);
1069 #endif
1070 
1071     /*
1072      * Catch SIGPWR (power failure?) to preserve the swap files, so that no
1073      * work will be lost.
1074      */
1075 #ifdef SIGPWR
1076     signal(SIGPWR, (RETSIGTYPE (*)())catch_sigpwr);
1077 #endif
1078 
1079     /*
1080      * Arrange for other signals to gracefully shutdown Vim.
1081      */
1082     catch_signals(deathtrap, SIG_ERR);
1083 
1084 #if defined(FEAT_GUI) && defined(SIGHUP)
1085     /*
1086      * When the GUI is running, ignore the hangup signal.
1087      */
1088     if (gui.in_use)
1089 	signal(SIGHUP, SIG_IGN);
1090 #endif
1091 }
1092 
1093     void
1094 reset_signals()
1095 {
1096     catch_signals(SIG_DFL, SIG_DFL);
1097 #ifdef _REENTRANT
1098     /* SIGCONT isn't in the list, because its default action is ignore */
1099     signal(SIGCONT, SIG_DFL);
1100 #endif
1101 }
1102 
1103     static void
1104 catch_signals(func_deadly, func_other)
1105     RETSIGTYPE (*func_deadly)();
1106     RETSIGTYPE (*func_other)();
1107 {
1108     int	    i;
1109 
1110     for (i = 0; signal_info[i].sig != -1; i++)
1111 	if (signal_info[i].deadly)
1112 	{
1113 #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1114 	    struct sigaction sa;
1115 
1116 	    /* Setup to use the alternate stack for the signal function. */
1117 	    sa.sa_handler = func_deadly;
1118 	    sigemptyset(&sa.sa_mask);
1119 # if defined(__linux__) && defined(_REENTRANT)
1120 	    /* On Linux, with glibc compiled for kernel 2.2, there is a bug in
1121 	     * thread handling in combination with using the alternate stack:
1122 	     * pthread library functions try to use the stack pointer to
1123 	     * identify the current thread, causing a SEGV signal, which
1124 	     * recursively calls deathtrap() and hangs. */
1125 	    sa.sa_flags = 0;
1126 # else
1127 	    sa.sa_flags = SA_ONSTACK;
1128 # endif
1129 	    sigaction(signal_info[i].sig, &sa, NULL);
1130 #else
1131 # if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGVEC)
1132 	    struct sigvec sv;
1133 
1134 	    /* Setup to use the alternate stack for the signal function. */
1135 	    sv.sv_handler = func_deadly;
1136 	    sv.sv_mask = 0;
1137 	    sv.sv_flags = SV_ONSTACK;
1138 	    sigvec(signal_info[i].sig, &sv, NULL);
1139 # else
1140 	    signal(signal_info[i].sig, func_deadly);
1141 # endif
1142 #endif
1143 	}
1144 	else if (func_other != SIG_ERR)
1145 	    signal(signal_info[i].sig, func_other);
1146 }
1147 
1148 /*
1149  * Check_win checks whether we have an interactive stdout.
1150  */
1151 /* ARGSUSED */
1152     int
1153 mch_check_win(argc, argv)
1154     int	    argc;
1155     char    **argv;
1156 {
1157 #ifdef OS2
1158     /*
1159      * Store argv[0], may be used for $VIM.  Only use it if it is an absolute
1160      * name, mostly it's just "vim" and found in the path, which is unusable.
1161      */
1162     if (mch_isFullName(argv[0]))
1163 	exe_name = vim_strsave((char_u *)argv[0]);
1164 #endif
1165     if (isatty(1))
1166 	return OK;
1167     return FAIL;
1168 }
1169 
1170 /*
1171  * Return TRUE if the input comes from a terminal, FALSE otherwise.
1172  */
1173     int
1174 mch_input_isatty()
1175 {
1176     if (isatty(read_cmd_fd))
1177 	return TRUE;
1178     return FALSE;
1179 }
1180 
1181 #ifdef FEAT_X11
1182 
1183 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
1184 	&& (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
1185 
1186 static void xopen_message __ARGS((struct timeval *tvp));
1187 
1188 /*
1189  * Give a message about the elapsed time for opening the X window.
1190  */
1191     static void
1192 xopen_message(tvp)
1193     struct timeval *tvp;	/* must contain start time */
1194 {
1195     struct timeval  end_tv;
1196 
1197     /* Compute elapsed time. */
1198     gettimeofday(&end_tv, NULL);
1199     smsg((char_u *)_("Opening the X display took %ld msec"),
1200 	    (end_tv.tv_sec - tvp->tv_sec) * 1000L
1201 	    + (end_tv.tv_usec - tvp->tv_usec) / 1000L);
1202 }
1203 # endif
1204 #endif
1205 
1206 #if defined(FEAT_X11) && (defined(FEAT_TITLE) || defined(FEAT_XCLIPBOARD))
1207 /*
1208  * A few functions shared by X11 title and clipboard code.
1209  */
1210 static int x_error_handler __ARGS((Display *dpy, XErrorEvent *error_event));
1211 static int x_error_check __ARGS((Display *dpy, XErrorEvent *error_event));
1212 static int x_connect_to_server __ARGS((void));
1213 static int test_x11_window __ARGS((Display *dpy));
1214 
1215 static int	got_x_error = FALSE;
1216 
1217 /*
1218  * X Error handler, otherwise X just exits!  (very rude) -- webb
1219  */
1220     static int
1221 x_error_handler(dpy, error_event)
1222     Display	*dpy;
1223     XErrorEvent	*error_event;
1224 {
1225     /* KDE sometimes produces X error that we want to ignore */
1226 #if defined(FEAT_GUI_KDE)
1227     XGetErrorText(dpy, error_event->error_code, (char *)IObuff, IOSIZE);
1228     STRCAT(IObuff, "\nVim: Got X error but we continue...\n");
1229     fprintf(stderr, IObuff);
1230     return 0;
1231 #else
1232     XGetErrorText(dpy, error_event->error_code, (char *)IObuff, IOSIZE);
1233     STRCAT(IObuff, _("\nVim: Got X error\n"));
1234 
1235     /* We cannot print a message and continue, because no X calls are allowed
1236      * here (causes my system to hang).  Silently continuing might be an
1237      * alternative... */
1238     preserve_exit();		    /* preserve files and exit */
1239 
1240     return 0;		/* NOTREACHED */
1241 #endif
1242 }
1243 
1244 /*
1245  * Another X Error handler, just used to check for errors.
1246  */
1247 /* ARGSUSED */
1248     static int
1249 x_error_check(dpy, error_event)
1250     Display *dpy;
1251     XErrorEvent	*error_event;
1252 {
1253     got_x_error = TRUE;
1254     return 0;
1255 }
1256 
1257 #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
1258 # if defined(HAVE_SETJMP_H)
1259 /*
1260  * An X IO Error handler, used to catch error while opening the display.
1261  */
1262 static int x_IOerror_check __ARGS((Display *dpy));
1263 
1264 /* ARGSUSED */
1265     static int
1266 x_IOerror_check(dpy)
1267     Display *dpy;
1268 {
1269     /* This function should not return, it causes exit().  Longjump instead. */
1270     LONGJMP(lc_jump_env, 1);
1271     /*NOTREACHED*/
1272     return 0;
1273 }
1274 # endif
1275 
1276 /*
1277  * An X IO Error handler, used to catch terminal errors.
1278  */
1279 static int x_IOerror_handler __ARGS((Display *dpy));
1280 
1281 /* ARGSUSED */
1282     static int
1283 x_IOerror_handler(dpy)
1284     Display *dpy;
1285 {
1286     xterm_dpy = NULL;
1287     x11_window = 0;
1288     x11_display = NULL;
1289     xterm_Shell = (Widget)0;
1290 
1291     /* This function should not return, it causes exit().  Longjump instead. */
1292     LONGJMP(x_jump_env, 1);
1293     /*NOTREACHED*/
1294     return 0;
1295 }
1296 #endif
1297 
1298 /*
1299  * Return TRUE when connection to the X server is desired.
1300  */
1301     static int
1302 x_connect_to_server()
1303 {
1304     regmatch_T	regmatch;
1305 
1306 #if defined(FEAT_CLIENTSERVER)
1307     if (x_force_connect)
1308 	return TRUE;
1309 #endif
1310     if (x_no_connect)
1311 	return FALSE;
1312 
1313     /* Check for a match with "exclude:" from 'clipboard'. */
1314     if (clip_exclude_prog != NULL)
1315     {
1316 	regmatch.rm_ic = FALSE;		/* Don't ignore case */
1317 	regmatch.regprog = clip_exclude_prog;
1318 	if (vim_regexec(&regmatch, T_NAME, (colnr_T)0))
1319 	    return FALSE;
1320     }
1321     return TRUE;
1322 }
1323 
1324 /*
1325  * Test if "dpy" and x11_window are valid by getting the window title.
1326  * I don't actually want it yet, so there may be a simpler call to use, but
1327  * this will cause the error handler x_error_check() to be called if anything
1328  * is wrong, such as the window pointer being invalid (as can happen when the
1329  * user changes his DISPLAY, but not his WINDOWID) -- webb
1330  */
1331     static int
1332 test_x11_window(dpy)
1333     Display	*dpy;
1334 {
1335     int			(*old_handler)();
1336     XTextProperty	text_prop;
1337 
1338     old_handler = XSetErrorHandler(x_error_check);
1339     got_x_error = FALSE;
1340     if (XGetWMName(dpy, x11_window, &text_prop))
1341 	XFree((void *)text_prop.value);
1342     XSync(dpy, False);
1343     (void)XSetErrorHandler(old_handler);
1344 
1345     if (p_verbose > 0 && got_x_error)
1346 	MSG(_("Testing the X display failed"));
1347 
1348     return (got_x_error ? FAIL : OK);
1349 }
1350 #endif
1351 
1352 #ifdef FEAT_TITLE
1353 
1354 #ifdef FEAT_X11
1355 
1356 static int get_x11_thing __ARGS((int get_title, int test_only));
1357 
1358 /*
1359  * try to get x11 window and display
1360  *
1361  * return FAIL for failure, OK otherwise
1362  */
1363     static int
1364 get_x11_windis()
1365 {
1366     char	    *winid;
1367     static int	    result = -1;
1368 #define XD_NONE	 0	/* x11_display not set here */
1369 #define XD_HERE	 1	/* x11_display opened here */
1370 #define XD_GUI	 2	/* x11_display used from gui.dpy */
1371 #define XD_XTERM 3	/* x11_display used from xterm_dpy */
1372     static int	    x11_display_from = XD_NONE;
1373     static int	    did_set_error_handler = FALSE;
1374 
1375     if (!did_set_error_handler)
1376     {
1377 	/* X just exits if it finds an error otherwise! */
1378 	(void)XSetErrorHandler(x_error_handler);
1379 	did_set_error_handler = TRUE;
1380     }
1381 
1382 #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_KDE)
1383     if (gui.in_use)
1384     {
1385 	/*
1386 	 * If the X11 display was opened here before, for the window where Vim
1387 	 * was started, close that one now to avoid a memory leak.
1388 	 */
1389 	if (x11_display_from == XD_HERE && x11_display != NULL)
1390 	{
1391 	    XCloseDisplay(x11_display);
1392 	    x11_display_from = XD_NONE;
1393 	}
1394 	if (gui_get_x11_windis(&x11_window, &x11_display) == OK)
1395 	{
1396 	    x11_display_from = XD_GUI;
1397 	    return OK;
1398 	}
1399 	x11_display = NULL;
1400 	return FAIL;
1401     }
1402     else if (x11_display_from == XD_GUI)
1403     {
1404 	/* GUI must have stopped somehow, clear x11_display */
1405 	x11_window = 0;
1406 	x11_display = NULL;
1407 	x11_display_from = XD_NONE;
1408     }
1409 #endif
1410 
1411     /* When started with the "-X" argument, don't try connecting. */
1412     if (!x_connect_to_server())
1413 	return FAIL;
1414 
1415     /*
1416      * If WINDOWID not set, should try another method to find out
1417      * what the current window number is. The only code I know for
1418      * this is very complicated.
1419      * We assume that zero is invalid for WINDOWID.
1420      */
1421     if (x11_window == 0 && (winid = getenv("WINDOWID")) != NULL)
1422 	x11_window = (Window)atol(winid);
1423 
1424 #ifdef FEAT_XCLIPBOARD
1425     if (xterm_dpy != NULL && x11_window != 0)
1426     {
1427 	/* Checked it already. */
1428 	if (x11_display_from == XD_XTERM)
1429 	    return OK;
1430 
1431 	/*
1432 	 * If the X11 display was opened here before, for the window where Vim
1433 	 * was started, close that one now to avoid a memory leak.
1434 	 */
1435 	if (x11_display_from == XD_HERE && x11_display != NULL)
1436 	    XCloseDisplay(x11_display);
1437 	x11_display = xterm_dpy;
1438 	x11_display_from = XD_XTERM;
1439 	if (test_x11_window(x11_display) == FAIL)
1440 	{
1441 	    /* probably bad $WINDOWID */
1442 	    x11_window = 0;
1443 	    x11_display = NULL;
1444 	    x11_display_from = XD_NONE;
1445 	    return FAIL;
1446 	}
1447 	return OK;
1448     }
1449 #endif
1450 
1451     if (x11_window == 0 || x11_display == NULL)
1452 	result = -1;
1453 
1454     if (result != -1)	    /* Have already been here and set this */
1455 	return result;	    /* Don't do all these X calls again */
1456 
1457     if (x11_window != 0 && x11_display == NULL)
1458     {
1459 #ifdef SET_SIG_ALARM
1460 	RETSIGTYPE (*sig_save)();
1461 #endif
1462 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1463 	struct timeval  start_tv;
1464 
1465 	if (p_verbose > 0)
1466 	    gettimeofday(&start_tv, NULL);
1467 #endif
1468 
1469 #ifdef SET_SIG_ALARM
1470 	/*
1471 	 * Opening the Display may hang if the DISPLAY setting is wrong, or
1472 	 * the network connection is bad.  Set an alarm timer to get out.
1473 	 */
1474 	sig_alarm_called = FALSE;
1475 	sig_save = (RETSIGTYPE (*)())signal(SIGALRM,
1476 						 (RETSIGTYPE (*)())sig_alarm);
1477 	alarm(2);
1478 #endif
1479 	x11_display = XOpenDisplay(NULL);
1480 
1481 #ifdef SET_SIG_ALARM
1482 	alarm(0);
1483 	signal(SIGALRM, (RETSIGTYPE (*)())sig_save);
1484 	if (p_verbose > 0 && sig_alarm_called)
1485 	    MSG(_("Opening the X display timed out"));
1486 #endif
1487 	if (x11_display != NULL)
1488 	{
1489 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1490 	    if (p_verbose > 0)
1491 		xopen_message(&start_tv);
1492 # endif
1493 	    if (test_x11_window(x11_display) == FAIL)
1494 	    {
1495 		/* Maybe window id is bad */
1496 		x11_window = 0;
1497 		XCloseDisplay(x11_display);
1498 		x11_display = NULL;
1499 	    }
1500 	    else
1501 		x11_display_from = XD_HERE;
1502 	}
1503     }
1504     if (x11_window == 0 || x11_display == NULL)
1505 	return (result = FAIL);
1506     return (result = OK);
1507 }
1508 
1509 /*
1510  * Determine original x11 Window Title
1511  */
1512     static int
1513 get_x11_title(test_only)
1514     int		test_only;
1515 {
1516     int		retval;
1517 
1518     retval = get_x11_thing(TRUE, test_only);
1519 
1520     /* could not get old title: oldtitle == NULL */
1521 
1522     return retval;
1523 }
1524 
1525 /*
1526  * Determine original x11 Window icon
1527  */
1528     static int
1529 get_x11_icon(test_only)
1530     int		test_only;
1531 {
1532     int		retval = FALSE;
1533 
1534     retval = get_x11_thing(FALSE, test_only);
1535 
1536     /* could not get old icon, use terminal name */
1537     if (oldicon == NULL && !test_only)
1538     {
1539 	if (STRNCMP(T_NAME, "builtin_", 8) == 0)
1540 	    oldicon = T_NAME + 8;
1541 	else
1542 	    oldicon = T_NAME;
1543     }
1544 
1545     return retval;
1546 }
1547 
1548     static int
1549 get_x11_thing(get_title, test_only)
1550     int		get_title;	/* get title string */
1551     int		test_only;
1552 {
1553     XTextProperty	text_prop;
1554     int			retval = FALSE;
1555     Status		status;
1556 
1557     if (get_x11_windis() == OK)
1558     {
1559 	/* Get window/icon name if any */
1560 	if (get_title)
1561 	    status = XGetWMName(x11_display, x11_window, &text_prop);
1562 	else
1563 	    status = XGetWMIconName(x11_display, x11_window, &text_prop);
1564 
1565 	/*
1566 	 * If terminal is xterm, then x11_window may be a child window of the
1567 	 * outer xterm window that actually contains the window/icon name, so
1568 	 * keep traversing up the tree until a window with a title/icon is
1569 	 * found.
1570 	 */
1571 	/* Previously this was only done for xterm and alikes.  I don't see a
1572 	 * reason why it would fail for other terminal emulators.
1573 	 * if (term_is_xterm) */
1574 	{
1575 	    Window	    root;
1576 	    Window	    parent;
1577 	    Window	    win = x11_window;
1578 	    Window	   *children;
1579 	    unsigned int    num_children;
1580 
1581 	    while (!status || text_prop.value == NULL)
1582 	    {
1583 		if (!XQueryTree(x11_display, win, &root, &parent, &children,
1584 							       &num_children))
1585 		    break;
1586 		if (children)
1587 		    XFree((void *)children);
1588 		if (parent == root || parent == 0)
1589 		    break;
1590 
1591 		win = parent;
1592 		if (get_title)
1593 		    status = XGetWMName(x11_display, win, &text_prop);
1594 		else
1595 		    status = XGetWMIconName(x11_display, win, &text_prop);
1596 	    }
1597 	}
1598 	if (status && text_prop.value != NULL)
1599 	{
1600 	    retval = TRUE;
1601 	    if (!test_only)
1602 	    {
1603 #ifdef FEAT_XFONTSET
1604 		if (text_prop.encoding == XA_STRING)
1605 		{
1606 #endif
1607 		    if (get_title)
1608 			oldtitle = vim_strsave((char_u *)text_prop.value);
1609 		    else
1610 			oldicon = vim_strsave((char_u *)text_prop.value);
1611 #ifdef FEAT_XFONTSET
1612 		}
1613 		else
1614 		{
1615 		    char    **cl;
1616 		    Status  transform_status;
1617 		    int	    n = 0;
1618 
1619 		    transform_status = XmbTextPropertyToTextList(x11_display,
1620 								 &text_prop,
1621 								 &cl, &n);
1622 		    if (transform_status >= Success && n > 0 && cl[0])
1623 		    {
1624 			if (get_title)
1625 			    oldtitle = vim_strsave((char_u *) cl[0]);
1626 			else
1627 			    oldicon = vim_strsave((char_u *) cl[0]);
1628 			XFreeStringList(cl);
1629 		    }
1630 		    else
1631 		    {
1632 			if (get_title)
1633 			    oldtitle = vim_strsave((char_u *)text_prop.value);
1634 			else
1635 			    oldicon = vim_strsave((char_u *)text_prop.value);
1636 		    }
1637 		}
1638 #endif
1639 	    }
1640 	    XFree((void *)text_prop.value);
1641 	}
1642     }
1643     return retval;
1644 }
1645 
1646 /* Are Xutf8 functions available?  Avoid error from old compilers. */
1647 #if defined(X_HAVE_UTF8_STRING) && defined(FEAT_MBYTE)
1648 # if X_HAVE_UTF8_STRING
1649 #  define USE_UTF8_STRING
1650 # endif
1651 #endif
1652 
1653 /*
1654  * Set x11 Window Title
1655  *
1656  * get_x11_windis() must be called before this and have returned OK
1657  */
1658     static void
1659 set_x11_title(title)
1660     char_u	*title;
1661 {
1662 	/* XmbSetWMProperties() and Xutf8SetWMProperties() should use a STRING
1663 	 * when possible, COMPOUND_TEXT otherwise.  COMPOUND_TEXT isn't
1664 	 * supported everywhere and STRING doesn't work for multi-byte titles.
1665 	 */
1666 #ifdef USE_UTF8_STRING
1667     if (enc_utf8)
1668 	Xutf8SetWMProperties(x11_display, x11_window, (const char *)title,
1669 					     NULL, NULL, 0, NULL, NULL, NULL);
1670     else
1671 #endif
1672     {
1673 #if XtSpecificationRelease >= 4
1674 # ifdef FEAT_XFONTSET
1675 	XmbSetWMProperties(x11_display, x11_window, (const char *)title,
1676 					     NULL, NULL, 0, NULL, NULL, NULL);
1677 # else
1678 	XTextProperty	text_prop;
1679 
1680 	/* directly from example 3-18 "basicwin" of Xlib Programming Manual */
1681 	(void)XStringListToTextProperty((char **)&title, 1, &text_prop);
1682 	XSetWMProperties(x11_display, x11_window, &text_prop,
1683 					     NULL, NULL, 0, NULL, NULL, NULL);
1684 # endif
1685 #else
1686 	XStoreName(x11_display, x11_window, (char *)title);
1687 #endif
1688     }
1689     XFlush(x11_display);
1690 }
1691 
1692 /*
1693  * Set x11 Window icon
1694  *
1695  * get_x11_windis() must be called before this and have returned OK
1696  */
1697     static void
1698 set_x11_icon(icon)
1699     char_u	*icon;
1700 {
1701     /* See above for comments about using X*SetWMProperties(). */
1702 #ifdef USE_UTF8_STRING
1703     if (enc_utf8)
1704 	Xutf8SetWMProperties(x11_display, x11_window, NULL, (const char *)icon,
1705 						   NULL, 0, NULL, NULL, NULL);
1706     else
1707 #endif
1708     {
1709 #if XtSpecificationRelease >= 4
1710 # ifdef FEAT_XFONTSET
1711 	XmbSetWMProperties(x11_display, x11_window, NULL, (const char *)icon,
1712 						   NULL, 0, NULL, NULL, NULL);
1713 # else
1714 	XTextProperty	text_prop;
1715 
1716 	(void)XStringListToTextProperty((char **)&icon, 1, &text_prop);
1717 	XSetWMProperties(x11_display, x11_window, NULL, &text_prop,
1718 						   NULL, 0, NULL, NULL, NULL);
1719 # endif
1720 #else
1721 	XSetIconName(x11_display, x11_window, (char *)icon);
1722 #endif
1723     }
1724     XFlush(x11_display);
1725 }
1726 
1727 #else  /* FEAT_X11 */
1728 
1729 /*ARGSUSED*/
1730     static int
1731 get_x11_title(test_only)
1732     int	    test_only;
1733 {
1734     return FALSE;
1735 }
1736 
1737     static int
1738 get_x11_icon(test_only)
1739     int	    test_only;
1740 {
1741     if (!test_only)
1742     {
1743 	if (STRNCMP(T_NAME, "builtin_", 8) == 0)
1744 	    oldicon = T_NAME + 8;
1745 	else
1746 	    oldicon = T_NAME;
1747     }
1748     return FALSE;
1749 }
1750 
1751 #endif /* FEAT_X11 */
1752 
1753     int
1754 mch_can_restore_title()
1755 {
1756     return get_x11_title(TRUE);
1757 }
1758 
1759     int
1760 mch_can_restore_icon()
1761 {
1762     return get_x11_icon(TRUE);
1763 }
1764 
1765 /*
1766  * Set the window title and icon.
1767  */
1768     void
1769 mch_settitle(title, icon)
1770     char_u *title;
1771     char_u *icon;
1772 {
1773     int		type = 0;
1774     static int	recursive = 0;
1775 
1776     if (T_NAME == NULL)	    /* no terminal name (yet) */
1777 	return;
1778     if (title == NULL && icon == NULL)	    /* nothing to do */
1779 	return;
1780 
1781     /* When one of the X11 functions causes a deadly signal, we get here again
1782      * recursively.  Avoid hanging then (something is probably locked). */
1783     if (recursive)
1784 	return;
1785     ++recursive;
1786 
1787     /*
1788      * if the window ID and the display is known, we may use X11 calls
1789      */
1790 #ifdef FEAT_X11
1791     if (get_x11_windis() == OK)
1792 	type = 1;
1793 #else
1794 # if defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK)
1795     if (gui.in_use)
1796 	type = 1;
1797 # endif
1798 # ifdef FEAT_GUI_BEOS
1799     /* TODO: If this means (gui.in_use) why not merge with above? (Dany) */
1800     /* we always have a 'window' */
1801     type = 1;
1802 # endif
1803 #endif
1804 
1805     /*
1806      * Note: if "t_TS" is set, title is set with escape sequence rather
1807      *	     than x11 calls, because the x11 calls don't always work
1808      */
1809 #ifdef FEAT_GUI_KDE
1810     /* dont know why but KDE needs this one as we don't go through the next function... */
1811     gui_mch_settitle(title, icon);
1812 #endif
1813     if ((type || *T_TS != NUL) && title != NULL)
1814     {
1815 	if (oldtitle == NULL
1816 #ifdef FEAT_GUI
1817 		&& !gui.in_use
1818 #endif
1819 		)		/* first call but not in GUI, save title */
1820 	    (void)get_x11_title(FALSE);
1821 
1822 	if (*T_TS != NUL)		/* it's OK if t_fs is empty */
1823 	    term_settitle(title);
1824 #ifdef FEAT_X11
1825 	else
1826 # ifdef FEAT_GUI_GTK
1827 	if (!gui.in_use)		/* don't do this if GTK+ is running */
1828 # endif
1829 	    set_x11_title(title);		/* x11 */
1830 #endif
1831 #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_BEOS) \
1832 	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
1833 	else
1834 	    gui_mch_settitle(title, icon);
1835 #endif
1836 	did_set_title = TRUE;
1837     }
1838 
1839     if ((type || *T_CIS != NUL) && icon != NULL)
1840     {
1841 	if (oldicon == NULL
1842 #ifdef FEAT_GUI
1843 		&& !gui.in_use
1844 #endif
1845 		)		/* first call, save icon */
1846 	    get_x11_icon(FALSE);
1847 
1848 	if (*T_CIS != NUL)
1849 	{
1850 	    out_str(T_CIS);			/* set icon start */
1851 	    out_str_nf(icon);
1852 	    out_str(T_CIE);			/* set icon end */
1853 	    out_flush();
1854 	}
1855 #ifdef FEAT_X11
1856 	else
1857 # ifdef FEAT_GUI_GTK
1858 	if (!gui.in_use)		/* don't do this if GTK+ is running */
1859 # endif
1860 	    set_x11_icon(icon);			/* x11 */
1861 #endif
1862 	did_set_icon = TRUE;
1863     }
1864     --recursive;
1865 }
1866 
1867 /*
1868  * Restore the window/icon title.
1869  * "which" is one of:
1870  *  1  only restore title
1871  *  2  only restore icon
1872  *  3  restore title and icon
1873  */
1874     void
1875 mch_restore_title(which)
1876     int which;
1877 {
1878     /* only restore the title or icon when it has been set */
1879     mch_settitle(((which & 1) && did_set_title) ?
1880 			(oldtitle ? oldtitle : p_titleold) : NULL,
1881 			      ((which & 2) && did_set_icon) ? oldicon : NULL);
1882 }
1883 
1884 #endif /* FEAT_TITLE */
1885 
1886 /*
1887  * Return TRUE if "name" looks like some xterm name.
1888  */
1889     int
1890 vim_is_xterm(name)
1891     char_u *name;
1892 {
1893     if (name == NULL)
1894 	return FALSE;
1895     return (STRNICMP(name, "xterm", 5) == 0
1896 		|| STRNICMP(name, "nxterm", 6) == 0
1897 		|| STRNICMP(name, "kterm", 5) == 0
1898 		|| STRNICMP(name, "rxvt", 4) == 0
1899 		|| STRCMP(name, "builtin_xterm") == 0);
1900 }
1901 
1902 #if defined(FEAT_MOUSE_TTY) || defined(PROTO)
1903 /*
1904  * Return non-zero when using an xterm mouse, according to 'ttymouse'.
1905  * Return 1 for "xterm".
1906  * Return 2 for "xterm2".
1907  */
1908     int
1909 use_xterm_mouse()
1910 {
1911     if (ttym_flags == TTYM_XTERM2)
1912 	return 2;
1913     if (ttym_flags == TTYM_XTERM)
1914 	return 1;
1915     return 0;
1916 }
1917 #endif
1918 
1919     int
1920 vim_is_iris(name)
1921     char_u  *name;
1922 {
1923     if (name == NULL)
1924 	return FALSE;
1925     return (STRNICMP(name, "iris-ansi", 9) == 0
1926 	    || STRCMP(name, "builtin_iris-ansi") == 0);
1927 }
1928 
1929     int
1930 vim_is_vt300(name)
1931     char_u  *name;
1932 {
1933     if (name == NULL)
1934 	return FALSE;	       /* actually all ANSI comp. terminals should be here  */
1935     return (STRNICMP(name, "vt3", 3) == 0     /* it will cover all from VT100-VT300 */
1936 	    || STRNICMP(name, "vt2", 3) == 0  /* TODO: from VT340 can hanle colors  */
1937 	    || STRNICMP(name, "vt1", 3) == 0
1938 	    || STRCMP(name, "builtin_vt320") == 0);
1939 }
1940 
1941 /*
1942  * Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
1943  * This should include all windowed terminal emulators.
1944  */
1945     int
1946 vim_is_fastterm(name)
1947     char_u  *name;
1948 {
1949     if (name == NULL)
1950 	return FALSE;
1951     if (vim_is_xterm(name) || vim_is_vt300(name) || vim_is_iris(name))
1952 	return TRUE;
1953     return (   STRNICMP(name, "hpterm", 6) == 0
1954 	    || STRNICMP(name, "sun-cmd", 7) == 0
1955 	    || STRNICMP(name, "screen", 6) == 0
1956 	    || STRNICMP(name, "dtterm", 6) == 0);
1957 }
1958 
1959 /*
1960  * Insert user name in s[len].
1961  * Return OK if a name found.
1962  */
1963     int
1964 mch_get_user_name(s, len)
1965     char_u  *s;
1966     int	    len;
1967 {
1968 #ifdef VMS
1969     STRNCPY((char *)s, cuserid(NULL), len);
1970     return OK;
1971 #else
1972     return mch_get_uname(getuid(), s, len);
1973 #endif
1974 }
1975 
1976 /*
1977  * Insert user name for "uid" in s[len].
1978  * Return OK if a name found.
1979  */
1980     int
1981 mch_get_uname(uid, s, len)
1982     uid_t	uid;
1983     char_u	*s;
1984     int		len;
1985 {
1986 #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
1987     struct passwd   *pw;
1988 
1989     if ((pw = getpwuid(uid)) != NULL
1990 	    && pw->pw_name != NULL && *(pw->pw_name) != NUL)
1991     {
1992 	STRNCPY(s, pw->pw_name, len);
1993 	return OK;
1994     }
1995 #endif
1996     sprintf((char *)s, "%d", (int)uid);	    /* assumes s is long enough */
1997     return FAIL;			    /* a number is not a name */
1998 }
1999 
2000 /*
2001  * Insert host name is s[len].
2002  */
2003 
2004 #ifdef HAVE_SYS_UTSNAME_H
2005     void
2006 mch_get_host_name(s, len)
2007     char_u  *s;
2008     int	    len;
2009 {
2010     struct utsname vutsname;
2011 
2012     if (uname(&vutsname) < 0)
2013 	*s = NUL;
2014     else
2015 	STRNCPY(s, vutsname.nodename, len);
2016     s[len - 1] = NUL;	/* make sure it's terminated */
2017 }
2018 #else /* HAVE_SYS_UTSNAME_H */
2019 
2020 # ifdef HAVE_SYS_SYSTEMINFO_H
2021 #  define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len)
2022 # endif
2023 
2024     void
2025 mch_get_host_name(s, len)
2026     char_u  *s;
2027     int	    len;
2028 {
2029 # ifdef VAXC
2030     vaxc$gethostname((char *)s, len);
2031 # else
2032     gethostname((char *)s, len);
2033 # endif
2034     s[len - 1] = NUL;	/* make sure it's terminated */
2035 }
2036 #endif /* HAVE_SYS_UTSNAME_H */
2037 
2038 /*
2039  * return process ID
2040  */
2041     long
2042 mch_get_pid()
2043 {
2044     return (long)getpid();
2045 }
2046 
2047 #if !defined(HAVE_STRERROR) && defined(USE_GETCWD)
2048 static char *strerror __ARGS((int));
2049 
2050     static char *
2051 strerror(err)
2052     int err;
2053 {
2054     extern int	    sys_nerr;
2055     extern char	    *sys_errlist[];
2056     static char	    er[20];
2057 
2058     if (err > 0 && err < sys_nerr)
2059 	return (sys_errlist[err]);
2060     sprintf(er, "Error %d", err);
2061     return er;
2062 }
2063 #endif
2064 
2065 /*
2066  * Get name of current directory into buffer 'buf' of length 'len' bytes.
2067  * Return OK for success, FAIL for failure.
2068  */
2069     int
2070 mch_dirname(buf, len)
2071     char_u  *buf;
2072     int	    len;
2073 {
2074 #if defined(USE_GETCWD)
2075     if (getcwd((char *)buf, len) == NULL)
2076     {
2077 	STRCPY(buf, strerror(errno));
2078 	return FAIL;
2079     }
2080     return OK;
2081 #else
2082     return (getwd((char *)buf) != NULL ? OK : FAIL);
2083 #endif
2084 }
2085 
2086 #if defined(OS2) || defined(PROTO)
2087 /*
2088  * Replace all slashes by backslashes.
2089  * When 'shellslash' set do it the other way around.
2090  */
2091     void
2092 slash_adjust(p)
2093     char_u  *p;
2094 {
2095     while (*p)
2096     {
2097 	if (*p == psepcN)
2098 	    *p = psepc;
2099 #ifdef FEAT_MBYTE
2100 	if (has_mbyte)
2101 	    p += (*mb_ptr2len_check)(p);
2102 	else
2103 #endif
2104 	    ++p;
2105     }
2106 }
2107 #endif
2108 
2109 /*
2110  * Get absolute file name into buffer 'buf' of length 'len' bytes.
2111  *
2112  * return FAIL for failure, OK for success
2113  */
2114     int
2115 mch_FullName(fname, buf, len, force)
2116     char_u	*fname, *buf;
2117     int		len;
2118     int		force;		/* also expand when already absolute path */
2119 {
2120     int		l;
2121 #ifdef OS2
2122     int		only_drive;	/* file name is only a drive letter */
2123 #endif
2124 #ifdef HAVE_FCHDIR
2125     int		fd = -1;
2126     static int	dont_fchdir = FALSE;	/* TRUE when fchdir() doesn't work */
2127 #endif
2128     char_u	olddir[MAXPATHL];
2129     char_u	*p;
2130     int		retval = OK;
2131 
2132 #ifdef VMS
2133     fname = vms_fixfilename(fname);
2134 #endif
2135 
2136     /* expand it if forced or not an absolute path */
2137     if (force || !mch_isFullName(fname))
2138     {
2139 	/*
2140 	 * If the file name has a path, change to that directory for a moment,
2141 	 * and then do the getwd() (and get back to where we were).
2142 	 * This will get the correct path name with "../" things.
2143 	 */
2144 #ifdef OS2
2145 	only_drive = 0;
2146 	if (((p = vim_strrchr(fname, '/')) != NULL)
2147 		|| ((p = vim_strrchr(fname, '\\')) != NULL)
2148 		|| (((p = vim_strchr(fname,  ':')) != NULL) && ++only_drive))
2149 #else
2150 	if ((p = vim_strrchr(fname, '/')) != NULL)
2151 #endif
2152 	{
2153 #ifdef HAVE_FCHDIR
2154 	    /*
2155 	     * Use fchdir() if possible, it's said to be faster and more
2156 	     * reliable.  But on SunOS 4 it might not work.  Check this by
2157 	     * doing a fchdir() right now.
2158 	     */
2159 	    if (!dont_fchdir)
2160 	    {
2161 		fd = open(".", O_RDONLY | O_EXTRA, 0);
2162 		if (fd >= 0 && fchdir(fd) < 0)
2163 		{
2164 		    close(fd);
2165 		    fd = -1;
2166 		    dont_fchdir = TRUE;	    /* don't try again */
2167 		}
2168 	    }
2169 #endif
2170 
2171 	    /* Only change directory when we are sure we can return to where
2172 	     * we are now.  After doing "su" chdir(".") might not work. */
2173 	    if (
2174 #ifdef HAVE_FCHDIR
2175 		fd < 0 &&
2176 #endif
2177 			(mch_dirname(olddir, MAXPATHL) == FAIL
2178 					   || mch_chdir((char *)olddir) != 0))
2179 	    {
2180 		p = NULL;	/* can't get current dir: don't chdir */
2181 		retval = FAIL;
2182 	    }
2183 	    else
2184 	    {
2185 #ifdef OS2
2186 		/*
2187 		 * compensate for case where ':' from "D:" was the only
2188 		 * path separator detected in the file name; the _next_
2189 		 * character has to be removed, and then restored later.
2190 		 */
2191 		if (only_drive)
2192 		    p++;
2193 #endif
2194 		/* The directory is copied into buf[], to be able to remove
2195 		 * the file name without changing it (could be a string in
2196 		 * read-only memory) */
2197 		if (p - fname >= len)
2198 		    retval = FAIL;
2199 		else
2200 		{
2201 		    STRNCPY(buf, fname, p - fname);
2202 		    buf[p - fname] = NUL;
2203 		    if (mch_chdir((char *)buf))
2204 			retval = FAIL;
2205 		    else
2206 			fname = p + 1;
2207 		    *buf = NUL;
2208 		}
2209 #ifdef OS2
2210 		if (only_drive)
2211 		{
2212 		    p--;
2213 		    if (retval != FAIL)
2214 			fname--;
2215 		}
2216 #endif
2217 	    }
2218 	}
2219 	if (mch_dirname(buf, len) == FAIL)
2220 	{
2221 	    retval = FAIL;
2222 	    *buf = NUL;
2223 	}
2224 	if (p != NULL)
2225 	{
2226 #ifdef HAVE_FCHDIR
2227 	    if (fd >= 0)
2228 	    {
2229 		l = fchdir(fd);
2230 		close(fd);
2231 	    }
2232 	    else
2233 #endif
2234 		l = mch_chdir((char *)olddir);
2235 	    if (l != 0)
2236 		EMSG(_(e_prev_dir));
2237 	}
2238 
2239 	l = STRLEN(buf);
2240 	if (l >= len)
2241 	    retval = FAIL;
2242 #ifndef VMS
2243 	else
2244 	{
2245 	    if (l > 0 && buf[l - 1] != '/' && *fname != NUL
2246 						   && STRCMP(fname, ".") != 0)
2247 		STRCAT(buf, "/");
2248 	}
2249 #endif
2250     }
2251     /* Catch file names which are too long. */
2252     if (retval == FAIL || STRLEN(buf) + STRLEN(fname) >= len)
2253 	return FAIL;
2254 
2255     /* Do not append ".", "/dir/." is equal to "/dir". */
2256     if (STRCMP(fname, ".") != 0)
2257 	STRCAT(buf, fname);
2258 
2259     return OK;
2260 }
2261 
2262 /*
2263  * Return TRUE if "fname" does not depend on the current directory.
2264  */
2265     int
2266 mch_isFullName(fname)
2267     char_u	*fname;
2268 {
2269 #ifdef __EMX__
2270     return _fnisabs(fname);
2271 #else
2272 # ifdef VMS
2273     return ( fname[0] == '/'	       || fname[0] == '.'	    ||
2274 	     strchr((char *)fname,':') || strchr((char *)fname,'"') ||
2275 	    (strchr((char *)fname,'[') && strchr((char *)fname,']'))||
2276 	    (strchr((char *)fname,'<') && strchr((char *)fname,'>'))   );
2277 # else
2278     return (*fname == '/' || *fname == '~');
2279 # endif
2280 #endif
2281 }
2282 
2283 /*
2284  * Get file permissions for 'name'.
2285  * Returns -1 when it doesn't exist.
2286  */
2287     long
2288 mch_getperm(name)
2289     char_u *name;
2290 {
2291     struct stat statb;
2292 
2293     /* Keep the #ifdef outside of stat(), it may be a macro. */
2294 #ifdef VMS
2295     if (stat((char *)vms_fixfilename(name), &statb))
2296 #else
2297     if (stat((char *)name, &statb))
2298 #endif
2299 	return -1;
2300     return statb.st_mode;
2301 }
2302 
2303 /*
2304  * set file permission for 'name' to 'perm'
2305  *
2306  * return FAIL for failure, OK otherwise
2307  */
2308     int
2309 mch_setperm(name, perm)
2310     char_u  *name;
2311     long    perm;
2312 {
2313     return (chmod((char *)
2314 #ifdef VMS
2315 		    vms_fixfilename(name),
2316 #else
2317 		    name,
2318 #endif
2319 		    (mode_t)perm) == 0 ? OK : FAIL);
2320 }
2321 
2322 #if defined(HAVE_ACL) || defined(PROTO)
2323 # ifdef HAVE_SYS_ACL_H
2324 #  include <sys/acl.h>
2325 # endif
2326 # ifdef HAVE_SYS_ACCESS_H
2327 #  include <sys/access.h>
2328 # endif
2329 
2330 # ifdef HAVE_SOLARIS_ACL
2331 typedef struct vim_acl_solaris_T {
2332     int acl_cnt;
2333     aclent_t *acl_entry;
2334 } vim_acl_solaris_T;
2335 # endif
2336 
2337 /*
2338  * Return a pointer to the ACL of file "fname" in allocated memory.
2339  * Return NULL if the ACL is not available for whatever reason.
2340  */
2341     vim_acl_T
2342 mch_get_acl(fname)
2343     char_u	*fname;
2344 {
2345     vim_acl_T	ret = NULL;
2346 #ifdef HAVE_POSIX_ACL
2347     ret = (vim_acl_T)acl_get_file((char *)fname, ACL_TYPE_ACCESS);
2348 #else
2349 #ifdef HAVE_SOLARIS_ACL
2350     vim_acl_solaris_T   *aclent;
2351 
2352     aclent = malloc(sizeof(vim_acl_solaris_T));
2353     if ((aclent->acl_cnt = acl((char *)fname, GETACLCNT, 0, NULL)) < 0)
2354     {
2355 	free(aclent);
2356 	return NULL;
2357     }
2358     aclent->acl_entry = malloc(aclent->acl_cnt * sizeof(aclent_t));
2359     if (acl((char *)fname, GETACL, aclent->acl_cnt, aclent->acl_entry) < 0)
2360     {
2361 	free(aclent->acl_entry);
2362 	free(aclent);
2363 	return NULL;
2364     }
2365     ret = (vim_acl_T)aclent;
2366 #else
2367 #if defined(HAVE_AIX_ACL)
2368     int		aclsize;
2369     struct acl *aclent;
2370 
2371     aclsize = sizeof(struct acl);
2372     aclent = malloc(aclsize);
2373     if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
2374     {
2375 	if (errno == ENOSPC)
2376 	{
2377 	    aclsize = aclent->acl_len;
2378 	    aclent = realloc(aclent, aclsize);
2379 	    if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
2380 	    {
2381 		free(aclent);
2382 		return NULL;
2383 	    }
2384 	}
2385 	else
2386 	{
2387 	    free(aclent);
2388 	    return NULL;
2389 	}
2390     }
2391     ret = (vim_acl_T)aclent;
2392 #endif /* HAVE_AIX_ACL */
2393 #endif /* HAVE_SOLARIS_ACL */
2394 #endif /* HAVE_POSIX_ACL */
2395     return ret;
2396 }
2397 
2398 /*
2399  * Set the ACL of file "fname" to "acl" (unless it's NULL).
2400  */
2401     void
2402 mch_set_acl(fname, aclent)
2403     char_u	*fname;
2404     vim_acl_T	aclent;
2405 {
2406     if (aclent == NULL)
2407 	return;
2408 #ifdef HAVE_POSIX_ACL
2409     acl_set_file((char *)fname, ACL_TYPE_ACCESS, (acl_t)aclent);
2410 #else
2411 #ifdef HAVE_SOLARIS_ACL
2412     acl((char *)fname, SETACL, ((vim_acl_solaris_T *)aclent)->acl_cnt,
2413 	    ((vim_acl_solaris_T *)aclent)->acl_entry);
2414 #else
2415 #ifdef HAVE_AIX_ACL
2416     chacl((char *)fname, aclent, ((struct acl *)aclent)->acl_len);
2417 #endif /* HAVE_AIX_ACL */
2418 #endif /* HAVE_SOLARIS_ACL */
2419 #endif /* HAVE_POSIX_ACL */
2420 }
2421 
2422     void
2423 mch_free_acl(aclent)
2424     vim_acl_T	aclent;
2425 {
2426     if (aclent == NULL)
2427 	return;
2428 #ifdef HAVE_POSIX_ACL
2429     acl_free((acl_t)aclent);
2430 #else
2431 #ifdef HAVE_SOLARIS_ACL
2432     free(((vim_acl_solaris_T *)aclent)->acl_entry);
2433     free(aclent);
2434 #else
2435 #ifdef HAVE_AIX_ACL
2436     free(aclent);
2437 #endif /* HAVE_AIX_ACL */
2438 #endif /* HAVE_SOLARIS_ACL */
2439 #endif /* HAVE_POSIX_ACL */
2440 }
2441 #endif
2442 
2443 /*
2444  * Set hidden flag for "name".
2445  */
2446 /* ARGSUSED */
2447     void
2448 mch_hide(name)
2449     char_u	*name;
2450 {
2451     /* can't hide a file */
2452 }
2453 
2454 /*
2455  * return TRUE if "name" is a directory
2456  * return FALSE if "name" is not a directory
2457  * return FALSE for error
2458  */
2459     int
2460 mch_isdir(name)
2461     char_u *name;
2462 {
2463     struct stat statb;
2464 
2465     if (*name == NUL)	    /* Some stat()s don't flag "" as an error. */
2466 	return FALSE;
2467     if (stat((char *)name, &statb))
2468 	return FALSE;
2469 #ifdef _POSIX_SOURCE
2470     return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
2471 #else
2472     return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
2473 #endif
2474 }
2475 
2476 #if defined(FEAT_EVAL) || defined(PROTO)
2477 
2478 static int executable_file __ARGS((char_u *name));
2479 
2480 /*
2481  * Return 1 if "name" is an executable file, 0 if not or it doesn't exist.
2482  */
2483     static int
2484 executable_file(name)
2485     char_u	*name;
2486 {
2487     struct stat	st;
2488 
2489     if (stat((char *)name, &st))
2490 	return 0;
2491     return S_ISREG(st.st_mode) && mch_access((char *)name, X_OK) == 0;
2492 }
2493 
2494 /*
2495  * Return 1 if "name" can be found in $PATH and executed, 0 if not.
2496  * Return -1 if unknown.
2497  */
2498     int
2499 mch_can_exe(name)
2500     char_u	*name;
2501 {
2502     char_u	*buf;
2503     char_u	*p, *e;
2504     int		retval;
2505 
2506     /* If it's an absolute or relative path don't need to use $PATH. */
2507     if (mch_isFullName(name) || (name[0] == '.' && (name[1] == '/'
2508 				      || (name[1] == '.' && name[2] == '/'))))
2509 	return executable_file(name);
2510 
2511     p = (char_u *)getenv("PATH");
2512     if (p == NULL || *p == NUL)
2513 	return -1;
2514     buf = alloc((unsigned)(STRLEN(name) + STRLEN(p) + 2));
2515     if (buf == NULL)
2516 	return -1;
2517 
2518     /*
2519      * Walk through all entries in $PATH to check if "name" exists there and
2520      * is an executable file.
2521      */
2522     for (;;)
2523     {
2524 	e = (char_u *)strchr((char *)p, ':');
2525 	if (e == NULL)
2526 	    e = p + STRLEN(p);
2527 	if (e - p <= 1)		/* empty entry means current dir */
2528 	    STRCPY(buf, "./");
2529 	else
2530 	{
2531 	    STRNCPY(buf, p, e - p);
2532 	    buf[e - p] = NUL;
2533 	    add_pathsep(buf);
2534 	}
2535 	STRCAT(buf, name);
2536 	retval = executable_file(buf);
2537 	if (retval == 1)
2538 	    break;
2539 
2540 	if (*e != ':')
2541 	    break;
2542 	p = e + 1;
2543     }
2544 
2545     vim_free(buf);
2546     return retval;
2547 }
2548 #endif
2549 
2550 /*
2551  * Check what "name" is:
2552  * NODE_NORMAL: file or directory (or doesn't exist)
2553  * NODE_WRITABLE: writable device, socket, fifo, etc.
2554  * NODE_OTHER: non-writable things
2555  */
2556     int
2557 mch_nodetype(name)
2558     char_u	*name;
2559 {
2560     struct stat	st;
2561 
2562     if (stat((char *)name, &st))
2563 	return NODE_NORMAL;
2564     if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
2565 	return NODE_NORMAL;
2566 #ifndef OS2
2567     if (S_ISBLK(st.st_mode))	/* block device isn't writable */
2568 	return NODE_OTHER;
2569 #endif
2570     /* Everything else is writable? */
2571     return NODE_WRITABLE;
2572 }
2573 
2574     void
2575 mch_early_init()
2576 {
2577 #ifdef HAVE_CHECK_STACK_GROWTH
2578     int			i;
2579 #endif
2580 
2581 #ifdef HAVE_CHECK_STACK_GROWTH
2582     check_stack_growth((char *)&i);
2583 
2584 # ifdef HAVE_GETRLIMIT
2585     get_stack_limit();
2586 # endif
2587 
2588 #endif
2589 
2590     /*
2591      * Setup an alternative stack for signals.  Helps to catch signals when
2592      * running out of stack space.
2593      * Use of sigaltstack() is preferred, it's more portable.
2594      * Ignore any errors.
2595      */
2596 #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
2597     signal_stack = malloc(SIGSTKSZ);
2598     init_signal_stack();
2599 #endif
2600 }
2601 
2602 static void exit_scroll __ARGS((void));
2603 
2604 /*
2605  * Output a newline when exiting.
2606  * Make sure the newline goes to the same stream as the text.
2607  */
2608     static void
2609 exit_scroll()
2610 {
2611     if (newline_on_exit || msg_didout)
2612     {
2613 	if (msg_use_printf())
2614 	{
2615 	    if (info_message)
2616 		mch_msg("\n");
2617 	    else
2618 		mch_errmsg("\r\n");
2619 	}
2620 	else
2621 	    out_char('\n');
2622     }
2623     else
2624     {
2625 	restore_cterm_colors();		/* get original colors back */
2626 	msg_clr_eos_force();		/* clear the rest of the display */
2627 	windgoto((int)Rows - 1, 0);	/* may have moved the cursor */
2628     }
2629 }
2630 
2631     void
2632 mch_exit(r)
2633     int r;
2634 {
2635     exiting = TRUE;
2636 
2637 #if defined(FEAT_X11) && defined(FEAT_CLIPBOARD)
2638     x11_export_final_selection();
2639 #endif
2640 
2641 #ifdef FEAT_GUI
2642     if (!gui.in_use)
2643 #endif
2644     {
2645 	settmode(TMODE_COOK);
2646 #ifdef FEAT_TITLE
2647 	mch_restore_title(3);	/* restore xterm title and icon name */
2648 #endif
2649 	/*
2650 	 * When t_ti is not empty but it doesn't cause swapping terminal
2651 	 * pages, need to output a newline when msg_didout is set.  But when
2652 	 * t_ti does swap pages it should not go to the shell page.  Do this
2653 	 * before stoptermcap().
2654 	 */
2655 	if (swapping_screen() && !newline_on_exit)
2656 	    exit_scroll();
2657 
2658 	/* Stop termcap: May need to check for T_CRV response, which
2659 	 * requires RAW mode. */
2660 	stoptermcap();
2661 
2662 	/*
2663 	 * A newline is only required after a message in the alternate screen.
2664 	 * This is set to TRUE by wait_return().
2665 	 */
2666 	if (!swapping_screen() || newline_on_exit)
2667 	    exit_scroll();
2668 
2669 	/* Cursor may have been switched off without calling starttermcap()
2670 	 * when doing "vim -u vimrc" and vimrc contains ":q". */
2671 	if (full_screen)
2672 	    cursor_on();
2673     }
2674     out_flush();
2675     ml_close_all(TRUE);		/* remove all memfiles */
2676     may_core_dump();
2677 #ifdef FEAT_GUI
2678 # ifndef FEAT_GUI_BEOS		/* BeOS always has GUI */
2679     if (gui.in_use)
2680 # endif
2681 	gui_exit(r);
2682 #endif
2683 #ifdef __QNX__
2684     /* A core dump won't be created if the signal handler
2685      * doesn't return, so we can't call exit() */
2686     if (deadly_signal != 0)
2687 	return;
2688 #endif
2689 
2690     exit(r);
2691 }
2692 
2693     static void
2694 may_core_dump()
2695 {
2696     if (deadly_signal != 0)
2697     {
2698 	signal(deadly_signal, SIG_DFL);
2699 	kill(getpid(), deadly_signal);	/* Die using the signal we caught */
2700     }
2701 }
2702 
2703 #ifndef VMS
2704 
2705     void
2706 mch_settmode(tmode)
2707     int		tmode;
2708 {
2709     static int first = TRUE;
2710 
2711     /* Why is NeXT excluded here (and not in os_unixx.h)? */
2712 #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
2713     /*
2714      * for "new" tty systems
2715      */
2716 # ifdef HAVE_TERMIOS_H
2717     static struct termios told;
2718 	   struct termios tnew;
2719 # else
2720     static struct termio told;
2721 	   struct termio tnew;
2722 # endif
2723 
2724     if (first)
2725     {
2726 	first = FALSE;
2727 # if defined(HAVE_TERMIOS_H)
2728 	tcgetattr(read_cmd_fd, &told);
2729 # else
2730 	ioctl(read_cmd_fd, TCGETA, &told);
2731 # endif
2732     }
2733 
2734     tnew = told;
2735     if (tmode == TMODE_RAW)
2736     {
2737 	/*
2738 	 * ~ICRNL enables typing ^V^M
2739 	 */
2740 	tnew.c_iflag &= ~ICRNL;
2741 	tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
2742 # if defined(IEXTEN) && !defined(__MINT__)
2743 		    | IEXTEN	    /* IEXTEN enables typing ^V on SOLARIS */
2744 				    /* but it breaks function keys on MINT */
2745 # endif
2746 				);
2747 # ifdef ONLCR	    /* don't map NL -> CR NL, we do it ourselves */
2748 	tnew.c_oflag &= ~ONLCR;
2749 # endif
2750 	tnew.c_cc[VMIN] = 1;		/* return after 1 char */
2751 	tnew.c_cc[VTIME] = 0;		/* don't wait */
2752     }
2753     else if (tmode == TMODE_SLEEP)
2754 	tnew.c_lflag &= ~(ECHO);
2755 
2756 # if defined(HAVE_TERMIOS_H)
2757     {
2758 	int	n = 10;
2759 
2760 	/* A signal may cause tcsetattr() to fail (e.g., SIGCONT).  Retry a
2761 	 * few times. */
2762 	while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
2763 						   && errno == EINTR && n > 0)
2764 	    --n;
2765     }
2766 # else
2767     ioctl(read_cmd_fd, TCSETA, &tnew);
2768 # endif
2769 
2770 #else
2771 
2772     /*
2773      * for "old" tty systems
2774      */
2775 # ifndef TIOCSETN
2776 #  define TIOCSETN TIOCSETP	/* for hpux 9.0 */
2777 # endif
2778     static struct sgttyb ttybold;
2779 	   struct sgttyb ttybnew;
2780 
2781     if (first)
2782     {
2783 	first = FALSE;
2784 	ioctl(read_cmd_fd, TIOCGETP, &ttybold);
2785     }
2786 
2787     ttybnew = ttybold;
2788     if (tmode == TMODE_RAW)
2789     {
2790 	ttybnew.sg_flags &= ~(CRMOD | ECHO);
2791 	ttybnew.sg_flags |= RAW;
2792     }
2793     else if (tmode == TMODE_SLEEP)
2794 	ttybnew.sg_flags &= ~(ECHO);
2795     ioctl(read_cmd_fd, TIOCSETN, &ttybnew);
2796 #endif
2797     curr_tmode = tmode;
2798 }
2799 
2800 /*
2801  * Try to get the code for "t_kb" from the stty setting
2802  *
2803  * Even if termcap claims a backspace key, the user's setting *should*
2804  * prevail.  stty knows more about reality than termcap does, and if
2805  * somebody's usual erase key is DEL (which, for most BSD users, it will
2806  * be), they're going to get really annoyed if their erase key starts
2807  * doing forward deletes for no reason. (Eric Fischer)
2808  */
2809     void
2810 get_stty()
2811 {
2812     char_u  buf[2];
2813     char_u  *p;
2814 
2815     /* Why is NeXT excluded here (and not in os_unixx.h)? */
2816 #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
2817     /* for "new" tty systems */
2818 # ifdef HAVE_TERMIOS_H
2819     struct termios keys;
2820 # else
2821     struct termio keys;
2822 # endif
2823 
2824 # if defined(HAVE_TERMIOS_H)
2825     if (tcgetattr(read_cmd_fd, &keys) != -1)
2826 # else
2827     if (ioctl(read_cmd_fd, TCGETA, &keys) != -1)
2828 # endif
2829     {
2830 	buf[0] = keys.c_cc[VERASE];
2831 	intr_char = keys.c_cc[VINTR];
2832 #else
2833     /* for "old" tty systems */
2834     struct sgttyb keys;
2835 
2836     if (ioctl(read_cmd_fd, TIOCGETP, &keys) != -1)
2837     {
2838 	buf[0] = keys.sg_erase;
2839 	intr_char = keys.sg_kill;
2840 #endif
2841 	buf[1] = NUL;
2842 	add_termcode((char_u *)"kb", buf, FALSE);
2843 
2844 	/*
2845 	 * If <BS> and <DEL> are now the same, redefine <DEL>.
2846 	 */
2847 	p = find_termcode((char_u *)"kD");
2848 	if (p != NULL && p[0] == buf[0] && p[1] == buf[1])
2849 	    do_fixdel(NULL);
2850     }
2851 #if 0
2852     }	    /* to keep cindent happy */
2853 #endif
2854 }
2855 
2856 #endif /* VMS  */
2857 
2858 #if defined(FEAT_MOUSE_TTY) || defined(PROTO)
2859 /*
2860  * Set mouse clicks on or off.
2861  */
2862     void
2863 mch_setmouse(on)
2864     int		on;
2865 {
2866     static int	ison = FALSE;
2867     int		xterm_mouse_vers;
2868 
2869     if (on == ison)	/* return quickly if nothing to do */
2870 	return;
2871 
2872     xterm_mouse_vers = use_xterm_mouse();
2873     if (xterm_mouse_vers > 0)
2874     {
2875 	if (on)	/* enable mouse events, use mouse tracking if available */
2876 	    out_str_nf((char_u *)
2877 		       (xterm_mouse_vers > 1
2878 			? IF_EB("\033[?1002h", ESC_STR "[?1002h")
2879 			: IF_EB("\033[?1000h", ESC_STR "[?1000h")));
2880 	else	/* disable mouse events, could probably always send the same */
2881 	    out_str_nf((char_u *)
2882 		       (xterm_mouse_vers > 1
2883 			? IF_EB("\033[?1002l", ESC_STR "[?1002l")
2884 			: IF_EB("\033[?1000l", ESC_STR "[?1000l")));
2885 	ison = on;
2886     }
2887 
2888 # ifdef FEAT_MOUSE_DEC
2889     else if (ttym_flags == TTYM_DEC)
2890     {
2891 	if (on)	/* enable mouse events */
2892 	    out_str_nf((char_u *)"\033[1;2'z\033[1;3'{");
2893 	else	/* disable mouse events */
2894 	    out_str_nf((char_u *)"\033['z");
2895 	ison = on;
2896     }
2897 # endif
2898 
2899 # ifdef FEAT_MOUSE_GPM
2900     else
2901     {
2902 	if (on)
2903 	{
2904 	    if (gpm_open())
2905 		ison = TRUE;
2906 	}
2907 	else
2908 	{
2909 	    gpm_close();
2910 	    ison = FALSE;
2911 	}
2912     }
2913 # endif
2914 
2915 # ifdef FEAT_MOUSE_JSB
2916     else
2917     {
2918 	if (on)
2919 	{
2920 	    /* D - Enable Mouse up/down messages
2921 	     * L - Enable Left Button Reporting
2922 	     * M - Enable Middle Button Reporting
2923 	     * R - Enable Right Button Reporting
2924 	     * K - Enable SHIFT and CTRL key Reporting
2925 	     * + - Enable Advanced messaging of mouse moves and up/down messages
2926 	     * Q - Quiet No Ack
2927 	     * # - Numeric value of mouse pointer required
2928 	     *	  0 = Multiview 2000 cursor, used as standard
2929 	     *	  1 = Windows Arrow
2930 	     *	  2 = Windows I Beam
2931 	     *	  3 = Windows Hour Glass
2932 	     *	  4 = Windows Cross Hair
2933 	     *	  5 = Windows UP Arrow
2934 	     */
2935 #ifdef JSBTERM_MOUSE_NONADVANCED /* Disables full feedback of pointer movements */
2936 	    out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK1Q\033\\",
2937 					 ESC_STR "[0~ZwLMRK1Q" ESC_STR "\\"));
2938 #else
2939 	    out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK+1Q\033\\",
2940 					ESC_STR "[0~ZwLMRK+1Q" ESC_STR "\\"));
2941 #endif
2942 	    ison = TRUE;
2943 	}
2944 	else
2945 	{
2946 	    out_str_nf((char_u *)IF_EB("\033[0~ZwQ\033\\",
2947 					      ESC_STR "[0~ZwQ" ESC_STR "\\"));
2948 	    ison = FALSE;
2949 	}
2950     }
2951 # endif
2952 # ifdef FEAT_MOUSE_PTERM
2953     else
2954     {
2955 	/* 1 = button press, 6 = release, 7 = drag, 1h...9l = right button */
2956 	if (on)
2957 	    out_str_nf("\033[>1h\033[>6h\033[>7h\033[>1h\033[>9l");
2958 	else
2959 	    out_str_nf("\033[>1l\033[>6l\033[>7l\033[>1l\033[>9h");
2960 	ison = on;
2961     }
2962 # endif
2963 }
2964 
2965 /*
2966  * Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
2967  */
2968     void
2969 check_mouse_termcode()
2970 {
2971 # ifdef FEAT_MOUSE_XTERM
2972     if (use_xterm_mouse()
2973 #  ifdef FEAT_GUI
2974 	    && !gui.in_use
2975 #  endif
2976 	    )
2977     {
2978 	set_mouse_termcode(KS_MOUSE, (char_u *)(term_is_8bit(T_NAME)
2979 		  ? IF_EB("\233M", CSI_STR "M") : IF_EB("\033[M", ESC_STR "[M")));
2980 	if (*p_mouse != NUL)
2981 	{
2982 	    /* force mouse off and maybe on to send possibly new mouse
2983 	     * activation sequence to the xterm, with(out) drag tracing. */
2984 	    mch_setmouse(FALSE);
2985 	    setmouse();
2986 	}
2987     }
2988     else
2989 	del_mouse_termcode(KS_MOUSE);
2990 # endif
2991 
2992 # ifdef FEAT_MOUSE_GPM
2993     if (!use_xterm_mouse()
2994 #  ifdef FEAT_GUI
2995 	    && !gui.in_use
2996 #  endif
2997 	    )
2998 	set_mouse_termcode(KS_MOUSE, (char_u *)IF_EB("\033MG", ESC_STR "MG"));
2999 # endif
3000 
3001 # ifdef FEAT_MOUSE_JSB
3002     /* conflicts with xterm mouse: "\033[" and "\033[M" ??? */
3003     if (!use_xterm_mouse()
3004 #  ifdef FEAT_GUI
3005 	    && !gui.in_use
3006 #  endif
3007 	    )
3008 	set_mouse_termcode(KS_JSBTERM_MOUSE,
3009 			       (char_u *)IF_EB("\033[0~zw", ESC_STR "[0~zw"));
3010     else
3011 	del_mouse_termcode(KS_JSBTERM_MOUSE);
3012 # endif
3013 
3014 # ifdef FEAT_MOUSE_NET
3015     /* There is no conflict, but one may type ESC } from Insert mode.  Don't
3016      * define it in the GUI or when using an xterm. */
3017     if (!use_xterm_mouse()
3018 #  ifdef FEAT_GUI
3019 	    && !gui.in_use
3020 #  endif
3021 	    )
3022 	set_mouse_termcode(KS_NETTERM_MOUSE,
3023 				       (char_u *)IF_EB("\033}", ESC_STR "}"));
3024     else
3025 	del_mouse_termcode(KS_NETTERM_MOUSE);
3026 # endif
3027 
3028 # ifdef FEAT_MOUSE_DEC
3029     /* conflicts with xterm mouse: "\033[" and "\033[M" */
3030     if (!use_xterm_mouse()
3031 #  ifdef FEAT_GUI
3032 	    && !gui.in_use
3033 #  endif
3034 	    )
3035 	set_mouse_termcode(KS_DEC_MOUSE,
3036 				       (char_u *)IF_EB("\033[", ESC_STR "["));
3037     else
3038 	del_mouse_termcode(KS_DEC_MOUSE);
3039 # endif
3040 # ifdef FEAT_MOUSE_PTERM
3041     /* same as the dec mouse */
3042     if (!use_xterm_mouse()
3043 #  ifdef FEAT_GUI
3044 	    && !gui.in_use
3045 #  endif
3046 	    )
3047 	set_mouse_termcode(KS_PTERM_MOUSE,
3048 				      (char_u *) IF_EB("\033[", ESC_STR "["));
3049     else
3050 	del_mouse_termcode(KS_PTERM_MOUSE);
3051 # endif
3052 }
3053 #endif
3054 
3055 /*
3056  * set screen mode, always fails.
3057  */
3058 /* ARGSUSED */
3059     int
3060 mch_screenmode(arg)
3061     char_u   *arg;
3062 {
3063     EMSG(_(e_screenmode));
3064     return FAIL;
3065 }
3066 
3067 #ifndef VMS
3068 
3069 /*
3070  * Try to get the current window size:
3071  * 1. with an ioctl(), most accurate method
3072  * 2. from the environment variables LINES and COLUMNS
3073  * 3. from the termcap
3074  * 4. keep using the old values
3075  * Return OK when size could be determined, FAIL otherwise.
3076  */
3077     int
3078 mch_get_shellsize()
3079 {
3080     long	rows = 0;
3081     long	columns = 0;
3082     char_u	*p;
3083 
3084     /*
3085      * For OS/2 use _scrsize().
3086      */
3087 # ifdef __EMX__
3088     {
3089 	int s[2];
3090 
3091 	_scrsize(s);
3092 	columns = s[0];
3093 	rows = s[1];
3094     }
3095 # endif
3096 
3097     /*
3098      * 1. try using an ioctl. It is the most accurate method.
3099      *
3100      * Try using TIOCGWINSZ first, some systems that have it also define
3101      * TIOCGSIZE but don't have a struct ttysize.
3102      */
3103 # ifdef TIOCGWINSZ
3104     {
3105 	struct winsize	ws;
3106 	int fd = 1;
3107 
3108 	/* When stdout is not a tty, use stdin for the ioctl(). */
3109 	if (!isatty(fd) && isatty(read_cmd_fd))
3110 	    fd = read_cmd_fd;
3111 	if (ioctl(fd, TIOCGWINSZ, &ws) == 0)
3112 	{
3113 	    columns = ws.ws_col;
3114 	    rows = ws.ws_row;
3115 	}
3116     }
3117 # else /* TIOCGWINSZ */
3118 #  ifdef TIOCGSIZE
3119     {
3120 	struct ttysize	ts;
3121 	int fd = 1;
3122 
3123 	/* When stdout is not a tty, use stdin for the ioctl(). */
3124 	if (!isatty(fd) && isatty(read_cmd_fd))
3125 	    fd = read_cmd_fd;
3126 	if (ioctl(fd, TIOCGSIZE, &ts) == 0)
3127 	{
3128 	    columns = ts.ts_cols;
3129 	    rows = ts.ts_lines;
3130 	}
3131     }
3132 #  endif /* TIOCGSIZE */
3133 # endif /* TIOCGWINSZ */
3134 
3135     /*
3136      * 2. get size from environment
3137      */
3138     if (columns == 0 || rows == 0)
3139     {
3140 	if ((p = (char_u *)getenv("LINES")))
3141 	    rows = atoi((char *)p);
3142 	if ((p = (char_u *)getenv("COLUMNS")))
3143 	    columns = atoi((char *)p);
3144     }
3145 
3146 #ifdef HAVE_TGETENT
3147     /*
3148      * 3. try reading "co" and "li" entries from termcap
3149      */
3150     if (columns == 0 || rows == 0)
3151 	getlinecol(&columns, &rows);
3152 #endif
3153 
3154     /*
3155      * 4. If everything fails, use the old values
3156      */
3157     if (columns <= 0 || rows <= 0)
3158 	return FAIL;
3159 
3160     Rows = rows;
3161     Columns = columns;
3162     return OK;
3163 }
3164 
3165 /*
3166  * Try to set the window size to Rows and Columns.
3167  */
3168     void
3169 mch_set_shellsize()
3170 {
3171     if (*T_CWS)
3172     {
3173 	/*
3174 	 * NOTE: if you get an error here that term_set_winsize() is
3175 	 * undefined, check the output of configure.  It could probably not
3176 	 * find a ncurses, termcap or termlib library.
3177 	 */
3178 	term_set_winsize((int)Rows, (int)Columns);
3179 	out_flush();
3180 	screen_start();			/* don't know where cursor is now */
3181     }
3182 }
3183 
3184 #endif /* VMS */
3185 
3186 /*
3187  * Rows and/or Columns has changed.
3188  */
3189     void
3190 mch_new_shellsize()
3191 {
3192     /* Nothing to do. */
3193 }
3194 
3195     int
3196 mch_call_shell(cmd, options)
3197     char_u	*cmd;
3198     int		options;	/* SHELL_*, see vim.h */
3199 {
3200 #ifdef VMS
3201     char	*ifn = NULL;
3202     char	*ofn = NULL;
3203 #endif
3204     int		tmode = cur_tmode;
3205 #ifdef USE_SYSTEM	/* use system() to start the shell: simple but slow */
3206     int	    x;
3207 # ifndef __EMX__
3208     char_u  *newcmd;   /* only needed for unix */
3209 # else
3210     /*
3211      * Set the preferred shell in the EMXSHELL environment variable (but
3212      * only if it is different from what is already in the environment).
3213      * Emx then takes care of whether to use "/c" or "-c" in an
3214      * intelligent way. Simply pass the whole thing to emx's system() call.
3215      * Emx also starts an interactive shell if system() is passed an empty
3216      * string.
3217      */
3218     char_u *p, *old;
3219 
3220     if (((old = (char_u *)getenv("EMXSHELL")) == NULL) || STRCMP(old, p_sh))
3221     {
3222 	/* should check HAVE_SETENV, but I know we don't have it. */
3223 	p = alloc(10 + strlen(p_sh));
3224 	if (p)
3225 	{
3226 	    sprintf((char *)p, "EMXSHELL=%s", p_sh);
3227 	    putenv((char *)p);	/* don't free the pointer! */
3228 	}
3229     }
3230 # endif
3231 
3232     out_flush();
3233 
3234     if (options & SHELL_COOKED)
3235 	settmode(TMODE_COOK);	    /* set to normal mode */
3236 
3237 # ifdef __EMX__
3238     if (cmd == NULL)
3239 	x = system("");	/* this starts an interactive shell in emx */
3240     else
3241 	x = system((char *)cmd);
3242     /* system() returns -1 when error occurs in starting shell */
3243     if (x == -1 && !emsg_silent)
3244     {
3245 	MSG_PUTS(_("\nCannot execute shell "));
3246 	msg_outtrans(p_sh);
3247 	msg_putchar('\n');
3248     }
3249 # else /* not __EMX__ */
3250     if (cmd == NULL)
3251 	x = system((char *)p_sh);
3252     else
3253     {
3254 #  ifdef VMS
3255 	if (ofn = strchr((char *)cmd, '>'))
3256 	    *ofn++ = '\0';
3257 	if (ifn = strchr((char *)cmd, '<'))
3258 	{
3259 	    char *p;
3260 
3261 	    *ifn++ = '\0';
3262 	    p = strchr(ifn,' '); /* chop off any trailing spaces */
3263 	    if (p)
3264 		*p = '\0';
3265 	}
3266 	if (ofn)
3267 	    x = vms_sys((char *)cmd, ofn, ifn);
3268 	else
3269 	    x = system((char *)cmd);
3270 #  else
3271 	newcmd = lalloc(STRLEN(p_sh)
3272 		+ (extra_shell_arg == NULL ? 0 : STRLEN(extra_shell_arg))
3273 		+ STRLEN(p_shcf) + STRLEN(cmd) + 4, TRUE);
3274 	if (newcmd == NULL)
3275 	    x = 0;
3276 	else
3277 	{
3278 	    sprintf((char *)newcmd, "%s %s %s %s", p_sh,
3279 		    extra_shell_arg == NULL ? "" : (char *)extra_shell_arg,
3280 		    (char *)p_shcf,
3281 		    (char *)cmd);
3282 	    x = system((char *)newcmd);
3283 	    vim_free(newcmd);
3284 	}
3285 #  endif
3286     }
3287 # ifdef VMS
3288     x = vms_sys_status(x);
3289 # endif
3290     if (emsg_silent)
3291 	;
3292     else if (x == 127)
3293 	MSG_PUTS(_("\nCannot execute shell sh\n"));
3294 # endif	/* __EMX__ */
3295     else if (x && !(options & SHELL_SILENT))
3296     {
3297 	MSG_PUTS(_("\nshell returned "));
3298 	msg_outnum((long)x);
3299 	msg_putchar('\n');
3300     }
3301 
3302     if (tmode == TMODE_RAW)
3303 	settmode(TMODE_RAW);	/* set to raw mode */
3304 # ifdef FEAT_TITLE
3305     resettitle();
3306 # endif
3307     return x;
3308 
3309 #else /* USE_SYSTEM */	    /* don't use system(), use fork()/exec() */
3310 
3311 #define EXEC_FAILED 122	    /* Exit code when shell didn't execute.  Don't use
3312 			       127, some shell use that already */
3313 
3314     char_u	*newcmd = NULL;
3315     pid_t	pid;
3316     pid_t	wait_pid = 0;
3317 # ifdef HAVE_UNION_WAIT
3318     union wait	status;
3319 # else
3320     int		status = -1;
3321 # endif
3322     int		retval = -1;
3323     char	**argv = NULL;
3324     int		argc;
3325     int		i;
3326     char_u	*p;
3327     int		inquote;
3328 # ifdef FEAT_GUI
3329     int		pty_master_fd = -1;	    /* for pty's */
3330     int		pty_slave_fd = -1;
3331     char	*tty_name;
3332     int		fd_toshell[2];	    /* for pipes */
3333     int		fd_fromshell[2];
3334     int		pipe_error = FALSE;
3335 #  ifdef HAVE_SETENV
3336     char	envbuf[50];
3337 #  else
3338     static char	envbuf_Rows[20];
3339     static char	envbuf_Columns[20];
3340 #  endif
3341 # endif
3342     int		did_settmode = FALSE; /* TRUE when settmode(TMODE_RAW) called */
3343 
3344     out_flush();
3345     if (options & SHELL_COOKED)
3346 	settmode(TMODE_COOK);		/* set to normal mode */
3347 
3348     /*
3349      * 1: find number of arguments
3350      * 2: separate them and built argv[]
3351      */
3352     newcmd = vim_strsave(p_sh);
3353     if (newcmd == NULL)		/* out of memory */
3354 	goto error;
3355     for (i = 0; i < 2; ++i)
3356     {
3357 	p = newcmd;
3358 	inquote = FALSE;
3359 	argc = 0;
3360 	for (;;)
3361 	{
3362 	    if (i == 1)
3363 		argv[argc] = (char *)p;
3364 	    ++argc;
3365 	    while (*p && (inquote || (*p != ' ' && *p != TAB)))
3366 	    {
3367 		if (*p == '"')
3368 		    inquote = !inquote;
3369 		++p;
3370 	    }
3371 	    if (*p == NUL)
3372 		break;
3373 	    if (i == 1)
3374 		*p++ = NUL;
3375 	    p = skipwhite(p);
3376 	}
3377 	if (i == 0)
3378 	{
3379 	    argv = (char **)alloc((unsigned)((argc + 4) * sizeof(char *)));
3380 	    if (argv == NULL)	    /* out of memory */
3381 		goto error;
3382 	}
3383     }
3384     if (cmd != NULL)
3385     {
3386 	if (extra_shell_arg != NULL)
3387 	    argv[argc++] = (char *)extra_shell_arg;
3388 	argv[argc++] = (char *)p_shcf;
3389 	argv[argc++] = (char *)cmd;
3390     }
3391     argv[argc] = NULL;
3392 
3393 # ifdef FEAT_GUI
3394     /*
3395      * For the GUI: Try using a pseudo-tty to get the stdin/stdout of the
3396      * executed command into the Vim window.  Or use a pipe.
3397      */
3398     if (gui.in_use && show_shell_mess)
3399     {
3400 	/*
3401 	 * Try to open a master pty.
3402 	 * If this works, open the slave pty.
3403 	 * If the slave can't be opened, close the master pty.
3404 	 */
3405 	if (p_guipty)
3406 	{
3407 	    pty_master_fd = OpenPTY(&tty_name);	    /* open pty */
3408 	    if (pty_master_fd >= 0 && ((pty_slave_fd =
3409 				    open(tty_name, O_RDWR | O_EXTRA, 0)) < 0))
3410 	    {
3411 		close(pty_master_fd);
3412 		pty_master_fd = -1;
3413 	    }
3414 	}
3415 	/*
3416 	 * If not opening a pty or it didn't work, try using pipes.
3417 	 */
3418 	if (pty_master_fd < 0)
3419 	{
3420 	    pipe_error = (pipe(fd_toshell) < 0);
3421 	    if (!pipe_error)			    /* pipe create OK */
3422 	    {
3423 		pipe_error = (pipe(fd_fromshell) < 0);
3424 		if (pipe_error)			    /* pipe create failed */
3425 		{
3426 		    close(fd_toshell[0]);
3427 		    close(fd_toshell[1]);
3428 		}
3429 	    }
3430 	    if (pipe_error)
3431 	    {
3432 		MSG_PUTS(_("\nCannot create pipes\n"));
3433 		out_flush();
3434 	    }
3435 	}
3436     }
3437 
3438     if (!pipe_error)			/* pty or pipe opened or not used */
3439 # endif
3440 
3441     {
3442 # ifdef __BEOS__
3443 	beos_cleanup_read_thread();
3444 # endif
3445 	if ((pid = fork()) == -1)	/* maybe we should use vfork() */
3446 	{
3447 	    MSG_PUTS(_("\nCannot fork\n"));
3448 # ifdef FEAT_GUI
3449 	    if (gui.in_use && show_shell_mess)
3450 	    {
3451 		if (pty_master_fd >= 0)		/* close the pseudo tty */
3452 		{
3453 		    close(pty_master_fd);
3454 		    close(pty_slave_fd);
3455 		}
3456 		else				/* close the pipes */
3457 		{
3458 		    close(fd_toshell[0]);
3459 		    close(fd_toshell[1]);
3460 		    close(fd_fromshell[0]);
3461 		    close(fd_fromshell[1]);
3462 		}
3463 	    }
3464 # endif
3465 	}
3466 	else if (pid == 0)	/* child */
3467 	{
3468 	    reset_signals();		/* handle signals normally */
3469 
3470 	    if (!show_shell_mess || (options & SHELL_EXPAND))
3471 	    {
3472 		int fd;
3473 
3474 		/*
3475 		 * Don't want to show any message from the shell.  Can't just
3476 		 * close stdout and stderr though, because some systems will
3477 		 * break if you try to write to them after that, so we must
3478 		 * use dup() to replace them with something else -- webb
3479 		 * Connect stdin to /dev/null too, so ":n `cat`" doesn't hang,
3480 		 * waiting for input.
3481 		 */
3482 		fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
3483 		fclose(stdin);
3484 		fclose(stdout);
3485 		fclose(stderr);
3486 
3487 		/*
3488 		 * If any of these open()'s and dup()'s fail, we just continue
3489 		 * anyway.  It's not fatal, and on most systems it will make
3490 		 * no difference at all.  On a few it will cause the execvp()
3491 		 * to exit with a non-zero status even when the completion
3492 		 * could be done, which is nothing too serious.  If the open()
3493 		 * or dup() failed we'd just do the same thing ourselves
3494 		 * anyway -- webb
3495 		 */
3496 		if (fd >= 0)
3497 		{
3498 		    dup(fd); /* To replace stdin  (file descriptor 0) */
3499 		    dup(fd); /* To replace stdout (file descriptor 1) */
3500 		    dup(fd); /* To replace stderr (file descriptor 2) */
3501 
3502 		    /* Don't need this now that we've duplicated it */
3503 		    close(fd);
3504 		}
3505 	    }
3506 # ifdef FEAT_GUI
3507 	    else if (gui.in_use)
3508 	    {
3509 
3510 #  ifdef HAVE_SETSID
3511 		(void)setsid();
3512 #  endif
3513 		/* push stream discipline modules */
3514 		if (options & SHELL_COOKED)
3515 		    SetupSlavePTY(pty_slave_fd);
3516 #  ifdef TIOCSCTTY
3517 		/* try to become controlling tty (probably doesn't work,
3518 		 * unless run by root) */
3519 		ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
3520 #  endif
3521 		/* Simulate to have a dumb terminal (for now) */
3522 #  ifdef HAVE_SETENV
3523 		setenv("TERM", "dumb", 1);
3524 		sprintf((char *)envbuf, "%ld", Rows);
3525 		setenv("ROWS", (char *)envbuf, 1);
3526 		sprintf((char *)envbuf, "%ld", Rows);
3527 		setenv("LINES", (char *)envbuf, 1);
3528 		sprintf((char *)envbuf, "%ld", Columns);
3529 		setenv("COLUMNS", (char *)envbuf, 1);
3530 #  else
3531 		/*
3532 		 * Putenv does not copy the string, it has to remain valid.
3533 		 * Use a static array to avoid loosing allocated memory.
3534 		 */
3535 		putenv("TERM=dumb");
3536 		sprintf(envbuf_Rows, "ROWS=%ld", Rows);
3537 		putenv(envbuf_Rows);
3538 		sprintf(envbuf_Rows, "LINES=%ld", Rows);
3539 		putenv(envbuf_Rows);
3540 		sprintf(envbuf_Columns, "COLUMNS=%ld", Columns);
3541 		putenv(envbuf_Columns);
3542 #  endif
3543 
3544 		if (pty_master_fd >= 0)
3545 		{
3546 		    close(pty_master_fd);   /* close master side of pty */
3547 
3548 		    /* set up stdin/stdout/stderr for the child */
3549 		    close(0);
3550 		    dup(pty_slave_fd);
3551 		    close(1);
3552 		    dup(pty_slave_fd);
3553 		    close(2);
3554 		    dup(pty_slave_fd);
3555 
3556 		    close(pty_slave_fd);    /* has been dupped, close it now */
3557 		}
3558 		else
3559 		{
3560 		    /* set up stdin for the child */
3561 		    close(fd_toshell[1]);
3562 		    close(0);
3563 		    dup(fd_toshell[0]);
3564 		    close(fd_toshell[0]);
3565 
3566 		    /* set up stdout for the child */
3567 		    close(fd_fromshell[0]);
3568 		    close(1);
3569 		    dup(fd_fromshell[1]);
3570 		    close(fd_fromshell[1]);
3571 
3572 		    /* set up stderr for the child */
3573 		    close(2);
3574 		    dup(1);
3575 		}
3576 	    }
3577 # endif /* FEAT_GUI */
3578 	    /*
3579 	     * There is no type cast for the argv, because the type may be
3580 	     * different on different machines. This may cause a warning
3581 	     * message with strict compilers, don't worry about it.
3582 	     * Call _exit() instead of exit() to avoid closing the connection
3583 	     * to the X server (esp. with GTK, which uses atexit()).
3584 	     */
3585 	    execvp(argv[0], argv);
3586 	    _exit(EXEC_FAILED);	    /* exec failed, return failure code */
3587 	}
3588 	else			/* parent */
3589 	{
3590 	    /*
3591 	     * While child is running, ignore terminating signals.
3592 	     */
3593 	    catch_signals(SIG_IGN, SIG_ERR);
3594 
3595 # ifdef FEAT_GUI
3596 
3597 	    /*
3598 	     * For the GUI we redirect stdin, stdout and stderr to our window.
3599 	     */
3600 	    if (gui.in_use && show_shell_mess)
3601 	    {
3602 #  define BUFLEN 100		/* length for buffer, pseudo tty limit is 128 */
3603 		char_u	    buffer[BUFLEN + 1];
3604 #  ifdef FEAT_MBYTE
3605 		int	    buffer_off = 0;	/* valid bytes in buffer[] */
3606 #  endif
3607 		char_u	    ta_buf[BUFLEN + 1];	/* TypeAHead */
3608 		int	    ta_len = 0;		/* valid bytes in ta_buf[] */
3609 		int	    len;
3610 		int	    p_more_save;
3611 		int	    old_State;
3612 		int	    c;
3613 		int	    toshell_fd;
3614 		int	    fromshell_fd;
3615 
3616 		if (pty_master_fd >= 0)
3617 		{
3618 		    close(pty_slave_fd);	/* close slave side of pty */
3619 		    fromshell_fd = pty_master_fd;
3620 		    toshell_fd = dup(pty_master_fd);
3621 		}
3622 		else
3623 		{
3624 		    close(fd_toshell[0]);
3625 		    close(fd_fromshell[1]);
3626 		    toshell_fd = fd_toshell[1];
3627 		    fromshell_fd = fd_fromshell[0];
3628 		}
3629 
3630 		/*
3631 		 * Write to the child if there are typed characters.
3632 		 * Read from the child if there are characters available.
3633 		 *   Repeat the reading a few times if more characters are
3634 		 *   available. Need to check for typed keys now and then, but
3635 		 *   not too often (delays when no chars are available).
3636 		 * This loop is quit if no characters can be read from the pty
3637 		 * (WaitForChar detected special condition), or there are no
3638 		 * characters available and the child has exited.
3639 		 * Only check if the child has exited when there is no more
3640 		 * output. The child may exit before all the output has
3641 		 * been printed.
3642 		 *
3643 		 * Currently this busy loops!
3644 		 * This can probably dead-lock when the write blocks!
3645 		 */
3646 		p_more_save = p_more;
3647 		p_more = FALSE;
3648 		old_State = State;
3649 		State = EXTERNCMD;	/* don't redraw at window resize */
3650 
3651 		for (;;)
3652 		{
3653 		    /*
3654 		     * Check if keys have been typed, write them to the child
3655 		     * if there are any.  Don't do this if we are expanding
3656 		     * wild cards (would eat typeahead).  Don't get extra
3657 		     * characters when we already have one.
3658 		     */
3659 		    len = 0;
3660 		    if (!(options & SHELL_EXPAND)
3661 			    && (ta_len > 0
3662 				|| (len = ui_inchar(ta_buf, BUFLEN, 10L,
3663 								     0)) > 0))
3664 		    {
3665 			/*
3666 			 * For pipes:
3667 			 * Check for CTRL-C: send interrupt signal to child.
3668 			 * Check for CTRL-D: EOF, close pipe to child.
3669 			 */
3670 			if (len == 1 && (pty_master_fd < 0 || cmd != NULL))
3671 			{
3672 #  ifdef SIGINT
3673 			    /*
3674 			     * Send SIGINT to the child's group or all
3675 			     * processes in our group.
3676 			     */
3677 			    if (ta_buf[ta_len] == Ctrl_C
3678 					       || ta_buf[ta_len] == intr_char)
3679 #   ifdef HAVE_SETSID
3680 				kill(-pid, SIGINT);
3681 #   else
3682 				kill(0, SIGINT);
3683 #   endif
3684 #  endif
3685 			    if (pty_master_fd < 0 && toshell_fd >= 0
3686 					       && ta_buf[ta_len] == Ctrl_D)
3687 			    {
3688 				close(toshell_fd);
3689 				toshell_fd = -1;
3690 			    }
3691 			}
3692 
3693 			/* replace K_BS by <BS> and K_DEL by <DEL> */
3694 			for (i = ta_len; i < ta_len + len; ++i)
3695 			{
3696 			    if (ta_buf[i] == CSI && len - i > 2)
3697 			    {
3698 				c = TERMCAP2KEY(ta_buf[i + 1], ta_buf[i + 2]);
3699 				if (c == K_DEL || c == K_KDEL || c == K_BS)
3700 				{
3701 				    mch_memmove(ta_buf + i + 1, ta_buf + i + 3,
3702 						       (size_t)(len - i - 2));
3703 				    if (c == K_DEL || c == K_KDEL)
3704 					ta_buf[i] = DEL;
3705 				    else
3706 					ta_buf[i] = Ctrl_H;
3707 				    len -= 2;
3708 				}
3709 			    }
3710 			    else if (ta_buf[i] == '\r')
3711 				ta_buf[i] = '\n';
3712 #  ifdef FEAT_MBYTE
3713 			    if (has_mbyte)
3714 				i += (*mb_ptr2len_check)(ta_buf + i) - 1;
3715 #  endif
3716 			}
3717 
3718 			/*
3719 			 * For pipes: echo the typed characters.
3720 			 * For a pty this does not seem to work.
3721 			 */
3722 			if (pty_master_fd < 0)
3723 			{
3724 			    for (i = ta_len; i < ta_len + len; ++i)
3725 			    {
3726 				if (ta_buf[i] == '\n' || ta_buf[i] == '\b')
3727 				    msg_putchar(ta_buf[i]);
3728 #  ifdef FEAT_MBYTE
3729 				else if (has_mbyte)
3730 				{
3731 				    int l = (*mb_ptr2len_check)(ta_buf + i);
3732 
3733 				    msg_outtrans_len(ta_buf + i, l);
3734 				    i += l - 1;
3735 				}
3736 #  endif
3737 				else
3738 				    msg_outtrans_len(ta_buf + i, 1);
3739 			    }
3740 			    windgoto(msg_row, msg_col);
3741 			    out_flush();
3742 			}
3743 
3744 			ta_len += len;
3745 
3746 			/*
3747 			 * Write the characters to the child, unless EOF has
3748 			 * been typed for pipes.  Write one character at a
3749 			 * time, to avoid loosing too much typeahead.
3750 			 */
3751 			if (toshell_fd >= 0)
3752 			{
3753 			    len = write(toshell_fd, (char *)ta_buf, (size_t)1);
3754 			    if (len > 0)
3755 			    {
3756 				ta_len -= len;
3757 				mch_memmove(ta_buf, ta_buf + len, ta_len);
3758 			    }
3759 			}
3760 		    }
3761 
3762 		    /*
3763 		     * Check if the child has any characters to be printed.
3764 		     * Read them and write them to our window.	Repeat this as
3765 		     * long as there is something to do, avoid the 10ms wait
3766 		     * for mch_inchar(), or sending typeahead characters to
3767 		     * the external process.
3768 		     * TODO: This should handle escape sequences, compatible
3769 		     * to some terminal (vt52?).
3770 		     */
3771 		    while (RealWaitForChar(fromshell_fd, 10L, NULL))
3772 		    {
3773 			len = read(fromshell_fd, (char *)buffer
3774 #  ifdef FEAT_MBYTE
3775 				+ buffer_off, (size_t)(BUFLEN - buffer_off)
3776 #  else
3777 				, (size_t)BUFLEN
3778 #  endif
3779 				);
3780 			if (len <= 0)		    /* end of file or error */
3781 			    goto finished;
3782 #  ifdef FEAT_MBYTE
3783 			len += buffer_off;
3784 			buffer[len] = NUL;
3785 			if (has_mbyte)
3786 			{
3787 			    int		l;
3788 
3789 			    /* Check if the last character in buffer[] is
3790 			     * incomplete, keep these bytes for the next
3791 			     * round. */
3792 			    for (p = buffer; p < buffer + len; p += l)
3793 			    {
3794 				if (enc_utf8)	/* exclude composing chars */
3795 				    l = utf_ptr2len_check(p);
3796 				else
3797 				    l = (*mb_ptr2len_check)(p);
3798 				if (l == 0)
3799 				    l = 1;  /* NUL byte? */
3800 				else if (MB_BYTE2LEN(*p) != l)
3801 				    break;
3802 			    }
3803 			    if (p == buffer)	/* no complete character */
3804 			    {
3805 				/* avoid getting stuck at an illegal byte */
3806 				if (len >= 12)
3807 				    ++p;
3808 				else
3809 				{
3810 				    buffer_off = len;
3811 				    continue;
3812 				}
3813 			    }
3814 			    c = *p;
3815 			    *p = NUL;
3816 			    msg_puts(buffer);
3817 			    if (p < buffer + len)
3818 			    {
3819 				*p = c;
3820 				buffer_off = (buffer + len) - p;
3821 				mch_memmove(buffer, p, buffer_off);
3822 				continue;
3823 			    }
3824 			    buffer_off = 0;
3825 			}
3826 			else
3827 #  endif /* FEAT_MBYTE */
3828 			{
3829 			    buffer[len] = NUL;
3830 			    msg_puts(buffer);
3831 			}
3832 
3833 			windgoto(msg_row, msg_col);
3834 			cursor_on();
3835 			out_flush();
3836 			if (got_int)
3837 			    break;
3838 		    }
3839 
3840 		    /*
3841 		     * Check if the child still exists, before checking for
3842 		     * typed characters (otherwise we would loose typeahead).
3843 		     */
3844 #  ifdef __NeXT__
3845 		    wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *) 0);
3846 #  else
3847 		    wait_pid = waitpid(pid, &status, WNOHANG);
3848 #  endif
3849 		    if ((wait_pid == (pid_t)-1 && errno == ECHILD)
3850 			    || (wait_pid == pid && WIFEXITED(status)))
3851 		    {
3852 			wait_pid = pid;
3853 			break;
3854 		    }
3855 		    wait_pid = 0;
3856 		}
3857 finished:
3858 		p_more = p_more_save;
3859 
3860 #  ifndef MACOS_X_UNIX /* TODO: Is it needed for MACOS_X ? */
3861 		/*
3862 		 * Give all typeahead that wasn't used back to ui_inchar().
3863 		 */
3864 		if (ta_len)
3865 		    ui_inchar_undo(ta_buf, ta_len);
3866 #  endif
3867 		State = old_State;
3868 		if (toshell_fd >= 0)
3869 		    close(toshell_fd);
3870 		close(fromshell_fd);
3871 	    }
3872 # endif /* FEAT_GUI */
3873 
3874 	    /*
3875 	     * Wait until our child has exited.
3876 	     * Ignore wait() returning pids of other children and returning
3877 	     * because of some signal like SIGWINCH.
3878 	     * Don't wait if wait_pid was already set above, indicating the
3879 	     * child already exited.
3880 	     */
3881 	    while (wait_pid != pid)
3882 	    {
3883 #ifdef _THREAD_SAFE
3884 		/* Ugly hack: when compiled with Python threads are probably
3885 		 * used, in which case wait() sometimes hangs for no obvious
3886 		 * reason.  Use waitpid() instead and loop (like the GUI). */
3887 #  ifdef __NeXT__
3888 		wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
3889 #  else
3890 		wait_pid = waitpid(pid, &status, WNOHANG);
3891 #  endif
3892 		if (wait_pid == 0)
3893 		{
3894 		    /* Wait for 1/100 sec before trying again. */
3895 		    mch_delay(10L, TRUE);
3896 		    continue;
3897 		}
3898 #else
3899 		wait_pid = wait(&status);
3900 #endif
3901 		if (wait_pid <= 0
3902 # ifdef ECHILD
3903 			&& errno == ECHILD
3904 # endif
3905 		   )
3906 		    break;
3907 	    }
3908 
3909 	    /*
3910 	     * Set to raw mode right now, otherwise a CTRL-C after
3911 	     * catch_signals() will kill Vim.
3912 	     */
3913 	    if (tmode == TMODE_RAW)
3914 		settmode(TMODE_RAW);
3915 	    did_settmode = TRUE;
3916 	    set_signals();
3917 
3918 	    if (WIFEXITED(status))
3919 	    {
3920 		retval = WEXITSTATUS(status);
3921 		if (retval && !emsg_silent)
3922 		{
3923 		    if (retval == EXEC_FAILED)
3924 		    {
3925 			MSG_PUTS(_("\nCannot execute shell "));
3926 			msg_outtrans(p_sh);
3927 			msg_putchar('\n');
3928 		    }
3929 		    else if (!(options & SHELL_SILENT))
3930 		    {
3931 			MSG_PUTS(_("\nshell returned "));
3932 			msg_outnum((long)retval);
3933 			msg_putchar('\n');
3934 		    }
3935 		}
3936 	    }
3937 	    else
3938 		MSG_PUTS(_("\nCommand terminated\n"));
3939 	}
3940     }
3941     vim_free(argv);
3942 
3943 error:
3944     if (!did_settmode)
3945 	if (tmode == TMODE_RAW)
3946 	    settmode(TMODE_RAW);	/* set to raw mode */
3947 # ifdef FEAT_TITLE
3948     resettitle();
3949 # endif
3950     vim_free(newcmd);
3951 
3952     return retval;
3953 
3954 #endif /* USE_SYSTEM */
3955 }
3956 
3957 /*
3958  * Check for CTRL-C typed by reading all available characters.
3959  * In cooked mode we should get SIGINT, no need to check.
3960  */
3961     void
3962 mch_breakcheck()
3963 {
3964     if (curr_tmode == TMODE_RAW && RealWaitForChar(read_cmd_fd, 0L, NULL))
3965 	fill_input_buf(FALSE);
3966 }
3967 
3968 /*
3969  * Wait "msec" msec until a character is available from the keyboard or from
3970  * inbuf[]. msec == -1 will block forever.
3971  * When a GUI is being used, this will never get called -- webb
3972  */
3973     static int
3974 WaitForChar(msec)
3975     long	msec;
3976 {
3977 #ifdef FEAT_MOUSE_GPM
3978     int		gpm_process_wanted;
3979 #endif
3980 #ifdef FEAT_XCLIPBOARD
3981     int		rest;
3982 #endif
3983     int		avail;
3984 
3985     if (input_available())	    /* something in inbuf[] */
3986 	return 1;
3987 
3988 #if defined(FEAT_MOUSE_DEC)
3989     /* May need to query the mouse position. */
3990     if (WantQueryMouse)
3991     {
3992 	WantQueryMouse = 0;
3993 	mch_write((char_u *)IF_EB("\033[1'|", ESC_STR "[1'|"), 5);
3994     }
3995 #endif
3996 
3997     /*
3998      * For FEAT_MOUSE_GPM and FEAT_XCLIPBOARD we loop here to process mouse
3999      * events.  This is a bit complicated, because they might both be defined.
4000      */
4001 #if defined(FEAT_MOUSE_GPM) || defined(FEAT_XCLIPBOARD)
4002 # ifdef FEAT_XCLIPBOARD
4003     rest = 0;
4004     if (do_xterm_trace())
4005 	rest = msec;
4006 # endif
4007     do
4008     {
4009 # ifdef FEAT_XCLIPBOARD
4010 	if (rest != 0)
4011 	{
4012 	    msec = XT_TRACE_DELAY;
4013 	    if (rest >= 0 && rest < XT_TRACE_DELAY)
4014 		msec = rest;
4015 	    if (rest >= 0)
4016 		rest -= msec;
4017 	}
4018 # endif
4019 # ifdef FEAT_MOUSE_GPM
4020 	gpm_process_wanted = 0;
4021 	avail = RealWaitForChar(read_cmd_fd, msec, &gpm_process_wanted);
4022 # else
4023 	avail = RealWaitForChar(read_cmd_fd, msec, NULL);
4024 # endif
4025 	if (!avail)
4026 	{
4027 	    if (input_available())
4028 		return 1;
4029 # ifdef FEAT_XCLIPBOARD
4030 	    if (rest == 0 || !do_xterm_trace())
4031 # endif
4032 		break;
4033 	}
4034     }
4035     while (FALSE
4036 # ifdef FEAT_MOUSE_GPM
4037 	   || (gpm_process_wanted && mch_gpm_process() == 0)
4038 # endif
4039 # ifdef FEAT_XCLIPBOARD
4040 	   || (!avail && rest != 0)
4041 # endif
4042 	  );
4043 
4044 #else
4045     avail = RealWaitForChar(read_cmd_fd, msec, NULL);
4046 #endif
4047     return avail;
4048 }
4049 
4050 /*
4051  * Wait "msec" msec until a character is available from file descriptor "fd".
4052  * Time == -1 will block forever.
4053  * When a GUI is being used, this will not be used for input -- webb
4054  * Returns also, when a request from Sniff is waiting -- toni.
4055  * Or when a Linux GPM mouse event is waiting.
4056  */
4057 /* ARGSUSED */
4058 #if defined(__BEOS__)
4059     int
4060 #else
4061     static  int
4062 #endif
4063 RealWaitForChar(fd, msec, check_for_gpm)
4064     int		fd;
4065     long	msec;
4066     int		*check_for_gpm;
4067 {
4068     int		ret;
4069 #if defined(FEAT_XCLIPBOARD) || defined(USE_XSMP)
4070     static int	busy = FALSE;
4071 
4072     /* May retry getting characters after an event was handled. */
4073 # define MAY_LOOP
4074 
4075 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
4076     /* Remember at what time we started, so that we know how much longer we
4077      * should wait after being interrupted. */
4078 #  define USE_START_TV
4079     struct timeval  start_tv;
4080 
4081     if (msec > 0 && (
4082 #  ifdef FEAT_XCLIPBOARD
4083 	    xterm_Shell != (Widget)0
4084 #   ifdef USE_XSMP
4085 	    ||
4086 #   endif
4087 #  endif
4088 #  ifdef USE_XSMP
4089 	    xsmp_icefd != -1
4090 #  endif
4091 	    ))
4092 	gettimeofday(&start_tv, NULL);
4093 # endif
4094 
4095     /* Handle being called recursively.  This may happen for the session
4096      * manager stuff, it may save the file, which does a breakcheck. */
4097     if (busy)
4098 	return 0;
4099 #endif
4100 
4101 #ifdef MAY_LOOP
4102     while (1)
4103 #endif
4104     {
4105 #ifdef MAY_LOOP
4106 	int		finished = TRUE; /* default is to 'loop' just once */
4107 #endif
4108 #ifndef HAVE_SELECT
4109 	struct pollfd   fds[5];
4110 	int		nfd;
4111 # ifdef FEAT_XCLIPBOARD
4112 	int		xterm_idx = -1;
4113 # endif
4114 # ifdef FEAT_MOUSE_GPM
4115 	int		gpm_idx = -1;
4116 # endif
4117 # ifdef USE_XSMP
4118 	int		xsmp_idx = -1;
4119 # endif
4120 
4121 	fds[0].fd = fd;
4122 	fds[0].events = POLLIN;
4123 	nfd = 1;
4124 
4125 # ifdef FEAT_SNIFF
4126 #  define SNIFF_IDX 1
4127 	if (want_sniff_request)
4128 	{
4129 	    fds[SNIFF_IDX].fd = fd_from_sniff;
4130 	    fds[SNIFF_IDX].events = POLLIN;
4131 	    nfd++;
4132 	}
4133 # endif
4134 # ifdef FEAT_XCLIPBOARD
4135 	if (xterm_Shell != (Widget)0)
4136 	{
4137 	    xterm_idx = nfd;
4138 	    fds[nfd].fd = ConnectionNumber(xterm_dpy);
4139 	    fds[nfd].events = POLLIN;
4140 	    nfd++;
4141 	}
4142 # endif
4143 # ifdef FEAT_MOUSE_GPM
4144 	if (check_for_gpm != NULL && gpm_flag && gpm_fd >= 0)
4145 	{
4146 	    gpm_idx = nfd;
4147 	    fds[nfd].fd = gpm_fd;
4148 	    fds[nfd].events = POLLIN;
4149 	    nfd++;
4150 	}
4151 # endif
4152 # ifdef USE_XSMP
4153 	if (xsmp_icefd != -1)
4154 	{
4155 	    xsmp_idx = nfd;
4156 	    fds[nfd].fd = xsmp_icefd;
4157 	    fds[nfd].events = POLLIN;
4158 	    nfd++;
4159 	}
4160 # endif
4161 
4162 	ret = poll(fds, nfd, (int)msec);
4163 
4164 # ifdef FEAT_SNIFF
4165 	if (ret < 0)
4166 	    sniff_disconnect(1);
4167 	else if (want_sniff_request)
4168 	{
4169 	    if (fds[SNIFF_IDX].revents & POLLHUP)
4170 		sniff_disconnect(1);
4171 	    if (fds[SNIFF_IDX].revents & POLLIN)
4172 		sniff_request_waiting = 1;
4173 	}
4174 # endif
4175 # ifdef FEAT_XCLIPBOARD
4176 	if (xterm_Shell != (Widget)0 && (fds[xterm_idx].revents & POLLIN))
4177 	{
4178 	    xterm_update();      /* Maybe we should hand out clipboard */
4179 	    if (--ret == 0 && !input_available())
4180 		/* Try again */
4181 		finished = FALSE;
4182 	}
4183 # endif
4184 # ifdef FEAT_MOUSE_GPM
4185 	if (gpm_idx >= 0 && (fds[gpm_idx].revents & POLLIN))
4186 	{
4187 	    *check_for_gpm = 1;
4188 	}
4189 # endif
4190 # ifdef USE_XSMP
4191 	if (xsmp_idx >= 0 && (fds[xsmp_idx].revents & (POLLIN | POLLHUP)))
4192 	{
4193 	    if (fds[xsmp_idx].revents & POLLIN)
4194 	    {
4195 		busy = TRUE;
4196 		xsmp_handle_requests();
4197 		busy = FALSE;
4198 	    }
4199 	    else if (fds[xsmp_idx].revents & POLLHUP)
4200 	    {
4201 		if (p_verbose > 0)
4202 		    MSG(_("XSMP lost ICE connection"));
4203 		xsmp_close();
4204 	    }
4205 	    if (--ret == 0)
4206 		/* Try again */
4207 		finished = FALSE;
4208 	}
4209 # endif
4210 
4211 
4212 #else /* HAVE_SELECT */
4213 
4214 	struct timeval  tv;
4215 	fd_set		rfds, efds;
4216 	int		maxfd;
4217 
4218 # ifdef __EMX__
4219 	/* don't check for incoming chars if not in raw mode, because select()
4220 	 * always returns TRUE then (in some version of emx.dll) */
4221 	if (curr_tmode != TMODE_RAW)
4222 	    return 0;
4223 # endif
4224 
4225 	if (msec >= 0)
4226 	{
4227 	    tv.tv_sec = msec / 1000;
4228 	    tv.tv_usec = (msec % 1000) * (1000000/1000);
4229 	}
4230 
4231 	/*
4232 	 * Select on ready for reading and exceptional condition (end of file).
4233 	 */
4234 	FD_ZERO(&rfds); /* calls bzero() on a sun */
4235 	FD_ZERO(&efds);
4236 	FD_SET(fd, &rfds);
4237 # if !defined(__QNX__) && !defined(__CYGWIN32__)
4238 	/* For QNX select() always returns 1 if this is set.  Why? */
4239 	FD_SET(fd, &efds);
4240 # endif
4241 	maxfd = fd;
4242 
4243 # ifdef FEAT_SNIFF
4244 	if (want_sniff_request)
4245 	{
4246 	    FD_SET(fd_from_sniff, &rfds);
4247 	    FD_SET(fd_from_sniff, &efds);
4248 	    if (maxfd < fd_from_sniff)
4249 		maxfd = fd_from_sniff;
4250 	}
4251 # endif
4252 # ifdef FEAT_XCLIPBOARD
4253 	if (xterm_Shell != (Widget)0)
4254 	{
4255 	    FD_SET(ConnectionNumber(xterm_dpy), &rfds);
4256 	    if (maxfd < ConnectionNumber(xterm_dpy))
4257 		maxfd = ConnectionNumber(xterm_dpy);
4258 	}
4259 # endif
4260 # ifdef FEAT_MOUSE_GPM
4261 	if (check_for_gpm != NULL && gpm_flag && gpm_fd >= 0)
4262 	{
4263 	    FD_SET(gpm_fd, &rfds);
4264 	    FD_SET(gpm_fd, &efds);
4265 	    if (maxfd < gpm_fd)
4266 		maxfd = gpm_fd;
4267 	}
4268 # endif
4269 # ifdef USE_XSMP
4270 	if (xsmp_icefd != -1)
4271 	{
4272 	    FD_SET(xsmp_icefd, &rfds);
4273 	    FD_SET(xsmp_icefd, &efds);
4274 	    if (maxfd < xsmp_icefd)
4275 		maxfd = xsmp_icefd;
4276 	}
4277 # endif
4278 
4279 # ifdef OLD_VMS
4280 	/* Old VMS as v6.2 and older have broken select(). It waits more than
4281 	 * required. Should not be used */
4282 	ret = 0;
4283 # else
4284 	ret = select(maxfd + 1, &rfds, NULL, &efds, (msec >= 0) ? &tv : NULL);
4285 # endif
4286 
4287 # ifdef FEAT_SNIFF
4288 	if (ret < 0 )
4289 	    sniff_disconnect(1);
4290 	else if (ret > 0 && want_sniff_request)
4291 	{
4292 	    if (FD_ISSET(fd_from_sniff, &efds))
4293 		sniff_disconnect(1);
4294 	    if (FD_ISSET(fd_from_sniff, &rfds))
4295 		sniff_request_waiting = 1;
4296 	}
4297 # endif
4298 # ifdef FEAT_XCLIPBOARD
4299 	if (ret > 0 && xterm_Shell != (Widget)0
4300 		&& FD_ISSET(ConnectionNumber(xterm_dpy), &rfds))
4301 	{
4302 	    xterm_update();	      /* Maybe we should hand out clipboard */
4303 	    /* continue looping when we only got the X event and the input
4304 	     * buffer is empty */
4305 	    if (--ret == 0 && !input_available())
4306 	    {
4307 		/* Try again */
4308 		finished = FALSE;
4309 	    }
4310 	}
4311 # endif
4312 # ifdef FEAT_MOUSE_GPM
4313 	if (ret > 0 && gpm_flag && check_for_gpm != NULL && gpm_fd >= 0)
4314 	{
4315 	    if (FD_ISSET(gpm_fd, &efds))
4316 		gpm_close();
4317 	    else if (FD_ISSET(gpm_fd, &rfds))
4318 		*check_for_gpm = 1;
4319 	}
4320 # endif
4321 # ifdef USE_XSMP
4322 	if (ret > 0 && xsmp_icefd != -1)
4323 	{
4324 	    if (FD_ISSET(xsmp_icefd, &efds))
4325 	    {
4326 		if (p_verbose > 0)
4327 		    MSG(_("XSMP lost ICE connection"));
4328 		xsmp_close();
4329 		if (--ret == 0)
4330 		    finished = FALSE;   /* keep going if event was only one */
4331 	    }
4332 	    else if (FD_ISSET(xsmp_icefd, &rfds))
4333 	    {
4334 		busy = TRUE;
4335 		xsmp_handle_requests();
4336 		busy = FALSE;
4337 		if (--ret == 0)
4338 		    finished = FALSE;   /* keep going if event was only one */
4339 	    }
4340 	}
4341 # endif
4342 
4343 #endif /* HAVE_SELECT */
4344 
4345 #ifdef MAY_LOOP
4346 	if (finished || msec == 0)
4347 	    break;
4348 
4349 	/* We're going to loop around again, find out for how long */
4350 	if (msec > 0)
4351 	{
4352 # ifdef USE_START_TV
4353 	    struct timeval  mtv;
4354 
4355 	    /* Compute remaining wait time. */
4356 	    gettimeofday(&mtv, NULL);
4357 	    msec -= (mtv.tv_sec - start_tv.tv_sec) * 1000L
4358 				   + (mtv.tv_usec - start_tv.tv_usec) / 1000L;
4359 # else
4360 	    /* Guess we got interrupted halfway. */
4361 	    msec = msec / 2;
4362 # endif
4363 	    if (msec <= 0)
4364 		break;	/* waited long enough */
4365 	}
4366 #endif
4367     }
4368 
4369     return (ret > 0);
4370 }
4371 
4372 #ifndef VMS
4373 
4374 #ifndef NO_EXPANDPATH
4375     static int
4376 pstrcmp(a, b)
4377     const void *a, *b;
4378 {
4379     return (pathcmp(*(char **)a, *(char **)b));
4380 }
4381 
4382 /*
4383  * Recursively expand one path component into all matching files and/or
4384  * directories.
4385  * "path" has backslashes before chars that are not to be expanded, starting
4386  * at "path + wildoff".
4387  * Return the number of matches found.
4388  */
4389     int
4390 mch_expandpath(gap, path, flags)
4391     garray_T	*gap;
4392     char_u	*path;
4393     int		flags;		/* EW_* flags */
4394 {
4395     return unix_expandpath(gap, path, 0, flags);
4396 }
4397 
4398     static int
4399 unix_expandpath(gap, path, wildoff, flags)
4400     garray_T	*gap;
4401     char_u	*path;
4402     int		wildoff;
4403     int		flags;		/* EW_* flags */
4404 {
4405     char_u	*buf;
4406     char_u	*path_end;
4407     char_u	*p, *s, *e;
4408     int		start_len, c;
4409     char_u	*pat;
4410     DIR		*dirp;
4411     regmatch_T	regmatch;
4412     struct dirent *dp;
4413     int		starts_with_dot;
4414     int		matches;
4415     int		len;
4416 
4417     start_len = gap->ga_len;
4418     buf = alloc(STRLEN(path) + BASENAMELEN + 5);/* make room for file name */
4419     if (buf == NULL)
4420 	return 0;
4421 
4422 /*
4423  * Find the first part in the path name that contains a wildcard.
4424  * Copy it into buf, including the preceding characters.
4425  */
4426     p = buf;
4427     s = buf;
4428     e = NULL;
4429     path_end = path;
4430     while (*path_end != NUL)
4431     {
4432 	/* May ignore a wildcard that has a backslash before it; it will
4433 	 * be removed by rem_backslash() or file_pat_to_reg_pat() below. */
4434 	if (path_end >= path + wildoff && rem_backslash(path_end))
4435 	    *p++ = *path_end++;
4436 	else if (*path_end == '/')
4437 	{
4438 	    if (e != NULL)
4439 		break;
4440 	    s = p + 1;
4441 	}
4442 	else if (path_end >= path + wildoff
4443 			 && vim_strchr((char_u *)"*?[{~$", *path_end) != NULL)
4444 	    e = p;
4445 #ifdef FEAT_MBYTE
4446 	if (has_mbyte)
4447 	{
4448 	    len = (*mb_ptr2len_check)(path_end);
4449 	    STRNCPY(p, path_end, len);
4450 	    p += len;
4451 	    path_end += len;
4452 	}
4453 	else
4454 #endif
4455 	    *p++ = *path_end++;
4456     }
4457     e = p;
4458     *e = NUL;
4459 
4460     /* now we have one wildcard component between s and e */
4461     /* Remove backslashes between "wildoff" and the start of the wildcard
4462      * component. */
4463     for (p = buf + wildoff; p < s; ++p)
4464 	if (rem_backslash(p))
4465 	{
4466 	    STRCPY(p, p + 1);
4467 	    --e;
4468 	    --s;
4469 	}
4470 
4471     /* convert the file pattern to a regexp pattern */
4472     starts_with_dot = (*s == '.');
4473     pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
4474     if (pat == NULL)
4475     {
4476 	vim_free(buf);
4477 	return 0;
4478     }
4479 
4480     /* compile the regexp into a program */
4481 #ifdef MACOS_X /* Can/Should we use CASE_INSENSITIVE_FILENAME instead ?*/
4482     regmatch.rm_ic = TRUE;		/* Behave like Terminal.app */
4483 #else
4484     regmatch.rm_ic = FALSE;		/* Don't ever ignore case */
4485 #endif
4486     regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
4487     vim_free(pat);
4488 
4489     if (regmatch.regprog == NULL)
4490     {
4491 	vim_free(buf);
4492 	return 0;
4493     }
4494 
4495     /* open the directory for scanning */
4496     c = *s;
4497     *s = NUL;
4498     dirp = opendir(*buf == NUL ? "." : (char *)buf);
4499     *s = c;
4500 
4501     /* Find all matching entries */
4502     if (dirp != NULL)
4503     {
4504 	for (;;)
4505 	{
4506 	    dp = readdir(dirp);
4507 	    if (dp == NULL)
4508 		break;
4509 	    if ((dp->d_name[0] != '.' || starts_with_dot)
4510 		    && vim_regexec(&regmatch, (char_u *)dp->d_name, (colnr_T)0))
4511 	    {
4512 		STRCPY(s, dp->d_name);
4513 		len = STRLEN(buf);
4514 		STRCPY(buf + len, path_end);
4515 		if (mch_has_exp_wildcard(path_end)) /* handle more wildcards */
4516 		{
4517 		    /* need to expand another component of the path */
4518 		    /* remove backslashes for the remaining components only */
4519 		    (void)unix_expandpath(gap, buf, len + 1, flags);
4520 		}
4521 		else
4522 		{
4523 		    /* no more wildcards, check if there is a match */
4524 		    /* remove backslashes for the remaining components only */
4525 		    if (*path_end != NUL)
4526 			backslash_halve(buf + len + 1);
4527 		    if (mch_getperm(buf) >= 0)	/* add existing file */
4528 			addfile(gap, buf, flags);
4529 		}
4530 	    }
4531 	}
4532 
4533 	closedir(dirp);
4534     }
4535 
4536     vim_free(buf);
4537     vim_free(regmatch.regprog);
4538 
4539     matches = gap->ga_len - start_len;
4540     if (matches > 0)
4541 	qsort(((char_u **)gap->ga_data) + start_len, matches,
4542 						   sizeof(char_u *), pstrcmp);
4543     return matches;
4544 }
4545 #endif
4546 
4547 /*
4548  * mch_expand_wildcards() - this code does wild-card pattern matching using
4549  * the shell
4550  *
4551  * return OK for success, FAIL for error (you may lose some memory) and put
4552  * an error message in *file.
4553  *
4554  * num_pat is number of input patterns
4555  * pat is array of pointers to input patterns
4556  * num_file is pointer to number of matched file names
4557  * file is pointer to array of pointers to matched file names
4558  */
4559 
4560 #ifndef SEEK_SET
4561 # define SEEK_SET 0
4562 #endif
4563 #ifndef SEEK_END
4564 # define SEEK_END 2
4565 #endif
4566 
4567 /* ARGSUSED */
4568     int
4569 mch_expand_wildcards(num_pat, pat, num_file, file, flags)
4570     int		   num_pat;
4571     char_u	 **pat;
4572     int		  *num_file;
4573     char_u	***file;
4574     int		   flags;	/* EW_* flags */
4575 {
4576     int		i;
4577     size_t	len;
4578     char_u	*p;
4579     int		dir;
4580 #ifdef __EMX__
4581 # define EXPL_ALLOC_INC	16
4582     char_u	**expl_files;
4583     size_t	files_alloced, files_free;
4584     char_u	*buf;
4585     int		has_wildcard;
4586 
4587     *num_file = 0;	/* default: no files found */
4588     files_alloced = EXPL_ALLOC_INC; /* how much space is allocated */
4589     files_free = EXPL_ALLOC_INC;    /* how much space is not used  */
4590     *file = (char_u **)alloc(sizeof(char_u **) * files_alloced);
4591     if (*file == NULL)
4592 	return FAIL;
4593 
4594     for (; num_pat > 0; num_pat--, pat++)
4595     {
4596 	expl_files = NULL;
4597 	if (vim_strchr(*pat, '$') || vim_strchr(*pat, '~'))
4598 	    /* expand environment var or home dir */
4599 	    buf = expand_env_save(*pat);
4600 	else
4601 	    buf = vim_strsave(*pat);
4602 	expl_files = NULL;
4603 	has_wildcard = mch_has_exp_wildcard(buf);  /* (still) wildcards in there? */
4604 	if (has_wildcard)   /* yes, so expand them */
4605 	    expl_files = (char_u **)_fnexplode(buf);
4606 
4607 	/*
4608 	 * return value of buf if no wildcards left,
4609 	 * OR if no match AND EW_NOTFOUND is set.
4610 	 */
4611 	if ((!has_wildcard && ((flags & EW_NOTFOUND) || mch_getperm(buf) >= 0))
4612 		|| (expl_files == NULL && (flags & EW_NOTFOUND)))
4613 	{   /* simply save the current contents of *buf */
4614 	    expl_files = (char_u **)alloc(sizeof(char_u **) * 2);
4615 	    if (expl_files != NULL)
4616 	    {
4617 		expl_files[0] = vim_strsave(buf);
4618 		expl_files[1] = NULL;
4619 	    }
4620 	}
4621 	vim_free(buf);
4622 
4623 	/*
4624 	 * Count number of names resulting from expansion,
4625 	 * At the same time add a backslash to the end of names that happen to
4626 	 * be directories, and replace slashes with backslashes.
4627 	 */
4628 	if (expl_files)
4629 	{
4630 	    for (i = 0; (p = expl_files[i]) != NULL; i++)
4631 	    {
4632 		dir = mch_isdir(p);
4633 		/* If we don't want dirs and this is one, skip it */
4634 		if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
4635 		    continue;
4636 
4637 		if (--files_free == 0)
4638 		{
4639 		    /* need more room in table of pointers */
4640 		    files_alloced += EXPL_ALLOC_INC;
4641 		    *file = (char_u **)vim_realloc(*file,
4642 					   sizeof(char_u **) * files_alloced);
4643 		    if (*file == NULL)
4644 		    {
4645 			EMSG(_(e_outofmem));
4646 			*num_file = 0;
4647 			return FAIL;
4648 		    }
4649 		    files_free = EXPL_ALLOC_INC;
4650 		}
4651 		slash_adjust(p);
4652 		if (dir)
4653 		{
4654 		    /* For a directory we add a '/', unless it's already
4655 		     * there. */
4656 		    len = STRLEN(p);
4657 		    if (((*file)[*num_file] = alloc(len + 2)) != NULL)
4658 		    {
4659 			STRCPY((*file)[*num_file], p);
4660 			if (!vim_ispathsep((*file)[*num_file][len - 1]))
4661 			{
4662 			    (*file)[*num_file][len] = psepc;
4663 			    (*file)[*num_file][len + 1] = 0;
4664 			}
4665 		    }
4666 		}
4667 		else
4668 		{
4669 		    (*file)[*num_file] = vim_strsave(p);
4670 		}
4671 
4672 		/*
4673 		 * Error message already given by either alloc or vim_strsave.
4674 		 * Should return FAIL, but returning OK works also.
4675 		 */
4676 		if ((*file)[*num_file] == NULL)
4677 		    break;
4678 		(*num_file)++;
4679 	    }
4680 	    _fnexplodefree((char **)expl_files);
4681 	}
4682     }
4683     return OK;
4684 
4685 #else /* __EMX__ */
4686 
4687     int		j;
4688     char_u	*tempname;
4689     char_u	*command;
4690     FILE	*fd;
4691     char_u	*buffer;
4692 #define STYLE_ECHO  0	    /* use "echo" to expand */
4693 #define STYLE_GLOB  1	    /* use "glob" to expand, for csh */
4694 #define STYLE_PRINT 2	    /* use "print -N" to expand, for zsh */
4695 #define STYLE_BT    3	    /* `cmd` expansion, execute the pattern directly */
4696     int		shell_style = STYLE_ECHO;
4697     int		check_spaces;
4698     static int	did_find_nul = FALSE;
4699     int		ampersent = FALSE;
4700 
4701     *num_file = 0;	/* default: no files found */
4702     *file = NULL;
4703 
4704     /*
4705      * If there are no wildcards, just copy the names to allocated memory.
4706      * Saves a lot of time, because we don't have to start a new shell.
4707      */
4708     if (!have_wildcard(num_pat, pat))
4709 	return save_patterns(num_pat, pat, num_file, file);
4710 
4711     /*
4712      * Don't allow the use of backticks in secure and restricted mode.
4713      */
4714     if (secure || restricted)
4715 	for (i = 0; i < num_pat; ++i)
4716 	    if (vim_strchr(pat[i], '`') != NULL
4717 		    && (check_restricted() || check_secure()))
4718 		return FAIL;
4719 
4720     /*
4721      * get a name for the temp file
4722      */
4723     if ((tempname = vim_tempname('o')) == NULL)
4724     {
4725 	EMSG(_(e_notmp));
4726 	return FAIL;
4727     }
4728 
4729     /*
4730      * Let the shell expand the patterns and write the result into the temp
4731      * file.  if expanding `cmd` execute it directly.
4732      * If we use csh, glob will work better than echo.
4733      * If we use zsh, print -N will work better than glob.
4734      */
4735     if (num_pat == 1 && *pat[0] == '`'
4736 	    && (len = STRLEN(pat[0])) > 2
4737 	    && *(pat[0] + len - 1) == '`')
4738 	shell_style = STYLE_BT;
4739     else if ((len = STRLEN(p_sh)) >= 3)
4740     {
4741 	if (STRCMP(p_sh + len - 3, "csh") == 0)
4742 	    shell_style = STYLE_GLOB;
4743 	else if (STRCMP(p_sh + len - 3, "zsh") == 0)
4744 	    shell_style = STYLE_PRINT;
4745     }
4746 
4747     /* "unset nonomatch; print -N >" plus two is 29 */
4748     len = STRLEN(tempname) + 29;
4749     for (i = 0; i < num_pat; ++i)	/* count the length of the patterns */
4750 	len += STRLEN(pat[i]) + 3;	/* add space and two quotes */
4751     command = alloc(len);
4752     if (command == NULL)
4753     {
4754 	/* out of memory */
4755 	vim_free(tempname);
4756 	return FAIL;
4757     }
4758 
4759     /*
4760      * Build the shell command:
4761      * - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
4762      *	 recognizes this).
4763      * - Add the shell command to print the expanded names.
4764      * - Add the temp file name.
4765      * - Add the file name patterns.
4766      */
4767     if (shell_style == STYLE_BT)
4768     {
4769 	STRCPY(command, pat[0] + 1);		/* exclude first backtick */
4770 	p = command + STRLEN(command) - 1;
4771 	*p = ' ';				/* remove last backtick */
4772 	while (p > command && vim_iswhite(*p))
4773 	    --p;
4774 	if (*p == '&')				/* remove trailing '&' */
4775 	{
4776 	    ampersent = TRUE;
4777 	    *p = ' ';
4778 	}
4779 	STRCAT(command, ">");
4780     }
4781     else
4782     {
4783 	if (flags & EW_NOTFOUND)
4784 	    STRCPY(command, "set nonomatch; ");
4785 	else
4786 	    STRCPY(command, "unset nonomatch; ");
4787 	if (shell_style == STYLE_GLOB)
4788 	    STRCAT(command, "glob >");
4789 	else if (shell_style == STYLE_PRINT)
4790 	    STRCAT(command, "print -N >");
4791 	else
4792 	    STRCAT(command, "echo >");
4793     }
4794     STRCAT(command, tempname);
4795     if (shell_style != STYLE_BT)
4796 	for (i = 0; i < num_pat; ++i)
4797 	{
4798 	    /* When using system() always add extra quotes, because the shell
4799 	     * is started twice.  Otherwise only put quotes around spaces and
4800 	     * single quotes. */
4801 #ifdef USE_SYSTEM
4802 	    STRCAT(command, " \"");
4803 	    STRCAT(command, pat[i]);
4804 	    STRCAT(command, "\"");
4805 #else
4806 	    p = command + STRLEN(command);
4807 	    *p++ = ' ';
4808 	    for (j = 0; pat[i][j] != NUL; )
4809 		if (vim_strchr((char_u *)" '", pat[i][j]) != NULL)
4810 		{
4811 		    *p++ = '"';
4812 		    while (pat[i][j] != NUL
4813 			    && vim_strchr((char_u *)" '", pat[i][j]) != NULL)
4814 			*p++ = pat[i][j++];
4815 		    *p++ = '"';
4816 		}
4817 		else
4818 		    *p++ = pat[i][j++];
4819 	    *p = NUL;
4820 #endif
4821 	}
4822     if (flags & EW_SILENT)
4823 	show_shell_mess = FALSE;
4824     if (ampersent)
4825 	STRCAT(command, "&");		/* put the '&' back after the
4826 					   redirection */
4827 
4828     /*
4829      * Using zsh -G: If a pattern has no matches, it is just deleted from
4830      * the argument list, otherwise zsh gives an error message and doesn't
4831      * expand any other pattern.
4832      */
4833     if (shell_style == STYLE_PRINT)
4834 	extra_shell_arg = (char_u *)"-G";   /* Use zsh NULL_GLOB option */
4835 
4836     /*
4837      * If we use -f then shell variables set in .cshrc won't get expanded.
4838      * vi can do it, so we will too, but it is only necessary if there is a "$"
4839      * in one of the patterns, otherwise we can still use the fast option.
4840      */
4841     else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat))
4842 	extra_shell_arg = (char_u *)"-f";	/* Use csh fast option */
4843 
4844     /*
4845      * execute the shell command
4846      */
4847     i = call_shell(command, SHELL_EXPAND | SHELL_SILENT);
4848 
4849     /* When running in the background, give it some time to create the temp
4850      * file, but don't wait for it to finish. */
4851     if (ampersent)
4852 	mch_delay(10L, TRUE);
4853 
4854     extra_shell_arg = NULL;		/* cleanup */
4855     show_shell_mess = TRUE;
4856     vim_free(command);
4857 
4858     if (i)				/* mch_call_shell() failed */
4859     {
4860 	mch_remove(tempname);
4861 	vim_free(tempname);
4862 	/*
4863 	 * With interactive completion, the error message is not printed.
4864 	 * However with USE_SYSTEM, I don't know how to turn off error messages
4865 	 * from the shell, so screen may still get messed up -- webb.
4866 	 */
4867 #ifndef USE_SYSTEM
4868 	if (!(flags & EW_SILENT))
4869 #endif
4870 	{
4871 	    redraw_later_clear();	/* probably messed up screen */
4872 	    msg_putchar('\n');		/* clear bottom line quickly */
4873 	    cmdline_row = Rows - 1;	/* continue on last line */
4874 #ifdef USE_SYSTEM
4875 	    if (!(flags & EW_SILENT))
4876 #endif
4877 	    {
4878 		MSG(_(e_wildexpand));
4879 		msg_start();		/* don't overwrite this message */
4880 	    }
4881 	}
4882 	/* If a `cmd` expansion failed, don't list `cmd` as a match, even when
4883 	 * EW_NOTFOUND is given */
4884 	if (shell_style == STYLE_BT)
4885 	    return FAIL;
4886 	goto notfound;
4887     }
4888 
4889     /*
4890      * read the names from the file into memory
4891      */
4892     fd = fopen((char *)tempname, READBIN);
4893     if (fd == NULL)
4894     {
4895 	/* Something went wrong, perhaps a file name with a special char. */
4896 	if (!(flags & EW_SILENT))
4897 	{
4898 	    MSG(_(e_wildexpand));
4899 	    msg_start();		/* don't overwrite this message */
4900 	}
4901 	vim_free(tempname);
4902 	goto notfound;
4903     }
4904     fseek(fd, 0L, SEEK_END);
4905     len = ftell(fd);			/* get size of temp file */
4906     fseek(fd, 0L, SEEK_SET);
4907     buffer = alloc(len + 1);
4908     if (buffer == NULL)
4909     {
4910 	/* out of memory */
4911 	mch_remove(tempname);
4912 	vim_free(tempname);
4913 	fclose(fd);
4914 	return FAIL;
4915     }
4916     i = fread((char *)buffer, 1, len, fd);
4917     fclose(fd);
4918     mch_remove(tempname);
4919     if (i != len)
4920     {
4921 	/* unexpected read error */
4922 	EMSG2(_(e_notread), tempname);
4923 	vim_free(tempname);
4924 	vim_free(buffer);
4925 	return FAIL;
4926     }
4927     vim_free(tempname);
4928 
4929 #if defined(__CYGWIN__) || defined(__CYGWIN32__)
4930     /* Translate <CR><NL> into <NL>.  Caution, buffer may contain NUL. */
4931     p = buffer;
4932     for (i = 0; i < len; ++i)
4933 	if (!(buffer[i] == CAR && buffer[i + 1] == NL))
4934 	    *p++ = buffer[i];
4935     len = p - buffer;
4936 # endif
4937 
4938 
4939     /* file names are separated with Space */
4940     if (shell_style == STYLE_ECHO)
4941     {
4942 	buffer[len] = '\n';		/* make sure the buffer ends in NL */
4943 	p = buffer;
4944 	for (i = 0; *p != '\n'; ++i)	/* count number of entries */
4945 	{
4946 	    while (*p != ' ' && *p != '\n')
4947 		++p;
4948 	    p = skipwhite(p);		/* skip to next entry */
4949 	}
4950     }
4951     /* file names are separated with NL */
4952     else if (shell_style == STYLE_BT)
4953     {
4954 	buffer[len] = NUL;		/* make sure the buffer ends in NUL */
4955 	p = buffer;
4956 	for (i = 0; *p != NUL; ++i)	/* count number of entries */
4957 	{
4958 	    while (*p != '\n' && *p != NUL)
4959 		++p;
4960 	    if (*p != NUL)
4961 		++p;
4962 	    p = skipwhite(p);		/* skip leading white space */
4963 	}
4964     }
4965     /* file names are separated with NUL */
4966     else
4967     {
4968 	/*
4969 	 * Some versions of zsh use spaces instead of NULs to separate
4970 	 * results.  Only do this when there is no NUL before the end of the
4971 	 * buffer, otherwise we would never be able to use file names with
4972 	 * embedded spaces when zsh does use NULs.
4973 	 * When we found a NUL once, we know zsh is OK, set did_find_nul and
4974 	 * don't check for spaces again.
4975 	 */
4976 	check_spaces = FALSE;
4977 	if (shell_style == STYLE_PRINT && !did_find_nul)
4978 	{
4979 	    /* If there is a NUL, set did_find_nul, else set check_spaces */
4980 	    if (len && (int)STRLEN(buffer) < len - 1)
4981 		did_find_nul = TRUE;
4982 	    else
4983 		check_spaces = TRUE;
4984 	}
4985 
4986 	/*
4987 	 * Make sure the buffer ends with a NUL.  For STYLE_PRINT there
4988 	 * already is one, for STYLE_GLOB it needs to be added.
4989 	 */
4990 	if (len && buffer[len - 1] == NUL)
4991 	    --len;
4992 	else
4993 	    buffer[len] = NUL;
4994 	i = 0;
4995 	for (p = buffer; p < buffer + len; ++p)
4996 	    if (*p == NUL || (*p == ' ' && check_spaces))   /* count entry */
4997 	    {
4998 		++i;
4999 		*p = NUL;
5000 	    }
5001 	if (len)
5002 	    ++i;			/* count last entry */
5003     }
5004     if (i == 0)
5005     {
5006 	/*
5007 	 * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
5008 	 * /bin/sh will happily expand it to nothing rather than returning an
5009 	 * error; and hey, it's good to check anyway -- webb.
5010 	 */
5011 	vim_free(buffer);
5012 	goto notfound;
5013     }
5014     *num_file = i;
5015     *file = (char_u **)alloc(sizeof(char_u *) * i);
5016     if (*file == NULL)
5017     {
5018 	/* out of memory */
5019 	vim_free(buffer);
5020 	return FAIL;
5021     }
5022 
5023     /*
5024      * Isolate the individual file names.
5025      */
5026     p = buffer;
5027     for (i = 0; i < *num_file; ++i)
5028     {
5029 	(*file)[i] = p;
5030 	/* Space or NL separates */
5031 	if (shell_style == STYLE_ECHO || shell_style == STYLE_BT)
5032 	{
5033 	    while (!(shell_style == STYLE_ECHO && *p == ' ') && *p != '\n')
5034 		++p;
5035 	    if (p == buffer + len)		/* last entry */
5036 		*p = NUL;
5037 	    else
5038 	    {
5039 		*p++ = NUL;
5040 		p = skipwhite(p);		/* skip to next entry */
5041 	    }
5042 	}
5043 	else		/* NUL separates */
5044 	{
5045 	    while (*p && p < buffer + len)	/* skip entry */
5046 		++p;
5047 	    ++p;				/* skip NUL */
5048 	}
5049     }
5050 
5051     /*
5052      * Move the file names to allocated memory.
5053      */
5054     for (j = 0, i = 0; i < *num_file; ++i)
5055     {
5056 	/* Require the files to exist.	Helps when using /bin/sh */
5057 	if (!(flags & EW_NOTFOUND) && mch_getperm((*file)[i]) < 0)
5058 	    continue;
5059 
5060 	/* check if this entry should be included */
5061 	dir = (mch_isdir((*file)[i]));
5062 	if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
5063 	    continue;
5064 
5065 	p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
5066 	if (p)
5067 	{
5068 	    STRCPY(p, (*file)[i]);
5069 	    if (dir)
5070 		STRCAT(p, "/");	    /* add '/' to a directory name */
5071 	    (*file)[j++] = p;
5072 	}
5073     }
5074     vim_free(buffer);
5075     *num_file = j;
5076 
5077     if (*num_file == 0)	    /* rejected all entries */
5078     {
5079 	vim_free(*file);
5080 	*file = NULL;
5081 	goto notfound;
5082     }
5083 
5084     return OK;
5085 
5086 notfound:
5087     if (flags & EW_NOTFOUND)
5088 	return save_patterns(num_pat, pat, num_file, file);
5089     return FAIL;
5090 
5091 #endif /* __EMX__ */
5092 }
5093 
5094 #endif /* VMS */
5095 
5096 #ifndef __EMX__
5097     static int
5098 save_patterns(num_pat, pat, num_file, file)
5099     int		num_pat;
5100     char_u	**pat;
5101     int		*num_file;
5102     char_u	***file;
5103 {
5104     int		i;
5105 
5106     *file = (char_u **)alloc(num_pat * sizeof(char_u *));
5107     if (*file == NULL)
5108 	return FAIL;
5109     for (i = 0; i < num_pat; i++)
5110 	(*file)[i] = vim_strsave(pat[i]);
5111     *num_file = num_pat;
5112     return OK;
5113 }
5114 #endif
5115 
5116 
5117 /*
5118  * Return TRUE if the string "p" contains a wildcard that mch_expandpath() can
5119  * expand.
5120  */
5121     int
5122 mch_has_exp_wildcard(p)
5123     char_u  *p;
5124 {
5125     for ( ; *p; ++p)
5126     {
5127 #ifndef OS2
5128 	if (*p == '\\' && p[1] != NUL)
5129 	    ++p;
5130 	else
5131 #endif
5132 	    if (vim_strchr((char_u *)
5133 #ifdef VMS
5134 				    "*?%"
5135 #else
5136 # ifdef OS2
5137 				    "*?"
5138 # else
5139 				    "*?[{'"
5140 # endif
5141 #endif
5142 						, *p) != NULL)
5143 	    return TRUE;
5144 #ifdef FEAT_MBYTE
5145 	if (has_mbyte)
5146 	    p += (*mb_ptr2len_check)(p) - 1;
5147 #endif
5148     }
5149     return FALSE;
5150 }
5151 
5152 /*
5153  * Return TRUE if the string "p" contains a wildcard.
5154  * Don't recognize '~' at the end as a wildcard.
5155  */
5156     int
5157 mch_has_wildcard(p)
5158     char_u  *p;
5159 {
5160     for ( ; *p; ++p)
5161     {
5162 #ifndef OS2
5163 	if (*p == '\\' && p[1] != NUL)
5164 	    ++p;
5165 	else
5166 #endif
5167 	    if (vim_strchr((char_u *)
5168 #ifdef VMS
5169 				    "*?%$"
5170 #else
5171 # ifdef OS2
5172 #  ifdef VIM_BACKTICK
5173 				    "*?$`"
5174 #  else
5175 				    "*?$"
5176 #  endif
5177 # else
5178 				    "*?[{`'$"
5179 # endif
5180 #endif
5181 						, *p) != NULL
5182 		|| (*p == '~' && p[1] != NUL))
5183 	    return TRUE;
5184 #ifdef FEAT_MBYTE
5185 	if (has_mbyte)
5186 	    p += (*mb_ptr2len_check)(p) - 1;
5187 #endif
5188     }
5189     return FALSE;
5190 }
5191 
5192 #ifndef __EMX__
5193     static int
5194 have_wildcard(num, file)
5195     int	    num;
5196     char_u  **file;
5197 {
5198     int	    i;
5199 
5200     for (i = 0; i < num; i++)
5201 	if (mch_has_wildcard(file[i]))
5202 	    return 1;
5203     return 0;
5204 }
5205 
5206     static int
5207 have_dollars(num, file)
5208     int	    num;
5209     char_u  **file;
5210 {
5211     int	    i;
5212 
5213     for (i = 0; i < num; i++)
5214 	if (vim_strchr(file[i], '$') != NULL)
5215 	    return TRUE;
5216     return FALSE;
5217 }
5218 #endif	/* ifndef __EMX__ */
5219 
5220 #ifndef HAVE_RENAME
5221 /*
5222  * Scaled-down version of rename(), which is missing in Xenix.
5223  * This version can only move regular files and will fail if the
5224  * destination exists.
5225  */
5226     int
5227 mch_rename(src, dest)
5228     const char *src, *dest;
5229 {
5230     struct stat	    st;
5231 
5232     if (stat(dest, &st) >= 0)	    /* fail if destination exists */
5233 	return -1;
5234     if (link(src, dest) != 0)	    /* link file to new name */
5235 	return -1;
5236     if (mch_remove(src) == 0)	    /* delete link to old name */
5237 	return 0;
5238     return -1;
5239 }
5240 #endif /* !HAVE_RENAME */
5241 
5242 #ifdef FEAT_MOUSE_GPM
5243 /*
5244  * Initializes connection with gpm (if it isn't already opened)
5245  * Return 1 if succeeded (or connection already opened), 0 if failed
5246  */
5247     static int
5248 gpm_open()
5249 {
5250     static Gpm_Connect gpm_connect; /* Must it be kept till closing ? */
5251 
5252     if (!gpm_flag)
5253     {
5254 	gpm_connect.eventMask = (GPM_UP | GPM_DRAG | GPM_DOWN);
5255 	gpm_connect.defaultMask = ~GPM_HARD;
5256 	/* Default handling for mouse move*/
5257 	gpm_connect.minMod = 0; /* Handle any modifier keys */
5258 	gpm_connect.maxMod = 0xffff;
5259 	if (Gpm_Open(&gpm_connect, 0) > 0)
5260 	{
5261 	    /* gpm library tries to handling TSTP causes
5262 	     * problems. Anyways, we close connection to Gpm whenever
5263 	     * we are going to suspend or starting an external process
5264 	     * so we should'nt  have problem with this
5265 	     */
5266 	    signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
5267 	    return 1; /* succeed */
5268 	}
5269 	if (gpm_fd == -2)
5270 	    Gpm_Close(); /* We don't want to talk to xterm via gpm */
5271 	return 0;
5272     }
5273     return 1; /* already open */
5274 }
5275 
5276 /*
5277  * Closes connection to gpm
5278  * returns non-zero if connection succesfully closed
5279  */
5280     static void
5281 gpm_close()
5282 {
5283     if (gpm_flag && gpm_fd >= 0) /* if Open */
5284 	Gpm_Close();
5285 }
5286 
5287 /* Reads gpm event and adds special keys to input buf. Returns length of
5288  * generated key sequence.
5289  * This function is made after gui_send_mouse_event
5290  */
5291     static int
5292 mch_gpm_process()
5293 {
5294     int			button;
5295     static Gpm_Event	gpm_event;
5296     char_u		string[6];
5297     int_u		vim_modifiers;
5298     int			row,col;
5299     unsigned char	buttons_mask;
5300     unsigned char	gpm_modifiers;
5301     static unsigned char old_buttons = 0;
5302 
5303     Gpm_GetEvent(&gpm_event);
5304 
5305 #ifdef FEAT_GUI
5306     /* Don't put events in the input queue now. */
5307     if (hold_gui_events)
5308 	return 0;
5309 #endif
5310 
5311     row = gpm_event.y - 1;
5312     col = gpm_event.x - 1;
5313 
5314     string[0] = ESC; /* Our termcode */
5315     string[1] = 'M';
5316     string[2] = 'G';
5317     switch (GPM_BARE_EVENTS(gpm_event.type))
5318     {
5319 	case GPM_DRAG:
5320 	    string[3] = MOUSE_DRAG;
5321 	    break;
5322 	case GPM_DOWN:
5323 	    buttons_mask = gpm_event.buttons & ~old_buttons;
5324 	    old_buttons = gpm_event.buttons;
5325 	    switch (buttons_mask)
5326 	    {
5327 		case GPM_B_LEFT:
5328 		    button = MOUSE_LEFT;
5329 		    break;
5330 		case GPM_B_MIDDLE:
5331 		    button = MOUSE_MIDDLE;
5332 		    break;
5333 		case GPM_B_RIGHT:
5334 		    button = MOUSE_RIGHT;
5335 		    break;
5336 		default:
5337 		    return 0;
5338 		    /*Don't know what to do. Can more than one button be
5339 		     * reported in one event? */
5340 	    }
5341 	    string[3] = (char_u)(button | 0x20);
5342 	    SET_NUM_MOUSE_CLICKS(string[3], gpm_event.clicks + 1);
5343 	    break;
5344 	case GPM_UP:
5345 	    string[3] = MOUSE_RELEASE;
5346 	    old_buttons &= ~gpm_event.buttons;
5347 	    break;
5348 	default:
5349 	    return 0;
5350     }
5351     /*This code is based on gui_x11_mouse_cb in gui_x11.c */
5352     gpm_modifiers = gpm_event.modifiers;
5353     vim_modifiers = 0x0;
5354     /* I ignore capslock stats. Aren't we all just hate capslock mixing with
5355      * Vim commands ? Besides, gpm_event.modifiers is unsigned char, and
5356      * K_CAPSSHIFT is defined 8, so it probably isn't even reported
5357      */
5358     if (gpm_modifiers & ((1 << KG_SHIFT) | (1 << KG_SHIFTR) | (1 << KG_SHIFTL)))
5359 	vim_modifiers |= MOUSE_SHIFT;
5360 
5361     if (gpm_modifiers & ((1 << KG_CTRL) | (1 << KG_CTRLR) | (1 << KG_CTRLL)))
5362 	vim_modifiers |= MOUSE_CTRL;
5363     if (gpm_modifiers & ((1 << KG_ALT) | (1 << KG_ALTGR)))
5364 	vim_modifiers |= MOUSE_ALT;
5365     string[3] |= vim_modifiers;
5366     string[4] = (char_u)(col + ' ' + 1);
5367     string[5] = (char_u)(row + ' ' + 1);
5368     add_to_input_buf(string, 6);
5369     return 6;
5370 }
5371 #endif /* FEAT_MOUSE_GPM */
5372 
5373 #if defined(FEAT_LIBCALL) || defined(PROTO)
5374 typedef char_u * (*STRPROCSTR)__ARGS((char_u *));
5375 typedef char_u * (*INTPROCSTR)__ARGS((int));
5376 typedef int (*STRPROCINT)__ARGS((char_u *));
5377 typedef int (*INTPROCINT)__ARGS((int));
5378 
5379 /*
5380  * Call a DLL routine which takes either a string or int param
5381  * and returns an allocated string.
5382  */
5383     int
5384 mch_libcall(libname, funcname, argstring, argint, string_result, number_result)
5385     char_u	*libname;
5386     char_u	*funcname;
5387     char_u	*argstring;	/* NULL when using a argint */
5388     int		argint;
5389     char_u	**string_result;/* NULL when using number_result */
5390     int		*number_result;
5391 {
5392 # if defined(USE_DLOPEN)
5393     void	*hinstLib;
5394 # else
5395     shl_t	hinstLib;
5396 # endif
5397     STRPROCSTR	ProcAdd;
5398     INTPROCSTR	ProcAddI;
5399     char_u	*retval_str = NULL;
5400     int		retval_int = 0;
5401     int		success = FALSE;
5402 
5403     /* Get a handle to the DLL module. */
5404 # if defined(USE_DLOPEN)
5405     hinstLib = dlopen((char *)libname, RTLD_LAZY
5406 #  ifdef RTLD_LOCAL
5407 	    | RTLD_LOCAL
5408 #  endif
5409 	    );
5410 # else
5411     hinstLib = shl_load((const char*)libname, BIND_IMMEDIATE|BIND_VERBOSE, 0L);
5412 # endif
5413 
5414     /* If the handle is valid, try to get the function address. */
5415     if (hinstLib != NULL)
5416     {
5417 # ifdef HAVE_SETJMP_H
5418 	/*
5419 	 * Catch a crash when calling the library function.  For example when
5420 	 * using a number where a string pointer is expected.
5421 	 */
5422 	mch_startjmp();
5423 	if (SETJMP(lc_jump_env) != 0)
5424 	{
5425 	    success = FALSE;
5426 	    mch_didjmp();
5427 	}
5428 	else
5429 # endif
5430 	{
5431 	    retval_str = NULL;
5432 	    retval_int = 0;
5433 
5434 	    if (argstring != NULL)
5435 	    {
5436 # if defined(USE_DLOPEN)
5437 		ProcAdd = (STRPROCSTR)dlsym(hinstLib, (const char *)funcname);
5438 # else
5439 		if (shl_findsym(&hinstLib, (const char *)funcname,
5440 					TYPE_PROCEDURE, (void *)&ProcAdd) < 0)
5441 		    ProcAdd = NULL;
5442 # endif
5443 		if ((success = (ProcAdd != NULL)))
5444 		{
5445 		    if (string_result == NULL)
5446 			retval_int = ((STRPROCINT)ProcAdd)(argstring);
5447 		    else
5448 			retval_str = (ProcAdd)(argstring);
5449 		}
5450 	    }
5451 	    else
5452 	    {
5453 # if defined(USE_DLOPEN)
5454 		ProcAddI = (INTPROCSTR)dlsym(hinstLib, (const char *)funcname);
5455 # else
5456 		if (shl_findsym(&hinstLib, (const char *)funcname,
5457 				       TYPE_PROCEDURE, (void *)&ProcAddI) < 0)
5458 		    ProcAddI = NULL;
5459 # endif
5460 		if ((success = (ProcAddI != NULL)))
5461 		{
5462 		    if (string_result == NULL)
5463 			retval_int = ((INTPROCINT)ProcAddI)(argint);
5464 		    else
5465 			retval_str = (ProcAddI)(argint);
5466 		}
5467 	    }
5468 
5469 	    /* Save the string before we free the library. */
5470 	    /* Assume that a "1" or "-1" result is an illegal pointer. */
5471 	    if (string_result == NULL)
5472 		*number_result = retval_int;
5473 	    else if (retval_str != NULL
5474 		    && retval_str != (char_u *)1
5475 		    && retval_str != (char_u *)-1)
5476 		*string_result = vim_strsave(retval_str);
5477 	}
5478 
5479 # ifdef HAVE_SETJMP_H
5480 	mch_endjmp();
5481 #  ifdef SIGHASARG
5482 	if (lc_signal != 0)
5483 	{
5484 	    int i;
5485 
5486 	    /* try to find the name of this signal */
5487 	    for (i = 0; signal_info[i].sig != -1; i++)
5488 		if (lc_signal == signal_info[i].sig)
5489 		    break;
5490 	    EMSG2("E368: got SIG%s in libcall()", signal_info[i].name);
5491 	}
5492 #  endif
5493 # endif
5494 
5495 	/* Free the DLL module. */
5496 # if defined(USE_DLOPEN)
5497 	(void)dlclose(hinstLib);
5498 # else
5499 	(void)shl_unload(hinstLib);
5500 # endif
5501     }
5502 
5503     if (!success)
5504     {
5505 	EMSG2(_(e_libcall), funcname);
5506 	return FAIL;
5507     }
5508 
5509     return OK;
5510 }
5511 #endif
5512 
5513 #if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) || defined(PROTO)
5514 static int	xterm_trace = -1;	/* default: disabled */
5515 static int	xterm_button;
5516 
5517 /*
5518  * Setup a dummy window for X selections in a terminal.
5519  */
5520     void
5521 setup_term_clip()
5522 {
5523     int		z = 0;
5524     char	*strp = "";
5525     Widget	AppShell;
5526 
5527     if (!x_connect_to_server())
5528 	return;
5529 
5530     open_app_context();
5531     if (app_context != NULL && xterm_Shell == (Widget)0)
5532     {
5533 	int (*oldhandler)();
5534 #if defined(HAVE_SETJMP_H)
5535 	int (*oldIOhandler)();
5536 #endif
5537 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
5538 	struct timeval  start_tv;
5539 
5540 	if (p_verbose > 0)
5541 	    gettimeofday(&start_tv, NULL);
5542 # endif
5543 
5544 	/* Ignore X errors while opening the display */
5545 	oldhandler = XSetErrorHandler(x_error_check);
5546 
5547 #if defined(HAVE_SETJMP_H)
5548 	/* Ignore X IO errors while opening the display */
5549 	oldIOhandler = XSetIOErrorHandler(x_IOerror_check);
5550 	mch_startjmp();
5551 	if (SETJMP(lc_jump_env) != 0)
5552 	{
5553 	    mch_didjmp();
5554 	    xterm_dpy = NULL;
5555 	}
5556 	else
5557 #endif
5558 	{
5559 	    xterm_dpy = XtOpenDisplay(app_context, xterm_display,
5560 		    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
5561 #if defined(HAVE_SETJMP_H)
5562 	    mch_endjmp();
5563 #endif
5564 	}
5565 
5566 #if defined(HAVE_SETJMP_H)
5567 	/* Now handle X IO errors normally. */
5568 	(void)XSetIOErrorHandler(oldIOhandler);
5569 #endif
5570 	/* Now handle X errors normally. */
5571 	(void)XSetErrorHandler(oldhandler);
5572 
5573 	if (xterm_dpy == NULL)
5574 	{
5575 	    if (p_verbose > 0)
5576 		MSG(_("Opening the X display failed"));
5577 	    return;
5578 	}
5579 
5580 	/* Catch terminating error of the X server connection. */
5581 	(void)XSetIOErrorHandler(x_IOerror_handler);
5582 
5583 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
5584 	if (p_verbose > 0)
5585 	    xopen_message(&start_tv);
5586 # endif
5587 
5588 	/* Create a Shell to make converters work. */
5589 	AppShell = XtVaAppCreateShell("vim_xterm", "Vim_xterm",
5590 		applicationShellWidgetClass, xterm_dpy,
5591 		NULL);
5592 	if (AppShell == (Widget)0)
5593 	    return;
5594 	xterm_Shell = XtVaCreatePopupShell("VIM",
5595 		topLevelShellWidgetClass, AppShell,
5596 		XtNmappedWhenManaged, 0,
5597 		XtNwidth, 1,
5598 		XtNheight, 1,
5599 		NULL);
5600 	if (xterm_Shell == (Widget)0)
5601 	    return;
5602 
5603 	x11_setup_atoms(xterm_dpy);
5604 	if (x11_display == NULL)
5605 	    x11_display = xterm_dpy;
5606 
5607 	XtRealizeWidget(xterm_Shell);
5608 	XSync(xterm_dpy, False);
5609 	xterm_update();
5610     }
5611     if (xterm_Shell != (Widget)0)
5612     {
5613 	clip_init(TRUE);
5614 	if (x11_window == 0 && (strp = getenv("WINDOWID")) != NULL)
5615 	    x11_window = (Window)atol(strp);
5616 	/* Check if $WINDOWID is valid. */
5617 	if (test_x11_window(xterm_dpy) == FAIL)
5618 	    x11_window = 0;
5619 	if (x11_window != 0)
5620 	    xterm_trace = 0;
5621     }
5622 }
5623 
5624     void
5625 start_xterm_trace(button)
5626     int button;
5627 {
5628     if (x11_window == 0 || xterm_trace < 0 || xterm_Shell == (Widget)0)
5629 	return;
5630     xterm_trace = 1;
5631     xterm_button = button;
5632     do_xterm_trace();
5633 }
5634 
5635 
5636     void
5637 stop_xterm_trace()
5638 {
5639     if (xterm_trace < 0)
5640 	return;
5641     xterm_trace = 0;
5642 }
5643 
5644 /*
5645  * Query the xterm pointer and generate mouse termcodes if necessary
5646  * return TRUE if dragging is active, else FALSE
5647  */
5648     static int
5649 do_xterm_trace()
5650 {
5651     Window		root, child;
5652     int			root_x, root_y;
5653     int			win_x, win_y;
5654     int			row, col;
5655     int_u		mask_return;
5656     char_u		buf[50];
5657     char_u		*strp;
5658     long		got_hints;
5659     static char_u	*mouse_code;
5660     static char_u	mouse_name[2] = {KS_MOUSE, KE_FILLER};
5661     static int		prev_row = 0, prev_col = 0;
5662     static XSizeHints	xterm_hints;
5663 
5664     if (xterm_trace <= 0)
5665 	return FALSE;
5666 
5667     if (xterm_trace == 1)
5668     {
5669 	/* Get the hints just before tracking starts.  The font size might
5670 	 * have changed recently */
5671 	XGetWMNormalHints(xterm_dpy, x11_window, &xterm_hints, &got_hints);
5672 	if (!(got_hints & PResizeInc)
5673 		|| xterm_hints.width_inc <= 1
5674 		|| xterm_hints.height_inc <= 1)
5675 	{
5676 	    xterm_trace = -1;  /* Not enough data -- disable tracing */
5677 	    return FALSE;
5678 	}
5679 
5680 	/* Rely on the same mouse code for the duration of this */
5681 	mouse_code = find_termcode(mouse_name);
5682 	prev_row = mouse_row;
5683 	prev_row = mouse_col;
5684 	xterm_trace = 2;
5685 
5686 	/* Find the offset of the chars, there might be a scrollbar on the
5687 	 * left of the window and/or a menu on the top (eterm etc.) */
5688 	XQueryPointer(xterm_dpy, x11_window, &root, &child, &root_x, &root_y,
5689 		      &win_x, &win_y, &mask_return);
5690 	xterm_hints.y = win_y - (xterm_hints.height_inc * mouse_row)
5691 			      - (xterm_hints.height_inc / 2);
5692 	if (xterm_hints.y <= xterm_hints.height_inc / 2)
5693 	    xterm_hints.y = 2;
5694 	xterm_hints.x = win_x - (xterm_hints.width_inc * mouse_col)
5695 			      - (xterm_hints.width_inc / 2);
5696 	if (xterm_hints.x <= xterm_hints.width_inc / 2)
5697 	    xterm_hints.x = 2;
5698 	return TRUE;
5699     }
5700     if (mouse_code == NULL)
5701     {
5702 	xterm_trace = 0;
5703 	return FALSE;
5704     }
5705 
5706     XQueryPointer(xterm_dpy, x11_window, &root, &child, &root_x, &root_y,
5707 		  &win_x, &win_y, &mask_return);
5708 
5709     row = check_row((win_y - xterm_hints.y) / xterm_hints.height_inc);
5710     col = check_col((win_x - xterm_hints.x) / xterm_hints.width_inc);
5711     if (row == prev_row && col == prev_col)
5712 	return TRUE;
5713 
5714     STRCPY(buf, mouse_code);
5715     strp = buf + STRLEN(buf);
5716     *strp++ = (xterm_button | MOUSE_DRAG) & ~0x20;
5717     *strp++ = (char_u)(col + ' ' + 1);
5718     *strp++ = (char_u)(row + ' ' + 1);
5719     *strp = 0;
5720     add_to_input_buf(buf, STRLEN(buf));
5721 
5722     prev_row = row;
5723     prev_col = col;
5724     return TRUE;
5725 }
5726 
5727 # if defined(FEAT_GUI) || defined(PROTO)
5728 /*
5729  * Destroy the display, window and app_context.  Required for GTK.
5730  */
5731     void
5732 clear_xterm_clip()
5733 {
5734     if (xterm_Shell != (Widget)0)
5735     {
5736 	XtDestroyWidget(xterm_Shell);
5737 	xterm_Shell = (Widget)0;
5738     }
5739     if (xterm_dpy != NULL)
5740     {
5741 #if 0
5742 	/* Lesstif and Solaris crash here, lose some memory */
5743 	XtCloseDisplay(xterm_dpy);
5744 #endif
5745 	if (x11_display == xterm_dpy)
5746 	    x11_display = NULL;
5747 	xterm_dpy = NULL;
5748     }
5749 #if 0
5750     if (app_context != (XtAppContext)NULL)
5751     {
5752 	/* Lesstif and Solaris crash here, lose some memory */
5753 	XtDestroyApplicationContext(app_context);
5754 	app_context = (XtAppContext)NULL;
5755     }
5756 #endif
5757 }
5758 # endif
5759 
5760 /*
5761  * Catch up with any queued X events.  This may put keyboard input into the
5762  * input buffer, call resize call-backs, trigger timers etc.  If there is
5763  * nothing in the X event queue (& no timers pending), then we return
5764  * immediately.
5765  */
5766     static void
5767 xterm_update()
5768 {
5769     XEvent event;
5770 
5771     while (XtAppPending(app_context) && !vim_is_input_buf_full())
5772     {
5773 	XtAppNextEvent(app_context, &event);
5774 #ifdef FEAT_CLIENTSERVER
5775 	{
5776 	    XPropertyEvent *e = (XPropertyEvent *)&event;
5777 
5778 	    if (e->type == PropertyNotify && e->window == commWindow
5779 		   && e->atom == commProperty && e->state == PropertyNewValue)
5780 		serverEventProc(xterm_dpy, &event);
5781 	}
5782 #endif
5783 	XtDispatchEvent(&event);
5784     }
5785 }
5786 
5787     int
5788 clip_xterm_own_selection(cbd)
5789     VimClipboard *cbd;
5790 {
5791     if (xterm_Shell != (Widget)0)
5792 	return clip_x11_own_selection(xterm_Shell, cbd);
5793     return FAIL;
5794 }
5795 
5796     void
5797 clip_xterm_lose_selection(cbd)
5798     VimClipboard *cbd;
5799 {
5800     if (xterm_Shell != (Widget)0)
5801 	clip_x11_lose_selection(xterm_Shell, cbd);
5802 }
5803 
5804     void
5805 clip_xterm_request_selection(cbd)
5806     VimClipboard *cbd;
5807 {
5808     if (xterm_Shell != (Widget)0)
5809 	clip_x11_request_selection(xterm_Shell, xterm_dpy, cbd);
5810 }
5811 
5812     void
5813 clip_xterm_set_selection(cbd)
5814     VimClipboard *cbd;
5815 {
5816     clip_x11_set_selection(cbd);
5817 }
5818 #endif
5819 
5820 
5821 #if defined(USE_XSMP) || defined(PROTO)
5822 /*
5823  * Code for X Session Management Protocol.
5824  */
5825 static void xsmp_handle_save_yourself __ARGS((SmcConn smc_conn, SmPointer client_data, int save_type, Bool shutdown, int interact_style, Bool fast));
5826 static void xsmp_die __ARGS((SmcConn smc_conn, SmPointer client_data));
5827 static void xsmp_save_complete __ARGS((SmcConn smc_conn, SmPointer client_data));
5828 static void xsmp_shutdown_cancelled __ARGS((SmcConn smc_conn, SmPointer	client_data));
5829 static void xsmp_ice_connection __ARGS((IceConn iceConn, IcePointer clientData, Bool opening, IcePointer *watchData));
5830 
5831 
5832 # if defined(FEAT_GUI) && defined(USE_XSMP_INTERACT)
5833 static void xsmp_handle_interaction __ARGS((SmcConn smc_conn, SmPointer client_data));
5834 
5835 /*
5836  * This is our chance to ask the user if they want to save,
5837  * or abort the logout
5838  */
5839 /*ARGSUSED*/
5840     static void
5841 xsmp_handle_interaction(smc_conn, client_data)
5842     SmcConn	smc_conn;
5843     SmPointer	client_data;
5844 {
5845     cmdmod_T	save_cmdmod;
5846     int		cancel_shutdown = False;
5847 
5848     save_cmdmod = cmdmod;
5849     cmdmod.confirm = TRUE;
5850     if (check_changed_any(FALSE))
5851 	/* Mustn't logout */
5852 	cancel_shutdown = True;
5853     cmdmod = save_cmdmod;
5854     setcursor();		/* position cursor */
5855     out_flush();
5856 
5857     /* Done interaction */
5858     SmcInteractDone(smc_conn, cancel_shutdown);
5859 
5860     /* Finish off
5861      * Only end save-yourself here if we're not cancelling shutdown;
5862      * we'll get a cancelled callback later in which we'll end it.
5863      * Hopefully get around glitchy SMs (like GNOME-1)
5864      */
5865     if (!cancel_shutdown)
5866     {
5867 	xsmp.save_yourself = False;
5868 	SmcSaveYourselfDone(smc_conn, True);
5869     }
5870 }
5871 # endif
5872 
5873 /*
5874  * Callback that starts save-yourself.
5875  */
5876 /*ARGSUSED*/
5877     static void
5878 xsmp_handle_save_yourself(smc_conn, client_data, save_type,
5879 					       shutdown, interact_style, fast)
5880     SmcConn	smc_conn;
5881     SmPointer	client_data;
5882     int		save_type;
5883     Bool	shutdown;
5884     int		interact_style;
5885     Bool	fast;
5886 {
5887     /* Handle already being in saveyourself */
5888     if (xsmp.save_yourself)
5889 	SmcSaveYourselfDone(smc_conn, True);
5890     xsmp.save_yourself = True;
5891     xsmp.shutdown = shutdown;
5892 
5893     /* First up, preserve all files */
5894     out_flush();
5895     ml_sync_all(FALSE, FALSE);	/* preserve all swap files */
5896 
5897     if (p_verbose > 0)
5898 	MSG(_("XSMP handling save-yourself request"));
5899 
5900 # if defined(FEAT_GUI) && defined(USE_XSMP_INTERACT)
5901     /* Now see if we can ask about unsaved files */
5902     if (shutdown && !fast && gui.in_use)
5903 	/* Need to interact with user, but need SM's permission */
5904 	SmcInteractRequest(smc_conn, SmDialogError,
5905 					xsmp_handle_interaction, client_data);
5906     else
5907 # endif
5908     {
5909 	/* Can stop the cycle here */
5910 	SmcSaveYourselfDone(smc_conn, True);
5911 	xsmp.save_yourself = False;
5912     }
5913 }
5914 
5915 
5916 /*
5917  * Callback to warn us of imminent death.
5918  */
5919 /*ARGSUSED*/
5920     static void
5921 xsmp_die(smc_conn, client_data)
5922     SmcConn	smc_conn;
5923     SmPointer	client_data;
5924 {
5925     xsmp_close();
5926 
5927     /* quit quickly leaving swapfiles for modified buffers behind */
5928     getout_preserve_modified(0);
5929 }
5930 
5931 
5932 /*
5933  * Callback to tell us that save-yourself has completed.
5934  */
5935 /*ARGSUSED*/
5936     static void
5937 xsmp_save_complete(smc_conn, client_data)
5938     SmcConn	smc_conn;
5939     SmPointer	client_data;
5940 {
5941     xsmp.save_yourself = False;
5942 }
5943 
5944 
5945 /*
5946  * Callback to tell us that an instigated shutdown was cancelled
5947  * (maybe even by us)
5948  */
5949 /*ARGSUSED*/
5950     static void
5951 xsmp_shutdown_cancelled(smc_conn, client_data)
5952     SmcConn	smc_conn;
5953     SmPointer	client_data;
5954 {
5955     if (xsmp.save_yourself)
5956 	SmcSaveYourselfDone(smc_conn, True);
5957     xsmp.save_yourself = False;
5958     xsmp.shutdown = False;
5959 }
5960 
5961 
5962 /*
5963  * Callback to tell us that a new ICE connection has been established.
5964  */
5965 /*ARGSUSED*/
5966     static void
5967 xsmp_ice_connection(iceConn, clientData, opening, watchData)
5968     IceConn	iceConn;
5969     IcePointer	clientData;
5970     Bool	opening;
5971     IcePointer	*watchData;
5972 {
5973     /* Intercept creation of ICE connection fd */
5974     if (opening)
5975     {
5976 	xsmp_icefd = IceConnectionNumber(iceConn);
5977 	IceRemoveConnectionWatch(xsmp_ice_connection, NULL);
5978     }
5979 }
5980 
5981 
5982 /* Handle any ICE processing that's required; return FAIL if SM lost */
5983     int
5984 xsmp_handle_requests()
5985 {
5986     Bool rep;
5987 
5988     if (IceProcessMessages(xsmp.iceconn, NULL, &rep)
5989 						 == IceProcessMessagesIOError)
5990     {
5991 	/* Lost ICE */
5992 	if (p_verbose > 0)
5993 	    MSG(_("XSMP lost ICE connection"));
5994 	xsmp_close();
5995 	return FAIL;
5996     }
5997     else
5998 	return OK;
5999 }
6000 
6001 static int dummy;
6002 
6003 /* Set up X Session Management Protocol */
6004     void
6005 xsmp_init(void)
6006 {
6007     char		errorstring[80];
6008     char		*clientid;
6009     SmcCallbacks	smcallbacks;
6010 #if 0
6011     SmPropValue		smname;
6012     SmProp		smnameprop;
6013     SmProp		*smprops[1];
6014 #endif
6015 
6016     if (p_verbose > 0)
6017 	MSG(_("XSMP opening connection"));
6018 
6019     xsmp.save_yourself = xsmp.shutdown = False;
6020 
6021     /* Set up SM callbacks - must have all, even if they're not used */
6022     smcallbacks.save_yourself.callback = xsmp_handle_save_yourself;
6023     smcallbacks.save_yourself.client_data = NULL;
6024     smcallbacks.die.callback = xsmp_die;
6025     smcallbacks.die.client_data = NULL;
6026     smcallbacks.save_complete.callback = xsmp_save_complete;
6027     smcallbacks.save_complete.client_data = NULL;
6028     smcallbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
6029     smcallbacks.shutdown_cancelled.client_data = NULL;
6030 
6031     /* Set up a watch on ICE connection creations.  The "dummy" argument is
6032      * apparently required for FreeBSD (we get a BUS error when using NULL). */
6033     if (IceAddConnectionWatch(xsmp_ice_connection, &dummy) == 0)
6034     {
6035 	if (p_verbose > 0)
6036 	    MSG(_("XSMP ICE connection watch failed"));
6037 	return;
6038     }
6039 
6040     /* Create an SM connection */
6041     xsmp.smcconn = SmcOpenConnection(
6042 	    NULL,
6043 	    NULL,
6044 	    SmProtoMajor,
6045 	    SmProtoMinor,
6046 	    SmcSaveYourselfProcMask | SmcDieProcMask
6047 		     | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
6048 	    &smcallbacks,
6049 	    NULL,
6050 	    &clientid,
6051 	    sizeof(errorstring),
6052 	    errorstring);
6053     if (xsmp.smcconn == NULL)
6054     {
6055 	char errorreport[132];
6056 	sprintf(errorreport, _("XSMP SmcOpenConnection failed: %s"),
6057 		errorstring);
6058 	if (p_verbose > 0)
6059 	    MSG(errorreport);
6060 	return;
6061     }
6062     xsmp.iceconn = SmcGetIceConnection(xsmp.smcconn);
6063 
6064 #if 0
6065     /* ID ourselves */
6066     smname.value = "vim";
6067     smname.length = 3;
6068     smnameprop.name = "SmProgram";
6069     smnameprop.type = "SmARRAY8";
6070     smnameprop.num_vals = 1;
6071     smnameprop.vals = &smname;
6072 
6073     smprops[0] = &smnameprop;
6074     SmcSetProperties(xsmp.smcconn, 1, smprops);
6075 #endif
6076 }
6077 
6078 
6079 /* Shut down XSMP comms. */
6080     void
6081 xsmp_close()
6082 {
6083     if (xsmp_icefd != -1)
6084     {
6085 	SmcCloseConnection(xsmp.smcconn, 0, NULL);
6086 	xsmp_icefd = -1;
6087     }
6088 }
6089 #endif /* USE_XSMP */
6090 
6091 
6092 #ifdef EBCDIC
6093 /* Translate character to its CTRL- value */
6094 char CtrlTable[] =
6095 {
6096 /* 00 - 5E */
6097 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6098 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6099 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6100 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6101 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6102 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6103 /* ^ */ 0x1E,
6104 /* - */ 0x1F,
6105 /* 61 - 6C */
6106 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6107 /* _ */ 0x1F,
6108 /* 6E - 80 */
6109 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6110 /* a */ 0x01,
6111 /* b */ 0x02,
6112 /* c */ 0x03,
6113 /* d */ 0x37,
6114 /* e */ 0x2D,
6115 /* f */ 0x2E,
6116 /* g */ 0x2F,
6117 /* h */ 0x16,
6118 /* i */ 0x05,
6119 /* 8A - 90 */
6120 	0, 0, 0, 0, 0, 0, 0,
6121 /* j */ 0x15,
6122 /* k */ 0x0B,
6123 /* l */ 0x0C,
6124 /* m */ 0x0D,
6125 /* n */ 0x0E,
6126 /* o */ 0x0F,
6127 /* p */ 0x10,
6128 /* q */ 0x11,
6129 /* r */ 0x12,
6130 /* 9A - A1 */
6131 	0, 0, 0, 0, 0, 0, 0, 0,
6132 /* s */ 0x13,
6133 /* t */ 0x3C,
6134 /* u */ 0x3D,
6135 /* v */ 0x32,
6136 /* w */ 0x26,
6137 /* x */ 0x18,
6138 /* y */ 0x19,
6139 /* z */ 0x3F,
6140 /* AA - AC */
6141 	0, 0, 0,
6142 /* [ */ 0x27,
6143 /* AE - BC */
6144 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6145 /* ] */ 0x1D,
6146 /* BE - C0 */ 0, 0, 0,
6147 /* A */ 0x01,
6148 /* B */ 0x02,
6149 /* C */ 0x03,
6150 /* D */ 0x37,
6151 /* E */ 0x2D,
6152 /* F */ 0x2E,
6153 /* G */ 0x2F,
6154 /* H */ 0x16,
6155 /* I */ 0x05,
6156 /* CA - D0 */ 0, 0, 0, 0, 0, 0, 0,
6157 /* J */ 0x15,
6158 /* K */ 0x0B,
6159 /* L */ 0x0C,
6160 /* M */ 0x0D,
6161 /* N */ 0x0E,
6162 /* O */ 0x0F,
6163 /* P */ 0x10,
6164 /* Q */ 0x11,
6165 /* R */ 0x12,
6166 /* DA - DF */ 0, 0, 0, 0, 0, 0,
6167 /* \ */ 0x1C,
6168 /* E1 */ 0,
6169 /* S */ 0x13,
6170 /* T */ 0x3C,
6171 /* U */ 0x3D,
6172 /* V */ 0x32,
6173 /* W */ 0x26,
6174 /* X */ 0x18,
6175 /* Y */ 0x19,
6176 /* Z */ 0x3F,
6177 /* EA - FF*/ 0, 0, 0, 0, 0, 0,
6178 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6179 };
6180 
6181 char MetaCharTable[]=
6182 {/*   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
6183       0,  0,  0,  0,'\\', 0,'F',  0,'W','M','N',  0,  0,  0,  0,  0,
6184       0,  0,  0,  0,']',  0,  0,'G',  0,  0,'R','O',  0,  0,  0,  0,
6185     '@','A','B','C','D','E',  0,  0,'H','I','J','K','L',  0,  0,  0,
6186     'P','Q',  0,'S','T','U','V',  0,'X','Y','Z','[',  0,  0,'^',  0
6187 };
6188 
6189 
6190 /* TODO: Use characters NOT numbers!!! */
6191 char CtrlCharTable[]=
6192 {/*   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
6193     124,193,194,195,  0,201,  0,  0,  0,  0,  0,210,211,212,213,214,
6194     215,216,217,226,  0,209,200,  0,231,232,  0,  0,224,189, 95,109,
6195       0,  0,  0,  0,  0,  0,230,173,  0,  0,  0,  0,  0,197,198,199,
6196       0,  0,229,  0,  0,  0,  0,196,  0,  0,  0,  0,227,228,  0,233,
6197 };
6198 
6199 
6200 #endif
6201