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