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