xref: /vim-8.2.3635/src/os_unix.c (revision 2e693a88)
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 MSWIN
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	unix_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__)
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__)
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 
1663     void
1664 ex_xrestore(exarg_T *eap)
1665 {
1666     if (eap->arg != NULL && STRLEN(eap->arg) > 0)
1667     {
1668         if (xterm_display_allocated)
1669             vim_free(xterm_display);
1670         xterm_display = (char *)vim_strsave(eap->arg);
1671         xterm_display_allocated = TRUE;
1672     }
1673     smsg(_("restoring display %s"), xterm_display == NULL
1674 			      ? (char *)mch_getenv("DISPLAY") : xterm_display);
1675 
1676     clear_xterm_clip();
1677     x11_window = 0;
1678     xterm_dpy_retry_count = 5;  // Try reconnecting five times
1679     may_restore_clipboard();
1680 }
1681 #endif
1682 
1683 /*
1684  * Test if "dpy" and x11_window are valid by getting the window title.
1685  * I don't actually want it yet, so there may be a simpler call to use, but
1686  * this will cause the error handler x_error_check() to be called if anything
1687  * is wrong, such as the window pointer being invalid (as can happen when the
1688  * user changes his DISPLAY, but not his WINDOWID) -- webb
1689  */
1690     static int
1691 test_x11_window(Display *dpy)
1692 {
1693     int			(*old_handler)();
1694     XTextProperty	text_prop;
1695 
1696     old_handler = XSetErrorHandler(x_error_check);
1697     got_x_error = FALSE;
1698     if (XGetWMName(dpy, x11_window, &text_prop))
1699 	XFree((void *)text_prop.value);
1700     XSync(dpy, False);
1701     (void)XSetErrorHandler(old_handler);
1702 
1703     if (p_verbose > 0 && got_x_error)
1704 	verb_msg(_("Testing the X display failed"));
1705 
1706     return (got_x_error ? FAIL : OK);
1707 }
1708 #endif
1709 
1710 #ifdef FEAT_TITLE
1711 
1712 #ifdef FEAT_X11
1713 
1714 static int get_x11_thing(int get_title, int test_only);
1715 
1716 /*
1717  * try to get x11 window and display
1718  *
1719  * return FAIL for failure, OK otherwise
1720  */
1721     static int
1722 get_x11_windis(void)
1723 {
1724     char	    *winid;
1725     static int	    result = -1;
1726 #define XD_NONE	 0	/* x11_display not set here */
1727 #define XD_HERE	 1	/* x11_display opened here */
1728 #define XD_GUI	 2	/* x11_display used from gui.dpy */
1729 #define XD_XTERM 3	/* x11_display used from xterm_dpy */
1730     static int	    x11_display_from = XD_NONE;
1731     static int	    did_set_error_handler = FALSE;
1732 
1733     if (!did_set_error_handler)
1734     {
1735 	/* X just exits if it finds an error otherwise! */
1736 	(void)XSetErrorHandler(x_error_handler);
1737 	did_set_error_handler = TRUE;
1738     }
1739 
1740 #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
1741     if (gui.in_use)
1742     {
1743 	/*
1744 	 * If the X11 display was opened here before, for the window where Vim
1745 	 * was started, close that one now to avoid a memory leak.
1746 	 */
1747 	if (x11_display_from == XD_HERE && x11_display != NULL)
1748 	{
1749 	    XCloseDisplay(x11_display);
1750 	    x11_display_from = XD_NONE;
1751 	}
1752 	if (gui_get_x11_windis(&x11_window, &x11_display) == OK)
1753 	{
1754 	    x11_display_from = XD_GUI;
1755 	    return OK;
1756 	}
1757 	x11_display = NULL;
1758 	return FAIL;
1759     }
1760     else if (x11_display_from == XD_GUI)
1761     {
1762 	/* GUI must have stopped somehow, clear x11_display */
1763 	x11_window = 0;
1764 	x11_display = NULL;
1765 	x11_display_from = XD_NONE;
1766     }
1767 #endif
1768 
1769     /* When started with the "-X" argument, don't try connecting. */
1770     if (!x_connect_to_server())
1771 	return FAIL;
1772 
1773     /*
1774      * If WINDOWID not set, should try another method to find out
1775      * what the current window number is. The only code I know for
1776      * this is very complicated.
1777      * We assume that zero is invalid for WINDOWID.
1778      */
1779     if (x11_window == 0 && (winid = getenv("WINDOWID")) != NULL)
1780 	x11_window = (Window)atol(winid);
1781 
1782 #ifdef FEAT_XCLIPBOARD
1783     if (xterm_dpy == x11_display)
1784 	// x11_display may have been set to xterm_dpy elsewhere
1785 	x11_display_from = XD_XTERM;
1786 
1787     if (xterm_dpy != NULL && x11_window != 0)
1788     {
1789 	/* We may have checked it already, but Gnome terminal can move us to
1790 	 * another window, so we need to check every time. */
1791 	if (x11_display_from != XD_XTERM)
1792 	{
1793 	    /*
1794 	     * If the X11 display was opened here before, for the window where
1795 	     * Vim was started, close that one now to avoid a memory leak.
1796 	     */
1797 	    if (x11_display_from == XD_HERE && x11_display != NULL)
1798 		XCloseDisplay(x11_display);
1799 	    x11_display = xterm_dpy;
1800 	    x11_display_from = XD_XTERM;
1801 	}
1802 	if (test_x11_window(x11_display) == FAIL)
1803 	{
1804 	    /* probably bad $WINDOWID */
1805 	    x11_window = 0;
1806 	    x11_display = NULL;
1807 	    x11_display_from = XD_NONE;
1808 	    return FAIL;
1809 	}
1810 	return OK;
1811     }
1812 #endif
1813 
1814     if (x11_window == 0 || x11_display == NULL)
1815 	result = -1;
1816 
1817     if (result != -1)	    /* Have already been here and set this */
1818 	return result;	    /* Don't do all these X calls again */
1819 
1820     if (x11_window != 0 && x11_display == NULL)
1821     {
1822 #ifdef SET_SIG_ALARM
1823 	RETSIGTYPE (*sig_save)();
1824 #endif
1825 #ifdef ELAPSED_FUNC
1826 	elapsed_T start_tv;
1827 
1828 	if (p_verbose > 0)
1829 	    ELAPSED_INIT(start_tv);
1830 #endif
1831 
1832 #ifdef SET_SIG_ALARM
1833 	/*
1834 	 * Opening the Display may hang if the DISPLAY setting is wrong, or
1835 	 * the network connection is bad.  Set an alarm timer to get out.
1836 	 */
1837 	sig_alarm_called = FALSE;
1838 	sig_save = (RETSIGTYPE (*)())signal(SIGALRM,
1839 						 (RETSIGTYPE (*)())sig_alarm);
1840 	alarm(2);
1841 #endif
1842 	x11_display = XOpenDisplay(NULL);
1843 
1844 #ifdef SET_SIG_ALARM
1845 	alarm(0);
1846 	signal(SIGALRM, (RETSIGTYPE (*)())sig_save);
1847 	if (p_verbose > 0 && sig_alarm_called)
1848 	    verb_msg(_("Opening the X display timed out"));
1849 #endif
1850 	if (x11_display != NULL)
1851 	{
1852 # ifdef ELAPSED_FUNC
1853 	    if (p_verbose > 0)
1854 	    {
1855 		verbose_enter();
1856 		xopen_message(ELAPSED_FUNC(start_tv));
1857 		verbose_leave();
1858 	    }
1859 # endif
1860 	    if (test_x11_window(x11_display) == FAIL)
1861 	    {
1862 		/* Maybe window id is bad */
1863 		x11_window = 0;
1864 		XCloseDisplay(x11_display);
1865 		x11_display = NULL;
1866 	    }
1867 	    else
1868 		x11_display_from = XD_HERE;
1869 	}
1870     }
1871     if (x11_window == 0 || x11_display == NULL)
1872 	return (result = FAIL);
1873 
1874 # ifdef FEAT_EVAL
1875     set_vim_var_nr(VV_WINDOWID, (long)x11_window);
1876 # endif
1877 
1878     return (result = OK);
1879 }
1880 
1881 /*
1882  * Determine original x11 Window Title
1883  */
1884     static int
1885 get_x11_title(int test_only)
1886 {
1887     return get_x11_thing(TRUE, test_only);
1888 }
1889 
1890 /*
1891  * Determine original x11 Window icon
1892  */
1893     static int
1894 get_x11_icon(int test_only)
1895 {
1896     int		retval = FALSE;
1897 
1898     retval = get_x11_thing(FALSE, test_only);
1899 
1900     /* could not get old icon, use terminal name */
1901     if (oldicon == NULL && !test_only)
1902     {
1903 	if (STRNCMP(T_NAME, "builtin_", 8) == 0)
1904 	    oldicon = vim_strsave(T_NAME + 8);
1905 	else
1906 	    oldicon = vim_strsave(T_NAME);
1907     }
1908 
1909     return retval;
1910 }
1911 
1912     static int
1913 get_x11_thing(
1914     int		get_title,	/* get title string */
1915     int		test_only)
1916 {
1917     XTextProperty	text_prop;
1918     int			retval = FALSE;
1919     Status		status;
1920 
1921     if (get_x11_windis() == OK)
1922     {
1923 	/* Get window/icon name if any */
1924 	if (get_title)
1925 	    status = XGetWMName(x11_display, x11_window, &text_prop);
1926 	else
1927 	    status = XGetWMIconName(x11_display, x11_window, &text_prop);
1928 
1929 	/*
1930 	 * If terminal is xterm, then x11_window may be a child window of the
1931 	 * outer xterm window that actually contains the window/icon name, so
1932 	 * keep traversing up the tree until a window with a title/icon is
1933 	 * found.
1934 	 */
1935 	/* Previously this was only done for xterm and alikes.  I don't see a
1936 	 * reason why it would fail for other terminal emulators.
1937 	 * if (term_is_xterm) */
1938 	{
1939 	    Window	    root;
1940 	    Window	    parent;
1941 	    Window	    win = x11_window;
1942 	    Window	   *children;
1943 	    unsigned int    num_children;
1944 
1945 	    while (!status || text_prop.value == NULL)
1946 	    {
1947 		if (!XQueryTree(x11_display, win, &root, &parent, &children,
1948 							       &num_children))
1949 		    break;
1950 		if (children)
1951 		    XFree((void *)children);
1952 		if (parent == root || parent == 0)
1953 		    break;
1954 
1955 		win = parent;
1956 		if (get_title)
1957 		    status = XGetWMName(x11_display, win, &text_prop);
1958 		else
1959 		    status = XGetWMIconName(x11_display, win, &text_prop);
1960 	    }
1961 	}
1962 	if (status && text_prop.value != NULL)
1963 	{
1964 	    retval = TRUE;
1965 	    if (!test_only)
1966 	    {
1967 		if (text_prop.encoding == XA_STRING && !has_mbyte)
1968 		{
1969 		    if (get_title)
1970 			oldtitle = vim_strsave((char_u *)text_prop.value);
1971 		    else
1972 			oldicon = vim_strsave((char_u *)text_prop.value);
1973 		}
1974 		else
1975 		{
1976 		    char    **cl;
1977 		    Status  transform_status;
1978 		    int	    n = 0;
1979 
1980 		    transform_status = XmbTextPropertyToTextList(x11_display,
1981 								 &text_prop,
1982 								 &cl, &n);
1983 		    if (transform_status >= Success && n > 0 && cl[0])
1984 		    {
1985 			if (get_title)
1986 			    oldtitle = vim_strsave((char_u *) cl[0]);
1987 			else
1988 			    oldicon = vim_strsave((char_u *) cl[0]);
1989 			XFreeStringList(cl);
1990 		    }
1991 		    else
1992 		    {
1993 			if (get_title)
1994 			    oldtitle = vim_strsave((char_u *)text_prop.value);
1995 			else
1996 			    oldicon = vim_strsave((char_u *)text_prop.value);
1997 		    }
1998 		}
1999 	    }
2000 	    XFree((void *)text_prop.value);
2001 	}
2002     }
2003     return retval;
2004 }
2005 
2006 /* Xutf8 functions are not available on older systems. Note that on some
2007  * systems X_HAVE_UTF8_STRING may be defined in a header file but
2008  * Xutf8SetWMProperties() is not in the X11 library.  Configure checks for
2009  * that and defines HAVE_XUTF8SETWMPROPERTIES. */
2010 #if defined(X_HAVE_UTF8_STRING)
2011 # if X_HAVE_UTF8_STRING && HAVE_XUTF8SETWMPROPERTIES
2012 #  define USE_UTF8_STRING
2013 # endif
2014 #endif
2015 
2016 /*
2017  * Set x11 Window Title
2018  *
2019  * get_x11_windis() must be called before this and have returned OK
2020  */
2021     static void
2022 set_x11_title(char_u *title)
2023 {
2024 	/* XmbSetWMProperties() and Xutf8SetWMProperties() should use a STRING
2025 	 * when possible, COMPOUND_TEXT otherwise.  COMPOUND_TEXT isn't
2026 	 * supported everywhere and STRING doesn't work for multi-byte titles.
2027 	 */
2028 #ifdef USE_UTF8_STRING
2029     if (enc_utf8)
2030 	Xutf8SetWMProperties(x11_display, x11_window, (const char *)title,
2031 					     NULL, NULL, 0, NULL, NULL, NULL);
2032     else
2033 #endif
2034     {
2035 #if XtSpecificationRelease >= 4
2036 # ifdef FEAT_XFONTSET
2037 	XmbSetWMProperties(x11_display, x11_window, (const char *)title,
2038 					     NULL, NULL, 0, NULL, NULL, NULL);
2039 # else
2040 	XTextProperty	text_prop;
2041 	char		*c_title = (char *)title;
2042 
2043 	/* directly from example 3-18 "basicwin" of Xlib Programming Manual */
2044 	(void)XStringListToTextProperty(&c_title, 1, &text_prop);
2045 	XSetWMProperties(x11_display, x11_window, &text_prop,
2046 					     NULL, NULL, 0, NULL, NULL, NULL);
2047 # endif
2048 #else
2049 	XStoreName(x11_display, x11_window, (char *)title);
2050 #endif
2051     }
2052     XFlush(x11_display);
2053 }
2054 
2055 /*
2056  * Set x11 Window icon
2057  *
2058  * get_x11_windis() must be called before this and have returned OK
2059  */
2060     static void
2061 set_x11_icon(char_u *icon)
2062 {
2063     /* See above for comments about using X*SetWMProperties(). */
2064 #ifdef USE_UTF8_STRING
2065     if (enc_utf8)
2066 	Xutf8SetWMProperties(x11_display, x11_window, NULL, (const char *)icon,
2067 						   NULL, 0, NULL, NULL, NULL);
2068     else
2069 #endif
2070     {
2071 #if XtSpecificationRelease >= 4
2072 # ifdef FEAT_XFONTSET
2073 	XmbSetWMProperties(x11_display, x11_window, NULL, (const char *)icon,
2074 						   NULL, 0, NULL, NULL, NULL);
2075 # else
2076 	XTextProperty	text_prop;
2077 	char		*c_icon = (char *)icon;
2078 
2079 	(void)XStringListToTextProperty(&c_icon, 1, &text_prop);
2080 	XSetWMProperties(x11_display, x11_window, NULL, &text_prop,
2081 						   NULL, 0, NULL, NULL, NULL);
2082 # endif
2083 #else
2084 	XSetIconName(x11_display, x11_window, (char *)icon);
2085 #endif
2086     }
2087     XFlush(x11_display);
2088 }
2089 
2090 #else  /* FEAT_X11 */
2091 
2092     static int
2093 get_x11_title(int test_only UNUSED)
2094 {
2095     return FALSE;
2096 }
2097 
2098     static int
2099 get_x11_icon(int test_only)
2100 {
2101     if (!test_only)
2102     {
2103 	if (STRNCMP(T_NAME, "builtin_", 8) == 0)
2104 	    oldicon = vim_strsave(T_NAME + 8);
2105 	else
2106 	    oldicon = vim_strsave(T_NAME);
2107     }
2108     return FALSE;
2109 }
2110 
2111 #endif /* FEAT_X11 */
2112 
2113     int
2114 mch_can_restore_title(void)
2115 {
2116     return get_x11_title(TRUE);
2117 }
2118 
2119     int
2120 mch_can_restore_icon(void)
2121 {
2122     return get_x11_icon(TRUE);
2123 }
2124 
2125 /*
2126  * Set the window title and icon.
2127  */
2128     void
2129 mch_settitle(char_u *title, char_u *icon)
2130 {
2131     int		type = 0;
2132     static int	recursive = 0;
2133 
2134     if (T_NAME == NULL)	    /* no terminal name (yet) */
2135 	return;
2136     if (title == NULL && icon == NULL)	    /* nothing to do */
2137 	return;
2138 
2139     /* When one of the X11 functions causes a deadly signal, we get here again
2140      * recursively.  Avoid hanging then (something is probably locked). */
2141     if (recursive)
2142 	return;
2143     ++recursive;
2144 
2145     /*
2146      * if the window ID and the display is known, we may use X11 calls
2147      */
2148 #ifdef FEAT_X11
2149     if (get_x11_windis() == OK)
2150 	type = 1;
2151 #else
2152 # if defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK)
2153     if (gui.in_use)
2154 	type = 1;
2155 # endif
2156 #endif
2157 
2158     /*
2159      * Note: if "t_ts" is set, title is set with escape sequence rather
2160      *	     than x11 calls, because the x11 calls don't always work
2161      */
2162     if ((type || *T_TS != NUL) && title != NULL)
2163     {
2164 	if (oldtitle_outdated)
2165 	{
2166 	    oldtitle_outdated = FALSE;
2167 	    VIM_CLEAR(oldtitle);
2168 	}
2169 	if (oldtitle == NULL
2170 #ifdef FEAT_GUI
2171 		&& !gui.in_use
2172 #endif
2173 		)		/* first call but not in GUI, save title */
2174 	    (void)get_x11_title(FALSE);
2175 
2176 	if (*T_TS != NUL)		/* it's OK if t_fs is empty */
2177 	    term_settitle(title);
2178 #ifdef FEAT_X11
2179 	else
2180 # ifdef FEAT_GUI_GTK
2181 	if (!gui.in_use)		/* don't do this if GTK+ is running */
2182 # endif
2183 	    set_x11_title(title);		/* x11 */
2184 #endif
2185 #if defined(FEAT_GUI_GTK) \
2186 	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
2187 	else
2188 	    gui_mch_settitle(title, icon);
2189 #endif
2190 	unix_did_set_title = TRUE;
2191     }
2192 
2193     if ((type || *T_CIS != NUL) && icon != NULL)
2194     {
2195 	if (oldicon == NULL
2196 #ifdef FEAT_GUI
2197 		&& !gui.in_use
2198 #endif
2199 		)		/* first call, save icon */
2200 	    get_x11_icon(FALSE);
2201 
2202 	if (*T_CIS != NUL)
2203 	{
2204 	    out_str(T_CIS);			/* set icon start */
2205 	    out_str_nf(icon);
2206 	    out_str(T_CIE);			/* set icon end */
2207 	    out_flush();
2208 	}
2209 #ifdef FEAT_X11
2210 	else
2211 # ifdef FEAT_GUI_GTK
2212 	if (!gui.in_use)		/* don't do this if GTK+ is running */
2213 # endif
2214 	    set_x11_icon(icon);			/* x11 */
2215 #endif
2216 	did_set_icon = TRUE;
2217     }
2218     --recursive;
2219 }
2220 
2221 /*
2222  * Restore the window/icon title.
2223  * "which" is one of:
2224  *  SAVE_RESTORE_TITLE only restore title
2225  *  SAVE_RESTORE_ICON  only restore icon
2226  *  SAVE_RESTORE_BOTH  restore title and icon
2227  */
2228     void
2229 mch_restore_title(int which)
2230 {
2231     int	do_push_pop = unix_did_set_title || did_set_icon;
2232 
2233     /* only restore the title or icon when it has been set */
2234     mch_settitle(((which & SAVE_RESTORE_TITLE) && unix_did_set_title) ?
2235 			(oldtitle ? oldtitle : p_titleold) : NULL,
2236 	       ((which & SAVE_RESTORE_ICON) && did_set_icon) ? oldicon : NULL);
2237 
2238     if (do_push_pop)
2239     {
2240 	// pop and push from/to the stack
2241 	term_pop_title(which);
2242 	term_push_title(which);
2243     }
2244 }
2245 
2246 #endif /* FEAT_TITLE */
2247 
2248 /*
2249  * Return TRUE if "name" looks like some xterm name.
2250  * Seiichi Sato mentioned that "mlterm" works like xterm.
2251  */
2252     int
2253 vim_is_xterm(char_u *name)
2254 {
2255     if (name == NULL)
2256 	return FALSE;
2257     return (STRNICMP(name, "xterm", 5) == 0
2258 		|| STRNICMP(name, "nxterm", 6) == 0
2259 		|| STRNICMP(name, "kterm", 5) == 0
2260 		|| STRNICMP(name, "mlterm", 6) == 0
2261 		|| STRNICMP(name, "rxvt", 4) == 0
2262 		|| STRNICMP(name, "screen.xterm", 12) == 0
2263 		|| STRCMP(name, "builtin_xterm") == 0);
2264 }
2265 
2266 #if defined(FEAT_MOUSE_XTERM) || defined(PROTO)
2267 /*
2268  * Return TRUE if "name" appears to be that of a terminal
2269  * known to support the xterm-style mouse protocol.
2270  * Relies on term_is_xterm having been set to its correct value.
2271  */
2272     int
2273 use_xterm_like_mouse(char_u *name)
2274 {
2275     return (name != NULL
2276 	    && (term_is_xterm
2277 		|| STRNICMP(name, "screen", 6) == 0
2278 		|| STRNICMP(name, "tmux", 4) == 0
2279 		|| STRICMP(name, "st") == 0
2280 		|| STRNICMP(name, "st-", 3) == 0
2281 		|| STRNICMP(name, "stterm", 6) == 0));
2282 }
2283 #endif
2284 
2285 #if defined(FEAT_MOUSE_TTY) || defined(PROTO)
2286 /*
2287  * Return non-zero when using an xterm mouse, according to 'ttymouse'.
2288  * Return 1 for "xterm".
2289  * Return 2 for "xterm2".
2290  * Return 3 for "urxvt".
2291  * Return 4 for "sgr".
2292  */
2293     int
2294 use_xterm_mouse(void)
2295 {
2296     if (ttym_flags == TTYM_SGR)
2297 	return 4;
2298     if (ttym_flags == TTYM_URXVT)
2299 	return 3;
2300     if (ttym_flags == TTYM_XTERM2)
2301 	return 2;
2302     if (ttym_flags == TTYM_XTERM)
2303 	return 1;
2304     return 0;
2305 }
2306 #endif
2307 
2308     int
2309 vim_is_iris(char_u *name)
2310 {
2311     if (name == NULL)
2312 	return FALSE;
2313     return (STRNICMP(name, "iris-ansi", 9) == 0
2314 	    || STRCMP(name, "builtin_iris-ansi") == 0);
2315 }
2316 
2317     int
2318 vim_is_vt300(char_u *name)
2319 {
2320     if (name == NULL)
2321 	return FALSE;	       /* actually all ANSI comp. terminals should be here  */
2322     /* catch VT100 - VT5xx */
2323     return ((STRNICMP(name, "vt", 2) == 0
2324 		&& vim_strchr((char_u *)"12345", name[2]) != NULL)
2325 	    || STRCMP(name, "builtin_vt320") == 0);
2326 }
2327 
2328 /*
2329  * Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
2330  * This should include all windowed terminal emulators.
2331  */
2332     int
2333 vim_is_fastterm(char_u *name)
2334 {
2335     if (name == NULL)
2336 	return FALSE;
2337     if (vim_is_xterm(name) || vim_is_vt300(name) || vim_is_iris(name))
2338 	return TRUE;
2339     return (   STRNICMP(name, "hpterm", 6) == 0
2340 	    || STRNICMP(name, "sun-cmd", 7) == 0
2341 	    || STRNICMP(name, "screen", 6) == 0
2342 	    || STRNICMP(name, "tmux", 4) == 0
2343 	    || STRNICMP(name, "dtterm", 6) == 0);
2344 }
2345 
2346 /*
2347  * Insert user name in s[len].
2348  * Return OK if a name found.
2349  */
2350     int
2351 mch_get_user_name(char_u *s, int len)
2352 {
2353 #ifdef VMS
2354     vim_strncpy(s, (char_u *)cuserid(NULL), len - 1);
2355     return OK;
2356 #else
2357     return mch_get_uname(getuid(), s, len);
2358 #endif
2359 }
2360 
2361 /*
2362  * Insert user name for "uid" in s[len].
2363  * Return OK if a name found.
2364  */
2365     int
2366 mch_get_uname(uid_t uid, char_u *s, int len)
2367 {
2368 #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
2369     struct passwd   *pw;
2370 
2371     if ((pw = getpwuid(uid)) != NULL
2372 	    && pw->pw_name != NULL && *(pw->pw_name) != NUL)
2373     {
2374 	vim_strncpy(s, (char_u *)pw->pw_name, len - 1);
2375 	return OK;
2376     }
2377 #endif
2378     sprintf((char *)s, "%d", (int)uid);	    /* assumes s is long enough */
2379     return FAIL;			    /* a number is not a name */
2380 }
2381 
2382 /*
2383  * Insert host name is s[len].
2384  */
2385 
2386 #ifdef HAVE_SYS_UTSNAME_H
2387     void
2388 mch_get_host_name(char_u *s, int len)
2389 {
2390     struct utsname vutsname;
2391 
2392     if (uname(&vutsname) < 0)
2393 	*s = NUL;
2394     else
2395 	vim_strncpy(s, (char_u *)vutsname.nodename, len - 1);
2396 }
2397 #else /* HAVE_SYS_UTSNAME_H */
2398 
2399 # ifdef HAVE_SYS_SYSTEMINFO_H
2400 #  define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len)
2401 # endif
2402 
2403     void
2404 mch_get_host_name(char_u *s, int len)
2405 {
2406 # ifdef VAXC
2407     vaxc$gethostname((char *)s, len);
2408 # else
2409     gethostname((char *)s, len);
2410 # endif
2411     s[len - 1] = NUL;	/* make sure it's terminated */
2412 }
2413 #endif /* HAVE_SYS_UTSNAME_H */
2414 
2415 /*
2416  * return process ID
2417  */
2418     long
2419 mch_get_pid(void)
2420 {
2421     return (long)getpid();
2422 }
2423 
2424 /*
2425  * return TRUE if process "pid" is still running
2426  */
2427     int
2428 mch_process_running(long pid)
2429 {
2430     // EMX kill() not working correctly, it seems
2431     return kill(pid, 0) == 0;
2432 }
2433 
2434 #if !defined(HAVE_STRERROR) && defined(USE_GETCWD)
2435     static char *
2436 strerror(int err)
2437 {
2438     extern int	    sys_nerr;
2439     extern char	    *sys_errlist[];
2440     static char	    er[20];
2441 
2442     if (err > 0 && err < sys_nerr)
2443 	return (sys_errlist[err]);
2444     sprintf(er, "Error %d", err);
2445     return er;
2446 }
2447 #endif
2448 
2449 /*
2450  * Get name of current directory into buffer "buf" of length "len" bytes.
2451  * "len" must be at least PATH_MAX.
2452  * Return OK for success, FAIL for failure.
2453  */
2454     int
2455 mch_dirname(char_u *buf, int len)
2456 {
2457 #if defined(USE_GETCWD)
2458     if (getcwd((char *)buf, len) == NULL)
2459     {
2460 	STRCPY(buf, strerror(errno));
2461 	return FAIL;
2462     }
2463     return OK;
2464 #else
2465     return (getwd((char *)buf) != NULL ? OK : FAIL);
2466 #endif
2467 }
2468 
2469 /*
2470  * Get absolute file name into "buf[len]".
2471  *
2472  * return FAIL for failure, OK for success
2473  */
2474     int
2475 mch_FullName(
2476     char_u	*fname,
2477     char_u	*buf,
2478     int		len,
2479     int		force)		/* also expand when already absolute path */
2480 {
2481     int		l;
2482 #ifdef HAVE_FCHDIR
2483     int		fd = -1;
2484     static int	dont_fchdir = FALSE;	/* TRUE when fchdir() doesn't work */
2485 #endif
2486     char_u	olddir[MAXPATHL];
2487     char_u	*p;
2488     int		retval = OK;
2489 #ifdef __CYGWIN__
2490     char_u	posix_fname[MAXPATHL];	/* Cygwin docs mention MAX_PATH, but
2491 					   it's not always defined */
2492 #endif
2493 
2494 #ifdef VMS
2495     fname = vms_fixfilename(fname);
2496 #endif
2497 
2498 #ifdef __CYGWIN__
2499     /*
2500      * This helps for when "/etc/hosts" is a symlink to "c:/something/hosts".
2501      */
2502 # if CYGWIN_VERSION_DLL_MAJOR >= 1007
2503     /* Use CCP_RELATIVE to avoid that it sometimes returns a path that ends in
2504      * a forward slash. */
2505     cygwin_conv_path(CCP_WIN_A_TO_POSIX | CCP_RELATIVE,
2506 		     fname, posix_fname, MAXPATHL);
2507 # else
2508     cygwin_conv_to_posix_path(fname, posix_fname);
2509 # endif
2510     fname = posix_fname;
2511 #endif
2512 
2513     /* Expand it if forced or not an absolute path.
2514      * Do not do it for "/file", the result is always "/". */
2515     if ((force || !mch_isFullName(fname))
2516 	    && ((p = vim_strrchr(fname, '/')) == NULL || p != fname))
2517     {
2518 	/*
2519 	 * If the file name has a path, change to that directory for a moment,
2520 	 * and then get the directory (and get back to where we were).
2521 	 * This will get the correct path name with "../" things.
2522 	 */
2523 	if (p != NULL)
2524 	{
2525 #ifdef HAVE_FCHDIR
2526 	    /*
2527 	     * Use fchdir() if possible, it's said to be faster and more
2528 	     * reliable.  But on SunOS 4 it might not work.  Check this by
2529 	     * doing a fchdir() right now.
2530 	     */
2531 	    if (!dont_fchdir)
2532 	    {
2533 		fd = open(".", O_RDONLY | O_EXTRA, 0);
2534 		if (fd >= 0 && fchdir(fd) < 0)
2535 		{
2536 		    close(fd);
2537 		    fd = -1;
2538 		    dont_fchdir = TRUE;	    /* don't try again */
2539 		}
2540 	    }
2541 #endif
2542 
2543 	    /* Only change directory when we are sure we can return to where
2544 	     * we are now.  After doing "su" chdir(".") might not work. */
2545 	    if (
2546 #ifdef HAVE_FCHDIR
2547 		fd < 0 &&
2548 #endif
2549 			(mch_dirname(olddir, MAXPATHL) == FAIL
2550 					   || mch_chdir((char *)olddir) != 0))
2551 	    {
2552 		p = NULL;	/* can't get current dir: don't chdir */
2553 		retval = FAIL;
2554 	    }
2555 	    else
2556 	    {
2557 		/* The directory is copied into buf[], to be able to remove
2558 		 * the file name without changing it (could be a string in
2559 		 * read-only memory) */
2560 		if (p - fname >= len)
2561 		    retval = FAIL;
2562 		else
2563 		{
2564 		    vim_strncpy(buf, fname, p - fname);
2565 		    if (mch_chdir((char *)buf))
2566 			retval = FAIL;
2567 		    else
2568 			fname = p + 1;
2569 		    *buf = NUL;
2570 		}
2571 	    }
2572 	}
2573 	if (mch_dirname(buf, len) == FAIL)
2574 	{
2575 	    retval = FAIL;
2576 	    *buf = NUL;
2577 	}
2578 	if (p != NULL)
2579 	{
2580 #ifdef HAVE_FCHDIR
2581 	    if (fd >= 0)
2582 	    {
2583 		if (p_verbose >= 5)
2584 		{
2585 		    verbose_enter();
2586 		    msg("fchdir() to previous dir");
2587 		    verbose_leave();
2588 		}
2589 		l = fchdir(fd);
2590 		close(fd);
2591 	    }
2592 	    else
2593 #endif
2594 		l = mch_chdir((char *)olddir);
2595 	    if (l != 0)
2596 		emsg(_(e_prev_dir));
2597 	}
2598 
2599 	l = STRLEN(buf);
2600 	if (l >= len - 1)
2601 	    retval = FAIL; /* no space for trailing "/" */
2602 #ifndef VMS
2603 	else if (l > 0 && buf[l - 1] != '/' && *fname != NUL
2604 						   && STRCMP(fname, ".") != 0)
2605 	    STRCAT(buf, "/");
2606 #endif
2607     }
2608 
2609     /* Catch file names which are too long. */
2610     if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len)
2611 	return FAIL;
2612 
2613     /* Do not append ".", "/dir/." is equal to "/dir". */
2614     if (STRCMP(fname, ".") != 0)
2615 	STRCAT(buf, fname);
2616 
2617     return OK;
2618 }
2619 
2620 /*
2621  * Return TRUE if "fname" does not depend on the current directory.
2622  */
2623     int
2624 mch_isFullName(char_u *fname)
2625 {
2626 #ifdef VMS
2627     return ( fname[0] == '/'	       || fname[0] == '.'	    ||
2628 	     strchr((char *)fname,':') || strchr((char *)fname,'"') ||
2629 	    (strchr((char *)fname,'[') && strchr((char *)fname,']'))||
2630 	    (strchr((char *)fname,'<') && strchr((char *)fname,'>'))   );
2631 #else
2632     return (*fname == '/' || *fname == '~');
2633 #endif
2634 }
2635 
2636 #if defined(USE_FNAME_CASE) || defined(PROTO)
2637 /*
2638  * Set the case of the file name, if it already exists.  This will cause the
2639  * file name to remain exactly the same.
2640  * Only required for file systems where case is ignored and preserved.
2641  */
2642     void
2643 fname_case(
2644     char_u	*name,
2645     int		len UNUSED)  /* buffer size, only used when name gets longer */
2646 {
2647     struct stat st;
2648     char_u	*slash, *tail;
2649     DIR		*dirp;
2650     struct dirent *dp;
2651 
2652     if (mch_lstat((char *)name, &st) >= 0)
2653     {
2654 	/* Open the directory where the file is located. */
2655 	slash = vim_strrchr(name, '/');
2656 	if (slash == NULL)
2657 	{
2658 	    dirp = opendir(".");
2659 	    tail = name;
2660 	}
2661 	else
2662 	{
2663 	    *slash = NUL;
2664 	    dirp = opendir((char *)name);
2665 	    *slash = '/';
2666 	    tail = slash + 1;
2667 	}
2668 
2669 	if (dirp != NULL)
2670 	{
2671 	    while ((dp = readdir(dirp)) != NULL)
2672 	    {
2673 		/* Only accept names that differ in case and are the same byte
2674 		 * length. TODO: accept different length name. */
2675 		if (STRICMP(tail, dp->d_name) == 0
2676 			&& STRLEN(tail) == STRLEN(dp->d_name))
2677 		{
2678 		    char_u	newname[MAXPATHL + 1];
2679 		    struct stat st2;
2680 
2681 		    /* Verify the inode is equal. */
2682 		    vim_strncpy(newname, name, MAXPATHL);
2683 		    vim_strncpy(newname + (tail - name), (char_u *)dp->d_name,
2684 						    MAXPATHL - (tail - name));
2685 		    if (mch_lstat((char *)newname, &st2) >= 0
2686 			    && st.st_ino == st2.st_ino
2687 			    && st.st_dev == st2.st_dev)
2688 		    {
2689 			STRCPY(tail, dp->d_name);
2690 			break;
2691 		    }
2692 		}
2693 	    }
2694 
2695 	    closedir(dirp);
2696 	}
2697     }
2698 }
2699 #endif
2700 
2701 /*
2702  * Get file permissions for 'name'.
2703  * Returns -1 when it doesn't exist.
2704  */
2705     long
2706 mch_getperm(char_u *name)
2707 {
2708     struct stat statb;
2709 
2710     /* Keep the #ifdef outside of stat(), it may be a macro. */
2711 #ifdef VMS
2712     if (stat((char *)vms_fixfilename(name), &statb))
2713 #else
2714     if (stat((char *)name, &statb))
2715 #endif
2716 	return -1;
2717 #ifdef __INTERIX
2718     /* The top bit makes the value negative, which means the file doesn't
2719      * exist.  Remove the bit, we don't use it. */
2720     return statb.st_mode & ~S_ADDACE;
2721 #else
2722     return statb.st_mode;
2723 #endif
2724 }
2725 
2726 /*
2727  * Set file permission for "name" to "perm".
2728  * Return FAIL for failure, OK otherwise.
2729  */
2730     int
2731 mch_setperm(char_u *name, long perm)
2732 {
2733     return (chmod((char *)
2734 #ifdef VMS
2735 		    vms_fixfilename(name),
2736 #else
2737 		    name,
2738 #endif
2739 		    (mode_t)perm) == 0 ? OK : FAIL);
2740 }
2741 
2742 #if defined(HAVE_FCHMOD) || defined(PROTO)
2743 /*
2744  * Set file permission for open file "fd" to "perm".
2745  * Return FAIL for failure, OK otherwise.
2746  */
2747     int
2748 mch_fsetperm(int fd, long perm)
2749 {
2750     return (fchmod(fd, (mode_t)perm) == 0 ? OK : FAIL);
2751 }
2752 #endif
2753 
2754 #if defined(HAVE_ACL) || defined(PROTO)
2755 # ifdef HAVE_SYS_ACL_H
2756 #  include <sys/acl.h>
2757 # endif
2758 # ifdef HAVE_SYS_ACCESS_H
2759 #  include <sys/access.h>
2760 # endif
2761 
2762 # ifdef HAVE_SOLARIS_ACL
2763 typedef struct vim_acl_solaris_T {
2764     int acl_cnt;
2765     aclent_t *acl_entry;
2766 } vim_acl_solaris_T;
2767 # endif
2768 
2769 #if defined(HAVE_SELINUX) || defined(PROTO)
2770 /*
2771  * Copy security info from "from_file" to "to_file".
2772  */
2773     void
2774 mch_copy_sec(char_u *from_file, char_u *to_file)
2775 {
2776     if (from_file == NULL)
2777 	return;
2778 
2779     if (selinux_enabled == -1)
2780 	selinux_enabled = is_selinux_enabled();
2781 
2782     if (selinux_enabled > 0)
2783     {
2784 	security_context_t from_context = NULL;
2785 	security_context_t to_context = NULL;
2786 
2787 	if (getfilecon((char *)from_file, &from_context) < 0)
2788 	{
2789 	    /* If the filesystem doesn't support extended attributes,
2790 	       the original had no special security context and the
2791 	       target cannot have one either.  */
2792 	    if (errno == EOPNOTSUPP)
2793 		return;
2794 
2795 	    msg_puts(_("\nCould not get security context for "));
2796 	    msg_outtrans(from_file);
2797 	    msg_putchar('\n');
2798 	    return;
2799 	}
2800 	if (getfilecon((char *)to_file, &to_context) < 0)
2801 	{
2802 	    msg_puts(_("\nCould not get security context for "));
2803 	    msg_outtrans(to_file);
2804 	    msg_putchar('\n');
2805 	    freecon (from_context);
2806 	    return ;
2807 	}
2808 	if (strcmp(from_context, to_context) != 0)
2809 	{
2810 	    if (setfilecon((char *)to_file, from_context) < 0)
2811 	    {
2812 		msg_puts(_("\nCould not set security context for "));
2813 		msg_outtrans(to_file);
2814 		msg_putchar('\n');
2815 	    }
2816 	}
2817 	freecon(to_context);
2818 	freecon(from_context);
2819     }
2820 }
2821 #endif /* HAVE_SELINUX */
2822 
2823 #if defined(HAVE_SMACK) && !defined(PROTO)
2824 /*
2825  * Copy security info from "from_file" to "to_file".
2826  */
2827     void
2828 mch_copy_sec(char_u *from_file, char_u *to_file)
2829 {
2830     static const char * const smack_copied_attributes[] =
2831 	{
2832 	    XATTR_NAME_SMACK,
2833 	    XATTR_NAME_SMACKEXEC,
2834 	    XATTR_NAME_SMACKMMAP
2835 	};
2836 
2837     char	buffer[SMACK_LABEL_LEN];
2838     const char	*name;
2839     int		index;
2840     int		ret;
2841     ssize_t	size;
2842 
2843     if (from_file == NULL)
2844 	return;
2845 
2846     for (index = 0 ; index < (int)(sizeof(smack_copied_attributes)
2847 			      / sizeof(smack_copied_attributes)[0]) ; index++)
2848     {
2849 	/* get the name of the attribute to copy */
2850 	name = smack_copied_attributes[index];
2851 
2852 	/* get the value of the attribute in buffer */
2853 	size = getxattr((char*)from_file, name, buffer, sizeof(buffer));
2854 	if (size >= 0)
2855 	{
2856 	    /* copy the attribute value of buffer */
2857 	    ret = setxattr((char*)to_file, name, buffer, (size_t)size, 0);
2858 	    if (ret < 0)
2859 	    {
2860 		vim_snprintf((char *)IObuff, IOSIZE,
2861 			_("Could not set security context %s for %s"),
2862 			name, to_file);
2863 		msg_outtrans(IObuff);
2864 		msg_putchar('\n');
2865 	    }
2866 	}
2867 	else
2868 	{
2869 	    /* what reason of not having the attribute value? */
2870 	    switch (errno)
2871 	    {
2872 		case ENOTSUP:
2873 		    /* extended attributes aren't supported or enabled */
2874 		    /* should a message be echoed? not sure... */
2875 		    return; /* leave because it isn't useful to continue */
2876 
2877 		case ERANGE:
2878 		default:
2879 		    /* no enough size OR unexpected error */
2880 		     vim_snprintf((char *)IObuff, IOSIZE,
2881 			    _("Could not get security context %s for %s. Removing it!"),
2882 			    name, from_file);
2883 		    msg_puts((char *)IObuff);
2884 		    msg_putchar('\n');
2885 		    /* FALLTHROUGH to remove the attribute */
2886 
2887 		case ENODATA:
2888 		    /* no attribute of this name */
2889 		    ret = removexattr((char*)to_file, name);
2890 		    /* Silently ignore errors, apparently this happens when
2891 		     * smack is not actually being used. */
2892 		    break;
2893 	    }
2894 	}
2895     }
2896 }
2897 #endif /* HAVE_SMACK */
2898 
2899 /*
2900  * Return a pointer to the ACL of file "fname" in allocated memory.
2901  * Return NULL if the ACL is not available for whatever reason.
2902  */
2903     vim_acl_T
2904 mch_get_acl(char_u *fname UNUSED)
2905 {
2906     vim_acl_T	ret = NULL;
2907 #ifdef HAVE_POSIX_ACL
2908     ret = (vim_acl_T)acl_get_file((char *)fname, ACL_TYPE_ACCESS);
2909 #else
2910 #ifdef HAVE_SOLARIS_ZFS_ACL
2911     acl_t *aclent;
2912 
2913     if (acl_get((char *)fname, 0, &aclent) < 0)
2914 	return NULL;
2915     ret = (vim_acl_T)aclent;
2916 #else
2917 #ifdef HAVE_SOLARIS_ACL
2918     vim_acl_solaris_T   *aclent;
2919 
2920     aclent = malloc(sizeof(vim_acl_solaris_T));
2921     if ((aclent->acl_cnt = acl((char *)fname, GETACLCNT, 0, NULL)) < 0)
2922     {
2923 	free(aclent);
2924 	return NULL;
2925     }
2926     aclent->acl_entry = malloc(aclent->acl_cnt * sizeof(aclent_t));
2927     if (acl((char *)fname, GETACL, aclent->acl_cnt, aclent->acl_entry) < 0)
2928     {
2929 	free(aclent->acl_entry);
2930 	free(aclent);
2931 	return NULL;
2932     }
2933     ret = (vim_acl_T)aclent;
2934 #else
2935 #if defined(HAVE_AIX_ACL)
2936     int		aclsize;
2937     struct acl *aclent;
2938 
2939     aclsize = sizeof(struct acl);
2940     aclent = malloc(aclsize);
2941     if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
2942     {
2943 	if (errno == ENOSPC)
2944 	{
2945 	    aclsize = aclent->acl_len;
2946 	    aclent = realloc(aclent, aclsize);
2947 	    if (statacl((char *)fname, STX_NORMAL, aclent, aclsize) < 0)
2948 	    {
2949 		free(aclent);
2950 		return NULL;
2951 	    }
2952 	}
2953 	else
2954 	{
2955 	    free(aclent);
2956 	    return NULL;
2957 	}
2958     }
2959     ret = (vim_acl_T)aclent;
2960 #endif /* HAVE_AIX_ACL */
2961 #endif /* HAVE_SOLARIS_ACL */
2962 #endif /* HAVE_SOLARIS_ZFS_ACL */
2963 #endif /* HAVE_POSIX_ACL */
2964     return ret;
2965 }
2966 
2967 /*
2968  * Set the ACL of file "fname" to "acl" (unless it's NULL).
2969  */
2970     void
2971 mch_set_acl(char_u *fname UNUSED, vim_acl_T aclent)
2972 {
2973     if (aclent == NULL)
2974 	return;
2975 #ifdef HAVE_POSIX_ACL
2976     acl_set_file((char *)fname, ACL_TYPE_ACCESS, (acl_t)aclent);
2977 #else
2978 #ifdef HAVE_SOLARIS_ZFS_ACL
2979     acl_set((char *)fname, (acl_t *)aclent);
2980 #else
2981 #ifdef HAVE_SOLARIS_ACL
2982     acl((char *)fname, SETACL, ((vim_acl_solaris_T *)aclent)->acl_cnt,
2983 	    ((vim_acl_solaris_T *)aclent)->acl_entry);
2984 #else
2985 #ifdef HAVE_AIX_ACL
2986     chacl((char *)fname, aclent, ((struct acl *)aclent)->acl_len);
2987 #endif /* HAVE_AIX_ACL */
2988 #endif /* HAVE_SOLARIS_ACL */
2989 #endif /* HAVE_SOLARIS_ZFS_ACL */
2990 #endif /* HAVE_POSIX_ACL */
2991 }
2992 
2993     void
2994 mch_free_acl(vim_acl_T aclent)
2995 {
2996     if (aclent == NULL)
2997 	return;
2998 #ifdef HAVE_POSIX_ACL
2999     acl_free((acl_t)aclent);
3000 #else
3001 #ifdef HAVE_SOLARIS_ZFS_ACL
3002     acl_free((acl_t *)aclent);
3003 #else
3004 #ifdef HAVE_SOLARIS_ACL
3005     free(((vim_acl_solaris_T *)aclent)->acl_entry);
3006     free(aclent);
3007 #else
3008 #ifdef HAVE_AIX_ACL
3009     free(aclent);
3010 #endif /* HAVE_AIX_ACL */
3011 #endif /* HAVE_SOLARIS_ACL */
3012 #endif /* HAVE_SOLARIS_ZFS_ACL */
3013 #endif /* HAVE_POSIX_ACL */
3014 }
3015 #endif
3016 
3017 /*
3018  * Set hidden flag for "name".
3019  */
3020     void
3021 mch_hide(char_u *name UNUSED)
3022 {
3023     /* can't hide a file */
3024 }
3025 
3026 /*
3027  * return TRUE if "name" is a directory or a symlink to a directory
3028  * return FALSE if "name" is not a directory
3029  * return FALSE for error
3030  */
3031     int
3032 mch_isdir(char_u *name)
3033 {
3034     struct stat statb;
3035 
3036     if (*name == NUL)	    /* Some stat()s don't flag "" as an error. */
3037 	return FALSE;
3038     if (stat((char *)name, &statb))
3039 	return FALSE;
3040     return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
3041 }
3042 
3043 /*
3044  * return TRUE if "name" is a directory, NOT a symlink to a directory
3045  * return FALSE if "name" is not a directory
3046  * return FALSE for error
3047  */
3048     int
3049 mch_isrealdir(char_u *name)
3050 {
3051     struct stat statb;
3052 
3053     if (*name == NUL)	    /* Some stat()s don't flag "" as an error. */
3054 	return FALSE;
3055     if (mch_lstat((char *)name, &statb))
3056 	return FALSE;
3057     return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
3058 }
3059 
3060 /*
3061  * Return 1 if "name" is an executable file, 0 if not or it doesn't exist.
3062  */
3063     static int
3064 executable_file(char_u *name)
3065 {
3066     struct stat	st;
3067 
3068     if (stat((char *)name, &st))
3069 	return 0;
3070 #ifdef VMS
3071     /* Like on Unix system file can have executable rights but not necessarily
3072      * be an executable, but on Unix is not a default for an ordianry file to
3073      * have an executable flag - on VMS it is in most cases.
3074      * Therefore, this check does not have any sense - let keep us to the
3075      * conventions instead:
3076      * *.COM and *.EXE files are the executables - the rest are not. This is
3077      * not ideal but better then it was.
3078      */
3079     int vms_executable = 0;
3080     if (S_ISREG(st.st_mode) && mch_access((char *)name, X_OK) == 0)
3081     {
3082 	if (strstr(vms_tolower((char*)name),".exe") != NULL
3083 		|| strstr(vms_tolower((char*)name),".com")!= NULL)
3084 	    vms_executable = 1;
3085     }
3086     return vms_executable;
3087 #else
3088     return S_ISREG(st.st_mode) && mch_access((char *)name, X_OK) == 0;
3089 #endif
3090 }
3091 
3092 /*
3093  * Return TRUE if "name" can be found in $PATH and executed, FALSE if not.
3094  * If "use_path" is FALSE only check if "name" is executable.
3095  * Return -1 if unknown.
3096  */
3097     int
3098 mch_can_exe(char_u *name, char_u **path, int use_path)
3099 {
3100     char_u	*buf;
3101     char_u	*p, *e;
3102     int		retval;
3103 
3104     /* When "use_path" is false and if it's an absolute or relative path don't
3105      * need to use $PATH. */
3106     if (!use_path || gettail(name) != name)
3107     {
3108 	/* There must be a path separator, files in the current directory
3109 	 * can't be executed. */
3110 	if ((use_path || gettail(name) != name) && executable_file(name))
3111 	{
3112 	    if (path != NULL)
3113 	    {
3114 		if (name[0] != '/')
3115 		    *path = FullName_save(name, TRUE);
3116 		else
3117 		    *path = vim_strsave(name);
3118 	    }
3119 	    return TRUE;
3120 	}
3121 	return FALSE;
3122     }
3123 
3124     p = (char_u *)getenv("PATH");
3125     if (p == NULL || *p == NUL)
3126 	return -1;
3127     buf = alloc(STRLEN(name) + STRLEN(p) + 2);
3128     if (buf == NULL)
3129 	return -1;
3130 
3131     /*
3132      * Walk through all entries in $PATH to check if "name" exists there and
3133      * is an executable file.
3134      */
3135     for (;;)
3136     {
3137 	e = (char_u *)strchr((char *)p, ':');
3138 	if (e == NULL)
3139 	    e = p + STRLEN(p);
3140 	if (e - p <= 1)		/* empty entry means current dir */
3141 	    STRCPY(buf, "./");
3142 	else
3143 	{
3144 	    vim_strncpy(buf, p, e - p);
3145 	    add_pathsep(buf);
3146 	}
3147 	STRCAT(buf, name);
3148 	retval = executable_file(buf);
3149 	if (retval == 1)
3150 	{
3151 	    if (path != NULL)
3152 	    {
3153 		if (buf[0] != '/')
3154 		    *path = FullName_save(buf, TRUE);
3155 		else
3156 		    *path = vim_strsave(buf);
3157 	    }
3158 	    break;
3159 	}
3160 
3161 	if (*e != ':')
3162 	    break;
3163 	p = e + 1;
3164     }
3165 
3166     vim_free(buf);
3167     return retval;
3168 }
3169 
3170 /*
3171  * Check what "name" is:
3172  * NODE_NORMAL: file or directory (or doesn't exist)
3173  * NODE_WRITABLE: writable device, socket, fifo, etc.
3174  * NODE_OTHER: non-writable things
3175  */
3176     int
3177 mch_nodetype(char_u *name)
3178 {
3179     struct stat	st;
3180 
3181     if (stat((char *)name, &st))
3182 	return NODE_NORMAL;
3183     if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
3184 	return NODE_NORMAL;
3185     if (S_ISBLK(st.st_mode))	/* block device isn't writable */
3186 	return NODE_OTHER;
3187     /* Everything else is writable? */
3188     return NODE_WRITABLE;
3189 }
3190 
3191     void
3192 mch_early_init(void)
3193 {
3194 #ifdef HAVE_CHECK_STACK_GROWTH
3195     int			i;
3196 
3197     check_stack_growth((char *)&i);
3198 
3199 # ifdef HAVE_STACK_LIMIT
3200     get_stack_limit();
3201 # endif
3202 
3203 #endif
3204 
3205     /*
3206      * Setup an alternative stack for signals.  Helps to catch signals when
3207      * running out of stack space.
3208      * Use of sigaltstack() is preferred, it's more portable.
3209      * Ignore any errors.
3210      */
3211 #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
3212     signal_stack = alloc(SIGSTKSZ);
3213     init_signal_stack();
3214 #endif
3215 }
3216 
3217 #if defined(EXITFREE) || defined(PROTO)
3218     void
3219 mch_free_mem(void)
3220 {
3221 # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
3222     if (clip_star.owned)
3223 	clip_lose_selection(&clip_star);
3224     if (clip_plus.owned)
3225 	clip_lose_selection(&clip_plus);
3226 # endif
3227 # if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
3228     if (xterm_Shell != (Widget)0)
3229 	XtDestroyWidget(xterm_Shell);
3230 #  ifndef LESSTIF_VERSION
3231     /* Lesstif crashes here, lose some memory */
3232     if (xterm_dpy != NULL)
3233 	XtCloseDisplay(xterm_dpy);
3234     if (app_context != (XtAppContext)NULL)
3235     {
3236 	XtDestroyApplicationContext(app_context);
3237 #   ifdef FEAT_X11
3238 	x11_display = NULL; /* freed by XtDestroyApplicationContext() */
3239 #   endif
3240     }
3241 #  endif
3242 # endif
3243 # if defined(FEAT_X11)
3244     if (x11_display != NULL
3245 #  ifdef FEAT_XCLIPBOARD
3246 	    && x11_display != xterm_dpy
3247 #  endif
3248 	    )
3249 	XCloseDisplay(x11_display);
3250 # endif
3251 # if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
3252     VIM_CLEAR(signal_stack);
3253 # endif
3254 # ifdef FEAT_TITLE
3255     vim_free(oldtitle);
3256     vim_free(oldicon);
3257 # endif
3258 }
3259 #endif
3260 
3261 /*
3262  * Output a newline when exiting.
3263  * Make sure the newline goes to the same stream as the text.
3264  */
3265     static void
3266 exit_scroll(void)
3267 {
3268     if (silent_mode)
3269 	return;
3270     if (newline_on_exit || msg_didout)
3271     {
3272 	if (msg_use_printf())
3273 	{
3274 	    if (info_message)
3275 		mch_msg("\n");
3276 	    else
3277 		mch_errmsg("\r\n");
3278 	}
3279 	else
3280 	    out_char('\n');
3281     }
3282     else
3283     {
3284 	restore_cterm_colors();		/* get original colors back */
3285 	msg_clr_eos_force();		/* clear the rest of the display */
3286 	windgoto((int)Rows - 1, 0);	/* may have moved the cursor */
3287     }
3288 }
3289 
3290     void
3291 mch_exit(int r)
3292 {
3293     exiting = TRUE;
3294 
3295 #if defined(FEAT_X11) && defined(FEAT_CLIPBOARD)
3296     x11_export_final_selection();
3297 #endif
3298 
3299 #ifdef FEAT_GUI
3300     if (!gui.in_use)
3301 #endif
3302     {
3303 	settmode(TMODE_COOK);
3304 #ifdef FEAT_TITLE
3305 	// restore xterm title and icon name
3306 	mch_restore_title(SAVE_RESTORE_BOTH);
3307 	term_pop_title(SAVE_RESTORE_BOTH);
3308 #endif
3309 	/*
3310 	 * When t_ti is not empty but it doesn't cause swapping terminal
3311 	 * pages, need to output a newline when msg_didout is set.  But when
3312 	 * t_ti does swap pages it should not go to the shell page.  Do this
3313 	 * before stoptermcap().
3314 	 */
3315 	if (swapping_screen() && !newline_on_exit)
3316 	    exit_scroll();
3317 
3318 	/* Stop termcap: May need to check for T_CRV response, which
3319 	 * requires RAW mode. */
3320 	stoptermcap();
3321 
3322 	/*
3323 	 * A newline is only required after a message in the alternate screen.
3324 	 * This is set to TRUE by wait_return().
3325 	 */
3326 	if (!swapping_screen() || newline_on_exit)
3327 	    exit_scroll();
3328 
3329 	/* Cursor may have been switched off without calling starttermcap()
3330 	 * when doing "vim -u vimrc" and vimrc contains ":q". */
3331 	if (full_screen)
3332 	    cursor_on();
3333     }
3334     out_flush();
3335     ml_close_all(TRUE);		/* remove all memfiles */
3336     may_core_dump();
3337 #ifdef FEAT_GUI
3338     if (gui.in_use)
3339 	gui_exit(r);
3340 #endif
3341 
3342 #ifdef MACOS_CONVERT
3343     mac_conv_cleanup();
3344 #endif
3345 
3346 #ifdef __QNX__
3347     /* A core dump won't be created if the signal handler
3348      * doesn't return, so we can't call exit() */
3349     if (deadly_signal != 0)
3350 	return;
3351 #endif
3352 
3353 #ifdef FEAT_NETBEANS_INTG
3354     netbeans_send_disconnect();
3355 #endif
3356 
3357 #ifdef EXITFREE
3358     free_all_mem();
3359 #endif
3360 
3361     exit(r);
3362 }
3363 
3364     static void
3365 may_core_dump(void)
3366 {
3367     if (deadly_signal != 0)
3368     {
3369 	signal(deadly_signal, SIG_DFL);
3370 	kill(getpid(), deadly_signal);	/* Die using the signal we caught */
3371     }
3372 }
3373 
3374 #ifndef VMS
3375 
3376 /*
3377  * Get the file descriptor to use for tty operations.
3378  */
3379     static int
3380 get_tty_fd(int fd)
3381 {
3382     int		tty_fd = fd;
3383 
3384 #if defined(HAVE_SVR4_PTYS) && defined(SUN_SYSTEM)
3385     // On SunOS: Get the terminal parameters from "fd", or the slave device of
3386     // "fd" when it is a master device.
3387     if (mch_isatty(fd) > 1)
3388     {
3389 	char *name;
3390 
3391 	name = ptsname(fd);
3392 	if (name == NULL)
3393 	    return -1;
3394 
3395 	tty_fd = open(name, O_RDONLY | O_NOCTTY | O_EXTRA, 0);
3396 	if (tty_fd < 0)
3397 	    return -1;
3398     }
3399 #endif
3400     return tty_fd;
3401 }
3402 
3403     static int
3404 mch_tcgetattr(int fd, void *term)
3405 {
3406     int		tty_fd;
3407     int		retval = -1;
3408 
3409     tty_fd = get_tty_fd(fd);
3410     if (tty_fd >= 0)
3411     {
3412 #ifdef NEW_TTY_SYSTEM
3413 # ifdef HAVE_TERMIOS_H
3414 	retval = tcgetattr(tty_fd, (struct termios *)term);
3415 # else
3416 	retval = ioctl(tty_fd, TCGETA, (struct termio *)term);
3417 # endif
3418 #else
3419 	// for "old" tty systems
3420 	retval = ioctl(tty_fd, TIOCGETP, (struct sgttyb *)term);
3421 #endif
3422 	if (tty_fd != fd)
3423 	    close(tty_fd);
3424     }
3425     return retval;
3426 }
3427 
3428     void
3429 mch_settmode(int tmode)
3430 {
3431     static int first = TRUE;
3432 
3433 #ifdef NEW_TTY_SYSTEM
3434 # ifdef HAVE_TERMIOS_H
3435     static struct termios told;
3436 	   struct termios tnew;
3437 # else
3438     static struct termio told;
3439 	   struct termio tnew;
3440 # endif
3441 
3442     if (first)
3443     {
3444 	first = FALSE;
3445 	mch_tcgetattr(read_cmd_fd, &told);
3446     }
3447 
3448     tnew = told;
3449     if (tmode == TMODE_RAW)
3450     {
3451 	/*
3452 	 * ~ICRNL enables typing ^V^M
3453 	 */
3454 	tnew.c_iflag &= ~ICRNL;
3455 	tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
3456 # if defined(IEXTEN) && !defined(__MINT__)
3457 		    | IEXTEN	    /* IEXTEN enables typing ^V on SOLARIS */
3458 				    /* but it breaks function keys on MINT */
3459 # endif
3460 				);
3461 # ifdef ONLCR	    /* don't map NL -> CR NL, we do it ourselves */
3462 	tnew.c_oflag &= ~ONLCR;
3463 # endif
3464 	tnew.c_cc[VMIN] = 1;		/* return after 1 char */
3465 	tnew.c_cc[VTIME] = 0;		/* don't wait */
3466     }
3467     else if (tmode == TMODE_SLEEP)
3468     {
3469 	/* Also reset ICANON here, otherwise on Solaris select() won't see
3470 	 * typeahead characters. */
3471 	tnew.c_lflag &= ~(ICANON | ECHO);
3472 	tnew.c_cc[VMIN] = 1;		/* return after 1 char */
3473 	tnew.c_cc[VTIME] = 0;		/* don't wait */
3474     }
3475 
3476 # if defined(HAVE_TERMIOS_H)
3477     {
3478 	int	n = 10;
3479 
3480 	/* A signal may cause tcsetattr() to fail (e.g., SIGCONT).  Retry a
3481 	 * few times. */
3482 	while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
3483 						   && errno == EINTR && n > 0)
3484 	    --n;
3485     }
3486 # else
3487     ioctl(read_cmd_fd, TCSETA, &tnew);
3488 # endif
3489 
3490 #else
3491     /*
3492      * for "old" tty systems
3493      */
3494 # ifndef TIOCSETN
3495 #  define TIOCSETN TIOCSETP	/* for hpux 9.0 */
3496 # endif
3497     static struct sgttyb ttybold;
3498 	   struct sgttyb ttybnew;
3499 
3500     if (first)
3501     {
3502 	first = FALSE;
3503 	mch_tcgetattr(read_cmd_fd, &ttybold);
3504     }
3505 
3506     ttybnew = ttybold;
3507     if (tmode == TMODE_RAW)
3508     {
3509 	ttybnew.sg_flags &= ~(CRMOD | ECHO);
3510 	ttybnew.sg_flags |= RAW;
3511     }
3512     else if (tmode == TMODE_SLEEP)
3513 	ttybnew.sg_flags &= ~(ECHO);
3514     ioctl(read_cmd_fd, TIOCSETN, &ttybnew);
3515 #endif
3516     curr_tmode = tmode;
3517 }
3518 
3519 /*
3520  * Try to get the code for "t_kb" from the stty setting
3521  *
3522  * Even if termcap claims a backspace key, the user's setting *should*
3523  * prevail.  stty knows more about reality than termcap does, and if
3524  * somebody's usual erase key is DEL (which, for most BSD users, it will
3525  * be), they're going to get really annoyed if their erase key starts
3526  * doing forward deletes for no reason. (Eric Fischer)
3527  */
3528     void
3529 get_stty(void)
3530 {
3531     ttyinfo_T	info;
3532     char_u	buf[2];
3533     char_u	*p;
3534 
3535     if (get_tty_info(read_cmd_fd, &info) == OK)
3536     {
3537 	intr_char = info.interrupt;
3538 	buf[0] = info.backspace;
3539 	buf[1] = NUL;
3540 	add_termcode((char_u *)"kb", buf, FALSE);
3541 
3542 	/* If <BS> and <DEL> are now the same, redefine <DEL>. */
3543 	p = find_termcode((char_u *)"kD");
3544 	if (p != NULL && p[0] == buf[0] && p[1] == buf[1])
3545 	    do_fixdel(NULL);
3546     }
3547 }
3548 
3549 /*
3550  * Obtain the characters that Backspace and Enter produce on "fd".
3551  * Returns OK or FAIL.
3552  */
3553     int
3554 get_tty_info(int fd, ttyinfo_T *info)
3555 {
3556 #ifdef NEW_TTY_SYSTEM
3557 # ifdef HAVE_TERMIOS_H
3558     struct termios keys;
3559 # else
3560     struct termio keys;
3561 # endif
3562 
3563     if (mch_tcgetattr(fd, &keys) != -1)
3564     {
3565 	info->backspace = keys.c_cc[VERASE];
3566 	info->interrupt = keys.c_cc[VINTR];
3567 	if (keys.c_iflag & ICRNL)
3568 	    info->enter = NL;
3569 	else
3570 	    info->enter = CAR;
3571 	if (keys.c_oflag & ONLCR)
3572 	    info->nl_does_cr = TRUE;
3573 	else
3574 	    info->nl_does_cr = FALSE;
3575 	return OK;
3576     }
3577 #else
3578     /* for "old" tty systems */
3579     struct sgttyb keys;
3580 
3581     if (mch_tcgetattr(fd, &keys) != -1)
3582     {
3583 	info->backspace = keys.sg_erase;
3584 	info->interrupt = keys.sg_kill;
3585 	info->enter = CAR;
3586 	info->nl_does_cr = TRUE;
3587 	return OK;
3588     }
3589 #endif
3590     return FAIL;
3591 }
3592 
3593 #endif /* VMS  */
3594 
3595 #if defined(FEAT_MOUSE_TTY) || defined(PROTO)
3596 static int	mouse_ison = FALSE;
3597 
3598 /*
3599  * Set mouse clicks on or off.
3600  */
3601     void
3602 mch_setmouse(int on)
3603 {
3604 # ifdef FEAT_BEVAL_TERM
3605     static int	bevalterm_ison = FALSE;
3606 # endif
3607     int		xterm_mouse_vers;
3608 
3609 # if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
3610     if (!on)
3611 	// Make sure not tracing mouse movements.  Important when a button-down
3612 	// was received but no release yet.
3613 	stop_xterm_trace();
3614 # endif
3615 
3616     if (on == mouse_ison
3617 # ifdef FEAT_BEVAL_TERM
3618 	    && p_bevalterm == bevalterm_ison
3619 # endif
3620 	    )
3621 	/* return quickly if nothing to do */
3622 	return;
3623 
3624     xterm_mouse_vers = use_xterm_mouse();
3625 
3626 # ifdef FEAT_MOUSE_URXVT
3627     if (ttym_flags == TTYM_URXVT)
3628     {
3629 	out_str_nf((char_u *)
3630 		   (on
3631 		   ? IF_EB("\033[?1015h", ESC_STR "[?1015h")
3632 		   : IF_EB("\033[?1015l", ESC_STR "[?1015l")));
3633 	mouse_ison = on;
3634     }
3635 # endif
3636 
3637     if (ttym_flags == TTYM_SGR)
3638     {
3639 	/* SGR mode supports columns above 223 */
3640 	out_str_nf((char_u *)
3641 		   (on
3642 		   ? IF_EB("\033[?1006h", ESC_STR "[?1006h")
3643 		   : IF_EB("\033[?1006l", ESC_STR "[?1006l")));
3644 	mouse_ison = on;
3645     }
3646 
3647 # ifdef FEAT_BEVAL_TERM
3648     if (bevalterm_ison != (p_bevalterm && on))
3649     {
3650 	bevalterm_ison = (p_bevalterm && on);
3651 	if (xterm_mouse_vers > 1 && !bevalterm_ison)
3652 	    /* disable mouse movement events, enabling is below */
3653 	    out_str_nf((char_u *)
3654 			(IF_EB("\033[?1003l", ESC_STR "[?1003l")));
3655     }
3656 # endif
3657 
3658     if (xterm_mouse_vers > 0)
3659     {
3660 	if (on)	/* enable mouse events, use mouse tracking if available */
3661 	    out_str_nf((char_u *)
3662 		       (xterm_mouse_vers > 1
3663 			? (
3664 # ifdef FEAT_BEVAL_TERM
3665 			    bevalterm_ison
3666 			       ? IF_EB("\033[?1003h", ESC_STR "[?1003h") :
3667 # endif
3668 			      IF_EB("\033[?1002h", ESC_STR "[?1002h"))
3669 			: IF_EB("\033[?1000h", ESC_STR "[?1000h")));
3670 	else	/* disable mouse events, could probably always send the same */
3671 	    out_str_nf((char_u *)
3672 		       (xterm_mouse_vers > 1
3673 			? IF_EB("\033[?1002l", ESC_STR "[?1002l")
3674 			: IF_EB("\033[?1000l", ESC_STR "[?1000l")));
3675 	mouse_ison = on;
3676     }
3677 
3678 # ifdef FEAT_MOUSE_DEC
3679     else if (ttym_flags == TTYM_DEC)
3680     {
3681 	if (on)	/* enable mouse events */
3682 	    out_str_nf((char_u *)"\033[1;2'z\033[1;3'{");
3683 	else	/* disable mouse events */
3684 	    out_str_nf((char_u *)"\033['z");
3685 	mouse_ison = on;
3686     }
3687 # endif
3688 
3689 # ifdef FEAT_MOUSE_GPM
3690     else
3691     {
3692 	if (on)
3693 	{
3694 	    if (gpm_open())
3695 		mouse_ison = TRUE;
3696 	}
3697 	else
3698 	{
3699 	    gpm_close();
3700 	    mouse_ison = FALSE;
3701 	}
3702     }
3703 # endif
3704 
3705 # ifdef FEAT_SYSMOUSE
3706     else
3707     {
3708 	if (on)
3709 	{
3710 	    if (sysmouse_open() == OK)
3711 		mouse_ison = TRUE;
3712 	}
3713 	else
3714 	{
3715 	    sysmouse_close();
3716 	    mouse_ison = FALSE;
3717 	}
3718     }
3719 # endif
3720 
3721 # ifdef FEAT_MOUSE_JSB
3722     else
3723     {
3724 	if (on)
3725 	{
3726 	    /* D - Enable Mouse up/down messages
3727 	     * L - Enable Left Button Reporting
3728 	     * M - Enable Middle Button Reporting
3729 	     * R - Enable Right Button Reporting
3730 	     * K - Enable SHIFT and CTRL key Reporting
3731 	     * + - Enable Advanced messaging of mouse moves and up/down messages
3732 	     * Q - Quiet No Ack
3733 	     * # - Numeric value of mouse pointer required
3734 	     *	  0 = Multiview 2000 cursor, used as standard
3735 	     *	  1 = Windows Arrow
3736 	     *	  2 = Windows I Beam
3737 	     *	  3 = Windows Hour Glass
3738 	     *	  4 = Windows Cross Hair
3739 	     *	  5 = Windows UP Arrow
3740 	     */
3741 #  ifdef JSBTERM_MOUSE_NONADVANCED
3742 	    /* Disables full feedback of pointer movements */
3743 	    out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK1Q\033\\",
3744 					 ESC_STR "[0~ZwLMRK1Q" ESC_STR "\\"));
3745 #  else
3746 	    out_str_nf((char_u *)IF_EB("\033[0~ZwLMRK+1Q\033\\",
3747 					ESC_STR "[0~ZwLMRK+1Q" ESC_STR "\\"));
3748 #  endif
3749 	    mouse_ison = TRUE;
3750 	}
3751 	else
3752 	{
3753 	    out_str_nf((char_u *)IF_EB("\033[0~ZwQ\033\\",
3754 					      ESC_STR "[0~ZwQ" ESC_STR "\\"));
3755 	    mouse_ison = FALSE;
3756 	}
3757     }
3758 # endif
3759 # ifdef FEAT_MOUSE_PTERM
3760     else
3761     {
3762 	/* 1 = button press, 6 = release, 7 = drag, 1h...9l = right button */
3763 	if (on)
3764 	    out_str_nf("\033[>1h\033[>6h\033[>7h\033[>1h\033[>9l");
3765 	else
3766 	    out_str_nf("\033[>1l\033[>6l\033[>7l\033[>1l\033[>9h");
3767 	mouse_ison = on;
3768     }
3769 # endif
3770 }
3771 
3772 #if defined(FEAT_BEVAL_TERM) || defined(PROTO)
3773 /*
3774  * Called when 'balloonevalterm' changed.
3775  */
3776     void
3777 mch_bevalterm_changed(void)
3778 {
3779     mch_setmouse(mouse_ison);
3780 }
3781 #endif
3782 
3783 /*
3784  * Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
3785  */
3786     void
3787 check_mouse_termcode(void)
3788 {
3789 # ifdef FEAT_MOUSE_XTERM
3790     if (use_xterm_mouse()
3791 # ifdef FEAT_MOUSE_URXVT
3792 	    && use_xterm_mouse() != 3
3793 # endif
3794 #  ifdef FEAT_GUI
3795 	    && !gui.in_use
3796 #  endif
3797 	    )
3798     {
3799 	set_mouse_termcode(KS_MOUSE, (char_u *)(term_is_8bit(T_NAME)
3800 		    ? IF_EB("\233M", CSI_STR "M")
3801 		    : IF_EB("\033[M", ESC_STR "[M")));
3802 	if (*p_mouse != NUL)
3803 	{
3804 	    /* force mouse off and maybe on to send possibly new mouse
3805 	     * activation sequence to the xterm, with(out) drag tracing. */
3806 	    mch_setmouse(FALSE);
3807 	    setmouse();
3808 	}
3809     }
3810     else
3811 	del_mouse_termcode(KS_MOUSE);
3812 # endif
3813 
3814 # ifdef FEAT_MOUSE_GPM
3815     if (!use_xterm_mouse()
3816 #  ifdef FEAT_GUI
3817 	    && !gui.in_use
3818 #  endif
3819 	    )
3820 	set_mouse_termcode(KS_GPM_MOUSE,
3821 				      (char_u *)IF_EB("\033MG", ESC_STR "MG"));
3822     else
3823 	del_mouse_termcode(KS_GPM_MOUSE);
3824 # endif
3825 
3826 # ifdef FEAT_SYSMOUSE
3827     if (!use_xterm_mouse()
3828 #  ifdef FEAT_GUI
3829 	    && !gui.in_use
3830 #  endif
3831 	    )
3832 	set_mouse_termcode(KS_MOUSE, (char_u *)IF_EB("\033MS", ESC_STR "MS"));
3833 # endif
3834 
3835 # ifdef FEAT_MOUSE_JSB
3836     /* Conflicts with xterm mouse: "\033[" and "\033[M" ??? */
3837     if (!use_xterm_mouse()
3838 #  ifdef FEAT_GUI
3839 	    && !gui.in_use
3840 #  endif
3841 	    )
3842 	set_mouse_termcode(KS_JSBTERM_MOUSE,
3843 			       (char_u *)IF_EB("\033[0~zw", ESC_STR "[0~zw"));
3844     else
3845 	del_mouse_termcode(KS_JSBTERM_MOUSE);
3846 # endif
3847 
3848 # ifdef FEAT_MOUSE_NET
3849     /* There is no conflict, but one may type "ESC }" from Insert mode.  Don't
3850      * define it in the GUI or when using an xterm. */
3851     if (!use_xterm_mouse()
3852 #  ifdef FEAT_GUI
3853 	    && !gui.in_use
3854 #  endif
3855 	    )
3856 	set_mouse_termcode(KS_NETTERM_MOUSE,
3857 				       (char_u *)IF_EB("\033}", ESC_STR "}"));
3858     else
3859 	del_mouse_termcode(KS_NETTERM_MOUSE);
3860 # endif
3861 
3862 # ifdef FEAT_MOUSE_DEC
3863     /* Conflicts with xterm mouse: "\033[" and "\033[M" */
3864     if (!use_xterm_mouse()
3865 #  ifdef FEAT_GUI
3866 	    && !gui.in_use
3867 #  endif
3868 	    )
3869 	set_mouse_termcode(KS_DEC_MOUSE, (char_u *)(term_is_8bit(T_NAME)
3870 		     ? IF_EB("\233", CSI_STR) : IF_EB("\033[", ESC_STR "[")));
3871     else
3872 	del_mouse_termcode(KS_DEC_MOUSE);
3873 # endif
3874 # ifdef FEAT_MOUSE_PTERM
3875     /* same conflict as the dec mouse */
3876     if (!use_xterm_mouse()
3877 #  ifdef FEAT_GUI
3878 	    && !gui.in_use
3879 #  endif
3880 	    )
3881 	set_mouse_termcode(KS_PTERM_MOUSE,
3882 				      (char_u *) IF_EB("\033[", ESC_STR "["));
3883     else
3884 	del_mouse_termcode(KS_PTERM_MOUSE);
3885 # endif
3886 # ifdef FEAT_MOUSE_URXVT
3887     if (use_xterm_mouse() == 3
3888 #  ifdef FEAT_GUI
3889 	    && !gui.in_use
3890 #  endif
3891 	    )
3892     {
3893 	set_mouse_termcode(KS_URXVT_MOUSE, (char_u *)(term_is_8bit(T_NAME)
3894 		    ? IF_EB("\233*M", CSI_STR "*M")
3895 		    : IF_EB("\033[*M", ESC_STR "[*M")));
3896 
3897 	if (*p_mouse != NUL)
3898 	{
3899 	    mch_setmouse(FALSE);
3900 	    setmouse();
3901 	}
3902     }
3903     else
3904 	del_mouse_termcode(KS_URXVT_MOUSE);
3905 # endif
3906     if (use_xterm_mouse() == 4
3907 # ifdef FEAT_GUI
3908 	    && !gui.in_use
3909 # endif
3910 	    )
3911     {
3912 	set_mouse_termcode(KS_SGR_MOUSE, (char_u *)(term_is_8bit(T_NAME)
3913 		    ? IF_EB("\233<*M", CSI_STR "<*M")
3914 		    : IF_EB("\033[<*M", ESC_STR "[<*M")));
3915 
3916 	set_mouse_termcode(KS_SGR_MOUSE_RELEASE, (char_u *)(term_is_8bit(T_NAME)
3917 		    ? IF_EB("\233<*m", CSI_STR "<*m")
3918 		    : IF_EB("\033[<*m", ESC_STR "[<*m")));
3919 
3920 	if (*p_mouse != NUL)
3921 	{
3922 	    mch_setmouse(FALSE);
3923 	    setmouse();
3924 	}
3925     }
3926     else
3927     {
3928 	del_mouse_termcode(KS_SGR_MOUSE);
3929 	del_mouse_termcode(KS_SGR_MOUSE_RELEASE);
3930     }
3931 }
3932 #endif
3933 
3934 /*
3935  * set screen mode, always fails.
3936  */
3937     int
3938 mch_screenmode(char_u *arg UNUSED)
3939 {
3940     emsg(_(e_screenmode));
3941     return FAIL;
3942 }
3943 
3944 #ifndef VMS
3945 
3946 /*
3947  * Try to get the current window size:
3948  * 1. with an ioctl(), most accurate method
3949  * 2. from the environment variables LINES and COLUMNS
3950  * 3. from the termcap
3951  * 4. keep using the old values
3952  * Return OK when size could be determined, FAIL otherwise.
3953  */
3954     int
3955 mch_get_shellsize(void)
3956 {
3957     long	rows = 0;
3958     long	columns = 0;
3959     char_u	*p;
3960 
3961     /*
3962      * 1. try using an ioctl. It is the most accurate method.
3963      *
3964      * Try using TIOCGWINSZ first, some systems that have it also define
3965      * TIOCGSIZE but don't have a struct ttysize.
3966      */
3967 # ifdef TIOCGWINSZ
3968     {
3969 	struct winsize	ws;
3970 	int fd = 1;
3971 
3972 	/* When stdout is not a tty, use stdin for the ioctl(). */
3973 	if (!isatty(fd) && isatty(read_cmd_fd))
3974 	    fd = read_cmd_fd;
3975 	if (ioctl(fd, TIOCGWINSZ, &ws) == 0)
3976 	{
3977 	    columns = ws.ws_col;
3978 	    rows = ws.ws_row;
3979 	}
3980     }
3981 # else /* TIOCGWINSZ */
3982 #  ifdef TIOCGSIZE
3983     {
3984 	struct ttysize	ts;
3985 	int fd = 1;
3986 
3987 	/* When stdout is not a tty, use stdin for the ioctl(). */
3988 	if (!isatty(fd) && isatty(read_cmd_fd))
3989 	    fd = read_cmd_fd;
3990 	if (ioctl(fd, TIOCGSIZE, &ts) == 0)
3991 	{
3992 	    columns = ts.ts_cols;
3993 	    rows = ts.ts_lines;
3994 	}
3995     }
3996 #  endif /* TIOCGSIZE */
3997 # endif /* TIOCGWINSZ */
3998 
3999     /*
4000      * 2. get size from environment
4001      *    When being POSIX compliant ('|' flag in 'cpoptions') this overrules
4002      *    the ioctl() values!
4003      */
4004     if (columns == 0 || rows == 0 || vim_strchr(p_cpo, CPO_TSIZE) != NULL)
4005     {
4006 	if ((p = (char_u *)getenv("LINES")))
4007 	    rows = atoi((char *)p);
4008 	if ((p = (char_u *)getenv("COLUMNS")))
4009 	    columns = atoi((char *)p);
4010     }
4011 
4012 #ifdef HAVE_TGETENT
4013     /*
4014      * 3. try reading "co" and "li" entries from termcap
4015      */
4016     if (columns == 0 || rows == 0)
4017 	getlinecol(&columns, &rows);
4018 #endif
4019 
4020     /*
4021      * 4. If everything fails, use the old values
4022      */
4023     if (columns <= 0 || rows <= 0)
4024 	return FAIL;
4025 
4026     Rows = rows;
4027     Columns = columns;
4028     limit_screen_size();
4029     return OK;
4030 }
4031 
4032 #if defined(FEAT_TERMINAL) || defined(PROTO)
4033 /*
4034  * Report the windows size "rows" and "cols" to tty "fd".
4035  */
4036     int
4037 mch_report_winsize(int fd, int rows, int cols)
4038 {
4039     int		tty_fd;
4040     int		retval = -1;
4041 
4042     tty_fd = get_tty_fd(fd);
4043     if (tty_fd >= 0)
4044     {
4045 # if defined(TIOCSWINSZ)
4046 	struct winsize ws;
4047 
4048 	ws.ws_col = cols;
4049 	ws.ws_row = rows;
4050 	ws.ws_xpixel = cols * 5;
4051 	ws.ws_ypixel = rows * 10;
4052 	retval = ioctl(tty_fd, TIOCSWINSZ, &ws);
4053 	ch_log(NULL, "ioctl(TIOCSWINSZ) %s",
4054 					  retval == 0 ? "success" : "failed");
4055 # elif defined(TIOCSSIZE)
4056 	struct ttysize ts;
4057 
4058 	ts.ts_cols = cols;
4059 	ts.ts_lines = rows;
4060 	retval = ioctl(tty_fd, TIOCSSIZE, &ts);
4061 	ch_log(NULL, "ioctl(TIOCSSIZE) %s",
4062 					  retval == 0 ? "success" : "failed");
4063 # endif
4064 	if (tty_fd != fd)
4065 	    close(tty_fd);
4066     }
4067     return retval == 0 ? OK : FAIL;
4068 }
4069 #endif
4070 
4071 /*
4072  * Try to set the window size to Rows and Columns.
4073  */
4074     void
4075 mch_set_shellsize(void)
4076 {
4077     if (*T_CWS)
4078     {
4079 	/*
4080 	 * NOTE: if you get an error here that term_set_winsize() is
4081 	 * undefined, check the output of configure.  It could probably not
4082 	 * find a ncurses, termcap or termlib library.
4083 	 */
4084 	term_set_winsize((int)Rows, (int)Columns);
4085 	out_flush();
4086 	screen_start();			/* don't know where cursor is now */
4087     }
4088 }
4089 
4090 #endif /* VMS */
4091 
4092 /*
4093  * Rows and/or Columns has changed.
4094  */
4095     void
4096 mch_new_shellsize(void)
4097 {
4098     /* Nothing to do. */
4099 }
4100 
4101 /*
4102  * Wait for process "child" to end.
4103  * Return "child" if it exited properly, <= 0 on error.
4104  */
4105     static pid_t
4106 wait4pid(pid_t child, waitstatus *status)
4107 {
4108     pid_t wait_pid = 0;
4109     long delay_msec = 1;
4110 
4111     while (wait_pid != child)
4112     {
4113 	/* When compiled with Python threads are probably used, in which case
4114 	 * wait() sometimes hangs for no obvious reason.  Use waitpid()
4115 	 * instead and loop (like the GUI). Also needed for other interfaces,
4116 	 * they might call system(). */
4117 # ifdef __NeXT__
4118 	wait_pid = wait4(child, status, WNOHANG, (struct rusage *)0);
4119 # else
4120 	wait_pid = waitpid(child, status, WNOHANG);
4121 # endif
4122 	if (wait_pid == 0)
4123 	{
4124 	    /* Wait for 1 to 10 msec before trying again. */
4125 	    mch_delay(delay_msec, TRUE);
4126 	    if (++delay_msec > 10)
4127 		delay_msec = 10;
4128 	    continue;
4129 	}
4130 	if (wait_pid <= 0
4131 # ifdef ECHILD
4132 		&& errno == ECHILD
4133 # endif
4134 	   )
4135 	    break;
4136     }
4137     return wait_pid;
4138 }
4139 
4140 #if !defined(USE_SYSTEM) || defined(FEAT_JOB_CHANNEL)
4141 /*
4142  * Set the environment for a child process.
4143  */
4144     static void
4145 set_child_environment(
4146 	long	rows,
4147 	long	columns,
4148 	char	*term,
4149 	int	is_terminal UNUSED)
4150 {
4151 # ifdef HAVE_SETENV
4152     char	envbuf[50];
4153 # else
4154     static char	envbuf_Term[30];
4155     static char	envbuf_Rows[20];
4156     static char	envbuf_Lines[20];
4157     static char	envbuf_Columns[20];
4158     static char	envbuf_Colors[20];
4159 #  ifdef FEAT_TERMINAL
4160     static char	envbuf_Version[20];
4161 #  endif
4162 #  ifdef FEAT_CLIENTSERVER
4163     static char	envbuf_Servername[60];
4164 #  endif
4165 # endif
4166     long	colors =
4167 #  ifdef FEAT_GUI
4168 	    gui.in_use ? 256*256*256 :
4169 #  endif
4170 	    t_colors;
4171 
4172 # ifdef HAVE_SETENV
4173     setenv("TERM", term, 1);
4174     sprintf((char *)envbuf, "%ld", rows);
4175     setenv("ROWS", (char *)envbuf, 1);
4176     sprintf((char *)envbuf, "%ld", rows);
4177     setenv("LINES", (char *)envbuf, 1);
4178     sprintf((char *)envbuf, "%ld", columns);
4179     setenv("COLUMNS", (char *)envbuf, 1);
4180     sprintf((char *)envbuf, "%ld", colors);
4181     setenv("COLORS", (char *)envbuf, 1);
4182 #  ifdef FEAT_TERMINAL
4183     if (is_terminal)
4184     {
4185 	sprintf((char *)envbuf, "%ld",  (long)get_vim_var_nr(VV_VERSION));
4186 	setenv("VIM_TERMINAL", (char *)envbuf, 1);
4187     }
4188 #  endif
4189 #  ifdef FEAT_CLIENTSERVER
4190     setenv("VIM_SERVERNAME", serverName == NULL ? "" : (char *)serverName, 1);
4191 #  endif
4192 # else
4193     /*
4194      * Putenv does not copy the string, it has to remain valid.
4195      * Use a static array to avoid losing allocated memory.
4196      * This won't work well when running multiple children...
4197      */
4198     vim_snprintf(envbuf_Term, sizeof(envbuf_Term), "TERM=%s", term);
4199     putenv(envbuf_Term);
4200     vim_snprintf(envbuf_Rows, sizeof(envbuf_Rows), "ROWS=%ld", rows);
4201     putenv(envbuf_Rows);
4202     vim_snprintf(envbuf_Lines, sizeof(envbuf_Lines), "LINES=%ld", rows);
4203     putenv(envbuf_Lines);
4204     vim_snprintf(envbuf_Columns, sizeof(envbuf_Columns),
4205 						       "COLUMNS=%ld", columns);
4206     putenv(envbuf_Columns);
4207     vim_snprintf(envbuf_Colors, sizeof(envbuf_Colors), "COLORS=%ld", colors);
4208     putenv(envbuf_Colors);
4209 #  ifdef FEAT_TERMINAL
4210     if (is_terminal)
4211     {
4212 	vim_snprintf(envbuf_Version, sizeof(envbuf_Version),
4213 			 "VIM_TERMINAL=%ld", (long)get_vim_var_nr(VV_VERSION));
4214 	putenv(envbuf_Version);
4215     }
4216 #  endif
4217 #  ifdef FEAT_CLIENTSERVER
4218     vim_snprintf(envbuf_Servername, sizeof(envbuf_Servername),
4219 	    "VIM_SERVERNAME=%s", serverName == NULL ? "" : (char *)serverName);
4220     putenv(envbuf_Servername);
4221 #  endif
4222 # endif
4223 }
4224 
4225     static void
4226 set_default_child_environment(int is_terminal)
4227 {
4228     set_child_environment(Rows, Columns, "dumb", is_terminal);
4229 }
4230 #endif
4231 
4232 #if defined(FEAT_GUI) || defined(FEAT_JOB_CHANNEL)
4233 /*
4234  * Open a PTY, with FD for the master and slave side.
4235  * When failing "pty_master_fd" and "pty_slave_fd" are -1.
4236  * When successful both file descriptors are stored and the allocated pty name
4237  * is stored in both "*name1" and "*name2".
4238  */
4239     static void
4240 open_pty(int *pty_master_fd, int *pty_slave_fd, char_u **name1, char_u **name2)
4241 {
4242     char	*tty_name;
4243 
4244     if (name1 != NULL)
4245 	*name1 = NULL;
4246     if (name2 != NULL)
4247 	*name2 = NULL;
4248 
4249     *pty_master_fd = mch_openpty(&tty_name);	    // open pty
4250     if (*pty_master_fd >= 0)
4251     {
4252 	/* Leaving out O_NOCTTY may lead to waitpid() always returning
4253 	 * 0 on Mac OS X 10.7 thereby causing freezes. Let's assume
4254 	 * adding O_NOCTTY always works when defined. */
4255 #ifdef O_NOCTTY
4256 	*pty_slave_fd = open(tty_name, O_RDWR | O_NOCTTY | O_EXTRA, 0);
4257 #else
4258 	*pty_slave_fd = open(tty_name, O_RDWR | O_EXTRA, 0);
4259 #endif
4260 	if (*pty_slave_fd < 0)
4261 	{
4262 	    close(*pty_master_fd);
4263 	    *pty_master_fd = -1;
4264 	}
4265 	else
4266 	{
4267 	    if (name1 != NULL)
4268 		*name1 = vim_strsave((char_u *)tty_name);
4269 	    if (name2 != NULL)
4270 		*name2 = vim_strsave((char_u *)tty_name);
4271 	}
4272     }
4273 }
4274 #endif
4275 
4276 /*
4277  * Send SIGINT to a child process if "c" is an interrupt character.
4278  */
4279     static void
4280 may_send_sigint(int c UNUSED, pid_t pid UNUSED, pid_t wpid UNUSED)
4281 {
4282 # ifdef SIGINT
4283     if (c == Ctrl_C || c == intr_char)
4284     {
4285 #  ifdef HAVE_SETSID
4286 	kill(-pid, SIGINT);
4287 #  else
4288 	kill(0, SIGINT);
4289 #  endif
4290 	if (wpid > 0)
4291 	    kill(wpid, SIGINT);
4292     }
4293 # endif
4294 }
4295 
4296 #if !defined(USE_SYSTEM) || (defined(FEAT_GUI) && defined(FEAT_TERMINAL))
4297 
4298     static int
4299 build_argv(
4300 	char_u *cmd,
4301 	char ***argvp,
4302 	char_u **sh_tofree,
4303 	char_u **shcf_tofree)
4304 {
4305     char	**argv = NULL;
4306     int		argc;
4307 
4308     *sh_tofree = vim_strsave(p_sh);
4309     if (*sh_tofree == NULL)		/* out of memory */
4310 	return FAIL;
4311 
4312     if (mch_parse_cmd(*sh_tofree, TRUE, &argv, &argc) == FAIL)
4313 	return FAIL;
4314     *argvp = argv;
4315 
4316     if (cmd != NULL)
4317     {
4318 	char_u	*s;
4319 	char_u	*p;
4320 
4321 	if (extra_shell_arg != NULL)
4322 	    argv[argc++] = (char *)extra_shell_arg;
4323 
4324 	/* Break 'shellcmdflag' into white separated parts.  This doesn't
4325 	 * handle quoted strings, they are very unlikely to appear. */
4326 	*shcf_tofree = alloc(STRLEN(p_shcf) + 1);
4327 	if (*shcf_tofree == NULL)    /* out of memory */
4328 	    return FAIL;
4329 	s = *shcf_tofree;
4330 	p = p_shcf;
4331 	while (*p != NUL)
4332 	{
4333 	    argv[argc++] = (char *)s;
4334 	    while (*p && *p != ' ' && *p != TAB)
4335 		*s++ = *p++;
4336 	    *s++ = NUL;
4337 	    p = skipwhite(p);
4338 	}
4339 
4340 	argv[argc++] = (char *)cmd;
4341     }
4342     argv[argc] = NULL;
4343     return OK;
4344 }
4345 #endif
4346 
4347 #if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
4348 /*
4349  * Use a terminal window to run a shell command in.
4350  */
4351     static int
4352 mch_call_shell_terminal(
4353     char_u	*cmd,
4354     int		options UNUSED)	/* SHELL_*, see vim.h */
4355 {
4356     jobopt_T	opt;
4357     char	**argv = NULL;
4358     char_u	*tofree1 = NULL;
4359     char_u	*tofree2 = NULL;
4360     int		retval = -1;
4361     buf_T	*buf;
4362     job_T	*job;
4363     aco_save_T	aco;
4364     oparg_T	oa;		/* operator arguments */
4365 
4366     if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
4367 	goto theend;
4368 
4369     init_job_options(&opt);
4370     ch_log(NULL, "starting terminal for system command '%s'", cmd);
4371     buf = term_start(NULL, argv, &opt, TERM_START_SYSTEM);
4372     if (buf == NULL)
4373 	goto theend;
4374 
4375     job = term_getjob(buf->b_term);
4376     ++job->jv_refcount;
4377 
4378     /* Find a window to make "buf" curbuf. */
4379     aucmd_prepbuf(&aco, buf);
4380 
4381     clear_oparg(&oa);
4382     while (term_use_loop())
4383     {
4384 	if (oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active)
4385 	{
4386 	    /* If terminal_loop() returns OK we got a key that is handled
4387 	     * in Normal model. We don't do redrawing anyway. */
4388 	    if (terminal_loop(TRUE) == OK)
4389 		normal_cmd(&oa, TRUE);
4390 	}
4391 	else
4392 	    normal_cmd(&oa, TRUE);
4393     }
4394     retval = job->jv_exitval;
4395     ch_log(NULL, "system command finished");
4396 
4397     job_unref(job);
4398 
4399     /* restore curwin/curbuf and a few other things */
4400     aucmd_restbuf(&aco);
4401 
4402     wait_return(TRUE);
4403     do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE);
4404 
4405 theend:
4406     vim_free(argv);
4407     vim_free(tofree1);
4408     vim_free(tofree2);
4409     return retval;
4410 }
4411 #endif
4412 
4413 #ifdef USE_SYSTEM
4414 /*
4415  * Use system() to start the shell: simple but slow.
4416  */
4417     static int
4418 mch_call_shell_system(
4419     char_u	*cmd,
4420     int		options)	/* SHELL_*, see vim.h */
4421 {
4422 #ifdef VMS
4423     char	*ifn = NULL;
4424     char	*ofn = NULL;
4425 #endif
4426     int		tmode = cur_tmode;
4427     char_u	*newcmd;	/* only needed for unix */
4428     int		x;
4429 
4430     out_flush();
4431 
4432     if (options & SHELL_COOKED)
4433 	settmode(TMODE_COOK);	    /* set to normal mode */
4434 
4435 # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
4436     save_clipboard();
4437     loose_clipboard();
4438 # endif
4439 
4440     if (cmd == NULL)
4441 	x = system((char *)p_sh);
4442     else
4443     {
4444 # ifdef VMS
4445 	if (ofn = strchr((char *)cmd, '>'))
4446 	    *ofn++ = '\0';
4447 	if (ifn = strchr((char *)cmd, '<'))
4448 	{
4449 	    char *p;
4450 
4451 	    *ifn++ = '\0';
4452 	    p = strchr(ifn,' '); /* chop off any trailing spaces */
4453 	    if (p)
4454 		*p = '\0';
4455 	}
4456 	if (ofn)
4457 	    x = vms_sys((char *)cmd, ofn, ifn);
4458 	else
4459 	    x = system((char *)cmd);
4460 # else
4461 	newcmd = alloc(STRLEN(p_sh)
4462 		+ (extra_shell_arg == NULL ? 0 : STRLEN(extra_shell_arg))
4463 		+ STRLEN(p_shcf) + STRLEN(cmd) + 4);
4464 	if (newcmd == NULL)
4465 	    x = 0;
4466 	else
4467 	{
4468 	    sprintf((char *)newcmd, "%s %s %s %s", p_sh,
4469 		    extra_shell_arg == NULL ? "" : (char *)extra_shell_arg,
4470 		    (char *)p_shcf,
4471 		    (char *)cmd);
4472 	    x = system((char *)newcmd);
4473 	    vim_free(newcmd);
4474 	}
4475 # endif
4476     }
4477 # ifdef VMS
4478     x = vms_sys_status(x);
4479 # endif
4480     if (emsg_silent)
4481 	;
4482     else if (x == 127)
4483 	msg_puts(_("\nCannot execute shell sh\n"));
4484     else if (x && !(options & SHELL_SILENT))
4485     {
4486 	msg_puts(_("\nshell returned "));
4487 	msg_outnum((long)x);
4488 	msg_putchar('\n');
4489     }
4490 
4491     if (tmode == TMODE_RAW)
4492 	settmode(TMODE_RAW);	/* set to raw mode */
4493 # ifdef FEAT_TITLE
4494     resettitle();
4495 # endif
4496 # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
4497     restore_clipboard();
4498 # endif
4499     return x;
4500 }
4501 
4502 #else /* USE_SYSTEM */
4503 
4504 # define EXEC_FAILED 122    /* Exit code when shell didn't execute.  Don't use
4505 			       127, some shells use that already */
4506 # define OPEN_NULL_FAILED 123 /* Exit code if /dev/null can't be opened */
4507 
4508 /*
4509  * Don't use system(), use fork()/exec().
4510  */
4511     static int
4512 mch_call_shell_fork(
4513     char_u	*cmd,
4514     int		options)	/* SHELL_*, see vim.h */
4515 {
4516     int		tmode = cur_tmode;
4517     pid_t	pid;
4518     pid_t	wpid = 0;
4519     pid_t	wait_pid = 0;
4520 # ifdef HAVE_UNION_WAIT
4521     union wait	status;
4522 # else
4523     int		status = -1;
4524 # endif
4525     int		retval = -1;
4526     char	**argv = NULL;
4527     char_u	*tofree1 = NULL;
4528     char_u	*tofree2 = NULL;
4529     int		i;
4530     int		pty_master_fd = -1;	    /* for pty's */
4531 # ifdef FEAT_GUI
4532     int		pty_slave_fd = -1;
4533 # endif
4534     int		fd_toshell[2];		/* for pipes */
4535     int		fd_fromshell[2];
4536     int		pipe_error = FALSE;
4537     int		did_settmode = FALSE;	/* settmode(TMODE_RAW) called */
4538 
4539     out_flush();
4540     if (options & SHELL_COOKED)
4541 	settmode(TMODE_COOK);		/* set to normal mode */
4542 
4543     if (build_argv(cmd, &argv, &tofree1, &tofree2) == FAIL)
4544 	goto error;
4545 
4546     /*
4547      * For the GUI, when writing the output into the buffer and when reading
4548      * input from the buffer: Try using a pseudo-tty to get the stdin/stdout
4549      * of the executed command into the Vim window.  Or use a pipe.
4550      */
4551     if ((options & (SHELL_READ|SHELL_WRITE))
4552 # ifdef FEAT_GUI
4553 	    || (gui.in_use && show_shell_mess)
4554 # endif
4555 		    )
4556     {
4557 # ifdef FEAT_GUI
4558 	/*
4559 	 * Try to open a master pty.
4560 	 * If this works, open the slave pty.
4561 	 * If the slave can't be opened, close the master pty.
4562 	 */
4563 	if (p_guipty && !(options & (SHELL_READ|SHELL_WRITE)))
4564 	    open_pty(&pty_master_fd, &pty_slave_fd, NULL, NULL);
4565 	/*
4566 	 * If not opening a pty or it didn't work, try using pipes.
4567 	 */
4568 	if (pty_master_fd < 0)
4569 # endif
4570 	{
4571 	    pipe_error = (pipe(fd_toshell) < 0);
4572 	    if (!pipe_error)			    /* pipe create OK */
4573 	    {
4574 		pipe_error = (pipe(fd_fromshell) < 0);
4575 		if (pipe_error)			    /* pipe create failed */
4576 		{
4577 		    close(fd_toshell[0]);
4578 		    close(fd_toshell[1]);
4579 		}
4580 	    }
4581 	    if (pipe_error)
4582 	    {
4583 		msg_puts(_("\nCannot create pipes\n"));
4584 		out_flush();
4585 	    }
4586 	}
4587     }
4588 
4589     if (!pipe_error)			/* pty or pipe opened or not used */
4590     {
4591 	SIGSET_DECL(curset)
4592 
4593 # ifdef __BEOS__
4594 	beos_cleanup_read_thread();
4595 # endif
4596 
4597 	BLOCK_SIGNALS(&curset);
4598 	pid = fork();	/* maybe we should use vfork() */
4599 	if (pid == -1)
4600 	{
4601 	    UNBLOCK_SIGNALS(&curset);
4602 
4603 	    msg_puts(_("\nCannot fork\n"));
4604 	    if ((options & (SHELL_READ|SHELL_WRITE))
4605 # ifdef FEAT_GUI
4606 		|| (gui.in_use && show_shell_mess)
4607 # endif
4608 		    )
4609 	    {
4610 # ifdef FEAT_GUI
4611 		if (pty_master_fd >= 0)		/* close the pseudo tty */
4612 		{
4613 		    close(pty_master_fd);
4614 		    close(pty_slave_fd);
4615 		}
4616 		else				/* close the pipes */
4617 # endif
4618 		{
4619 		    close(fd_toshell[0]);
4620 		    close(fd_toshell[1]);
4621 		    close(fd_fromshell[0]);
4622 		    close(fd_fromshell[1]);
4623 		}
4624 	    }
4625 	}
4626 	else if (pid == 0)	/* child */
4627 	{
4628 	    reset_signals();		/* handle signals normally */
4629 	    UNBLOCK_SIGNALS(&curset);
4630 
4631 # ifdef FEAT_JOB_CHANNEL
4632 	    if (ch_log_active())
4633 		/* close the log file in the child */
4634 		ch_logfile((char_u *)"", (char_u *)"");
4635 # endif
4636 
4637 	    if (!show_shell_mess || (options & SHELL_EXPAND))
4638 	    {
4639 		int fd;
4640 
4641 		/*
4642 		 * Don't want to show any message from the shell.  Can't just
4643 		 * close stdout and stderr though, because some systems will
4644 		 * break if you try to write to them after that, so we must
4645 		 * use dup() to replace them with something else -- webb
4646 		 * Connect stdin to /dev/null too, so ":n `cat`" doesn't hang,
4647 		 * waiting for input.
4648 		 */
4649 		fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
4650 		fclose(stdin);
4651 		fclose(stdout);
4652 		fclose(stderr);
4653 
4654 		/*
4655 		 * If any of these open()'s and dup()'s fail, we just continue
4656 		 * anyway.  It's not fatal, and on most systems it will make
4657 		 * no difference at all.  On a few it will cause the execvp()
4658 		 * to exit with a non-zero status even when the completion
4659 		 * could be done, which is nothing too serious.  If the open()
4660 		 * or dup() failed we'd just do the same thing ourselves
4661 		 * anyway -- webb
4662 		 */
4663 		if (fd >= 0)
4664 		{
4665 		    vim_ignored = dup(fd); /* To replace stdin  (fd 0) */
4666 		    vim_ignored = dup(fd); /* To replace stdout (fd 1) */
4667 		    vim_ignored = dup(fd); /* To replace stderr (fd 2) */
4668 
4669 		    /* Don't need this now that we've duplicated it */
4670 		    close(fd);
4671 		}
4672 	    }
4673 	    else if ((options & (SHELL_READ|SHELL_WRITE))
4674 # ifdef FEAT_GUI
4675 		    || gui.in_use
4676 # endif
4677 		    )
4678 	    {
4679 
4680 # ifdef HAVE_SETSID
4681 		/* Create our own process group, so that the child and all its
4682 		 * children can be kill()ed.  Don't do this when using pipes,
4683 		 * because stdin is not a tty, we would lose /dev/tty. */
4684 		if (p_stmp)
4685 		{
4686 		    (void)setsid();
4687 #  if defined(SIGHUP)
4688 		    /* When doing "!xterm&" and 'shell' is bash: the shell
4689 		     * will exit and send SIGHUP to all processes in its
4690 		     * group, killing the just started process.  Ignore SIGHUP
4691 		     * to avoid that. (suggested by Simon Schubert)
4692 		     */
4693 		    signal(SIGHUP, SIG_IGN);
4694 #  endif
4695 		}
4696 # endif
4697 # ifdef FEAT_GUI
4698 		if (pty_slave_fd >= 0)
4699 		{
4700 		    /* push stream discipline modules */
4701 		    if (options & SHELL_COOKED)
4702 			setup_slavepty(pty_slave_fd);
4703 #  ifdef TIOCSCTTY
4704 		    /* Try to become controlling tty (probably doesn't work,
4705 		     * unless run by root) */
4706 		    ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
4707 #  endif
4708 		}
4709 # endif
4710 		set_default_child_environment(FALSE);
4711 
4712 		/*
4713 		 * stderr is only redirected when using the GUI, so that a
4714 		 * program like gpg can still access the terminal to get a
4715 		 * passphrase using stderr.
4716 		 */
4717 # ifdef FEAT_GUI
4718 		if (pty_master_fd >= 0)
4719 		{
4720 		    close(pty_master_fd);   /* close master side of pty */
4721 
4722 		    /* set up stdin/stdout/stderr for the child */
4723 		    close(0);
4724 		    vim_ignored = dup(pty_slave_fd);
4725 		    close(1);
4726 		    vim_ignored = dup(pty_slave_fd);
4727 		    if (gui.in_use)
4728 		    {
4729 			close(2);
4730 			vim_ignored = dup(pty_slave_fd);
4731 		    }
4732 
4733 		    close(pty_slave_fd);    /* has been dupped, close it now */
4734 		}
4735 		else
4736 # endif
4737 		{
4738 		    /* set up stdin for the child */
4739 		    close(fd_toshell[1]);
4740 		    close(0);
4741 		    vim_ignored = dup(fd_toshell[0]);
4742 		    close(fd_toshell[0]);
4743 
4744 		    /* set up stdout for the child */
4745 		    close(fd_fromshell[0]);
4746 		    close(1);
4747 		    vim_ignored = dup(fd_fromshell[1]);
4748 		    close(fd_fromshell[1]);
4749 
4750 # ifdef FEAT_GUI
4751 		    if (gui.in_use)
4752 		    {
4753 			/* set up stderr for the child */
4754 			close(2);
4755 			vim_ignored = dup(1);
4756 		    }
4757 # endif
4758 		}
4759 	    }
4760 
4761 	    /*
4762 	     * There is no type cast for the argv, because the type may be
4763 	     * different on different machines. This may cause a warning
4764 	     * message with strict compilers, don't worry about it.
4765 	     * Call _exit() instead of exit() to avoid closing the connection
4766 	     * to the X server (esp. with GTK, which uses atexit()).
4767 	     */
4768 	    execvp(argv[0], argv);
4769 	    _exit(EXEC_FAILED);	    /* exec failed, return failure code */
4770 	}
4771 	else			/* parent */
4772 	{
4773 	    /*
4774 	     * While child is running, ignore terminating signals.
4775 	     * Do catch CTRL-C, so that "got_int" is set.
4776 	     */
4777 	    catch_signals(SIG_IGN, SIG_ERR);
4778 	    catch_int_signal();
4779 	    UNBLOCK_SIGNALS(&curset);
4780 # ifdef FEAT_JOB_CHANNEL
4781 	    ++dont_check_job_ended;
4782 # endif
4783 	    /*
4784 	     * For the GUI we redirect stdin, stdout and stderr to our window.
4785 	     * This is also used to pipe stdin/stdout to/from the external
4786 	     * command.
4787 	     */
4788 	    if ((options & (SHELL_READ|SHELL_WRITE))
4789 # ifdef FEAT_GUI
4790 		    || (gui.in_use && show_shell_mess)
4791 # endif
4792 	       )
4793 	    {
4794 # define BUFLEN 100		/* length for buffer, pseudo tty limit is 128 */
4795 		char_u	    buffer[BUFLEN + 1];
4796 		int	    buffer_off = 0;	/* valid bytes in buffer[] */
4797 		char_u	    ta_buf[BUFLEN + 1];	/* TypeAHead */
4798 		int	    ta_len = 0;		/* valid bytes in ta_buf[] */
4799 		int	    len;
4800 		int	    p_more_save;
4801 		int	    old_State;
4802 		int	    c;
4803 		int	    toshell_fd;
4804 		int	    fromshell_fd;
4805 		garray_T    ga;
4806 		int	    noread_cnt;
4807 # ifdef ELAPSED_FUNC
4808 		elapsed_T   start_tv;
4809 # endif
4810 
4811 # ifdef FEAT_GUI
4812 		if (pty_master_fd >= 0)
4813 		{
4814 		    fromshell_fd = pty_master_fd;
4815 		    toshell_fd = dup(pty_master_fd);
4816 		}
4817 		else
4818 # endif
4819 		{
4820 		    close(fd_toshell[0]);
4821 		    close(fd_fromshell[1]);
4822 		    toshell_fd = fd_toshell[1];
4823 		    fromshell_fd = fd_fromshell[0];
4824 		}
4825 
4826 		/*
4827 		 * Write to the child if there are typed characters.
4828 		 * Read from the child if there are characters available.
4829 		 *   Repeat the reading a few times if more characters are
4830 		 *   available. Need to check for typed keys now and then, but
4831 		 *   not too often (delays when no chars are available).
4832 		 * This loop is quit if no characters can be read from the pty
4833 		 * (WaitForChar detected special condition), or there are no
4834 		 * characters available and the child has exited.
4835 		 * Only check if the child has exited when there is no more
4836 		 * output. The child may exit before all the output has
4837 		 * been printed.
4838 		 *
4839 		 * Currently this busy loops!
4840 		 * This can probably dead-lock when the write blocks!
4841 		 */
4842 		p_more_save = p_more;
4843 		p_more = FALSE;
4844 		old_State = State;
4845 		State = EXTERNCMD;	/* don't redraw at window resize */
4846 
4847 		if ((options & SHELL_WRITE) && toshell_fd >= 0)
4848 		{
4849 		    /* Fork a process that will write the lines to the
4850 		     * external program. */
4851 		    if ((wpid = fork()) == -1)
4852 		    {
4853 			msg_puts(_("\nCannot fork\n"));
4854 		    }
4855 		    else if (wpid == 0) /* child */
4856 		    {
4857 			linenr_T    lnum = curbuf->b_op_start.lnum;
4858 			int	    written = 0;
4859 			char_u	    *lp = ml_get(lnum);
4860 			size_t	    l;
4861 
4862 			close(fromshell_fd);
4863 			for (;;)
4864 			{
4865 			    l = STRLEN(lp + written);
4866 			    if (l == 0)
4867 				len = 0;
4868 			    else if (lp[written] == NL)
4869 				/* NL -> NUL translation */
4870 				len = write(toshell_fd, "", (size_t)1);
4871 			    else
4872 			    {
4873 				char_u	*s = vim_strchr(lp + written, NL);
4874 
4875 				len = write(toshell_fd, (char *)lp + written,
4876 					   s == NULL ? l
4877 					      : (size_t)(s - (lp + written)));
4878 			    }
4879 			    if (len == (int)l)
4880 			    {
4881 				/* Finished a line, add a NL, unless this line
4882 				 * should not have one. */
4883 				if (lnum != curbuf->b_op_end.lnum
4884 					|| (!curbuf->b_p_bin
4885 					    && curbuf->b_p_fixeol)
4886 					|| (lnum != curbuf->b_no_eol_lnum
4887 					    && (lnum !=
4888 						    curbuf->b_ml.ml_line_count
4889 						    || curbuf->b_p_eol)))
4890 				    vim_ignored = write(toshell_fd, "\n",
4891 								   (size_t)1);
4892 				++lnum;
4893 				if (lnum > curbuf->b_op_end.lnum)
4894 				{
4895 				    /* finished all the lines, close pipe */
4896 				    close(toshell_fd);
4897 				    toshell_fd = -1;
4898 				    break;
4899 				}
4900 				lp = ml_get(lnum);
4901 				written = 0;
4902 			    }
4903 			    else if (len > 0)
4904 				written += len;
4905 			}
4906 			_exit(0);
4907 		    }
4908 		    else /* parent */
4909 		    {
4910 			close(toshell_fd);
4911 			toshell_fd = -1;
4912 		    }
4913 		}
4914 
4915 		if (options & SHELL_READ)
4916 		    ga_init2(&ga, 1, BUFLEN);
4917 
4918 		noread_cnt = 0;
4919 # ifdef ELAPSED_FUNC
4920 		ELAPSED_INIT(start_tv);
4921 # endif
4922 		for (;;)
4923 		{
4924 		    /*
4925 		     * Check if keys have been typed, write them to the child
4926 		     * if there are any.
4927 		     * Don't do this if we are expanding wild cards (would eat
4928 		     * typeahead).
4929 		     * Don't do this when filtering and terminal is in cooked
4930 		     * mode, the shell command will handle the I/O.  Avoids
4931 		     * that a typed password is echoed for ssh or gpg command.
4932 		     * Don't get characters when the child has already
4933 		     * finished (wait_pid == 0).
4934 		     * Don't read characters unless we didn't get output for a
4935 		     * while (noread_cnt > 4), avoids that ":r !ls" eats
4936 		     * typeahead.
4937 		     */
4938 		    len = 0;
4939 		    if (!(options & SHELL_EXPAND)
4940 			    && ((options &
4941 					 (SHELL_READ|SHELL_WRITE|SHELL_COOKED))
4942 				      != (SHELL_READ|SHELL_WRITE|SHELL_COOKED)
4943 # ifdef FEAT_GUI
4944 						    || gui.in_use
4945 # endif
4946 						    )
4947 			    && wait_pid == 0
4948 			    && (ta_len > 0 || noread_cnt > 4))
4949 		    {
4950 		      if (ta_len == 0)
4951 		      {
4952 			  /* Get extra characters when we don't have any.
4953 			   * Reset the counter and timer. */
4954 			  noread_cnt = 0;
4955 # ifdef ELAPSED_FUNC
4956 			  ELAPSED_INIT(start_tv);
4957 # endif
4958 			  len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
4959 		      }
4960 		      if (ta_len > 0 || len > 0)
4961 		      {
4962 			/*
4963 			 * For pipes:
4964 			 * Check for CTRL-C: send interrupt signal to child.
4965 			 * Check for CTRL-D: EOF, close pipe to child.
4966 			 */
4967 			if (len == 1 && (pty_master_fd < 0 || cmd != NULL))
4968 			{
4969 			    /*
4970 			     * Send SIGINT to the child's group or all
4971 			     * processes in our group.
4972 			     */
4973 			    may_send_sigint(ta_buf[ta_len], pid, wpid);
4974 
4975 			    if (pty_master_fd < 0 && toshell_fd >= 0
4976 					       && ta_buf[ta_len] == Ctrl_D)
4977 			    {
4978 				close(toshell_fd);
4979 				toshell_fd = -1;
4980 			    }
4981 			}
4982 
4983 			/* replace K_BS by <BS> and K_DEL by <DEL> */
4984 			for (i = ta_len; i < ta_len + len; ++i)
4985 			{
4986 			    if (ta_buf[i] == CSI && len - i > 2)
4987 			    {
4988 				c = TERMCAP2KEY(ta_buf[i + 1], ta_buf[i + 2]);
4989 				if (c == K_DEL || c == K_KDEL || c == K_BS)
4990 				{
4991 				    mch_memmove(ta_buf + i + 1, ta_buf + i + 3,
4992 						       (size_t)(len - i - 2));
4993 				    if (c == K_DEL || c == K_KDEL)
4994 					ta_buf[i] = DEL;
4995 				    else
4996 					ta_buf[i] = Ctrl_H;
4997 				    len -= 2;
4998 				}
4999 			    }
5000 			    else if (ta_buf[i] == '\r')
5001 				ta_buf[i] = '\n';
5002 			    if (has_mbyte)
5003 				i += (*mb_ptr2len_len)(ta_buf + i,
5004 							ta_len + len - i) - 1;
5005 			}
5006 
5007 			/*
5008 			 * For pipes: echo the typed characters.
5009 			 * For a pty this does not seem to work.
5010 			 */
5011 			if (pty_master_fd < 0)
5012 			{
5013 			    for (i = ta_len; i < ta_len + len; ++i)
5014 			    {
5015 				if (ta_buf[i] == '\n' || ta_buf[i] == '\b')
5016 				    msg_putchar(ta_buf[i]);
5017 				else if (has_mbyte)
5018 				{
5019 				    int l = (*mb_ptr2len)(ta_buf + i);
5020 
5021 				    msg_outtrans_len(ta_buf + i, l);
5022 				    i += l - 1;
5023 				}
5024 				else
5025 				    msg_outtrans_len(ta_buf + i, 1);
5026 			    }
5027 			    windgoto(msg_row, msg_col);
5028 			    out_flush();
5029 			}
5030 
5031 			ta_len += len;
5032 
5033 			/*
5034 			 * Write the characters to the child, unless EOF has
5035 			 * been typed for pipes.  Write one character at a
5036 			 * time, to avoid losing too much typeahead.
5037 			 * When writing buffer lines, drop the typed
5038 			 * characters (only check for CTRL-C).
5039 			 */
5040 			if (options & SHELL_WRITE)
5041 			    ta_len = 0;
5042 			else if (toshell_fd >= 0)
5043 			{
5044 			    len = write(toshell_fd, (char *)ta_buf, (size_t)1);
5045 			    if (len > 0)
5046 			    {
5047 				ta_len -= len;
5048 				mch_memmove(ta_buf, ta_buf + len, ta_len);
5049 			    }
5050 			}
5051 		      }
5052 		    }
5053 
5054 		    if (got_int)
5055 		    {
5056 			/* CTRL-C sends a signal to the child, we ignore it
5057 			 * ourselves */
5058 #  ifdef HAVE_SETSID
5059 			kill(-pid, SIGINT);
5060 #  else
5061 			kill(0, SIGINT);
5062 #  endif
5063 			if (wpid > 0)
5064 			    kill(wpid, SIGINT);
5065 			got_int = FALSE;
5066 		    }
5067 
5068 		    /*
5069 		     * Check if the child has any characters to be printed.
5070 		     * Read them and write them to our window.	Repeat this as
5071 		     * long as there is something to do, avoid the 10ms wait
5072 		     * for mch_inchar(), or sending typeahead characters to
5073 		     * the external process.
5074 		     * TODO: This should handle escape sequences, compatible
5075 		     * to some terminal (vt52?).
5076 		     */
5077 		    ++noread_cnt;
5078 		    while (RealWaitForChar(fromshell_fd, 10L, NULL, NULL))
5079 		    {
5080 			len = read_eintr(fromshell_fd, buffer
5081 				+ buffer_off, (size_t)(BUFLEN - buffer_off)
5082 				);
5083 			if (len <= 0)		    /* end of file or error */
5084 			    goto finished;
5085 
5086 			noread_cnt = 0;
5087 			if (options & SHELL_READ)
5088 			{
5089 			    /* Do NUL -> NL translation, append NL separated
5090 			     * lines to the current buffer. */
5091 			    for (i = 0; i < len; ++i)
5092 			    {
5093 				if (buffer[i] == NL)
5094 				    append_ga_line(&ga);
5095 				else if (buffer[i] == NUL)
5096 				    ga_append(&ga, NL);
5097 				else
5098 				    ga_append(&ga, buffer[i]);
5099 			    }
5100 			}
5101 			else if (has_mbyte)
5102 			{
5103 			    int		l;
5104 			    char_u	*p;
5105 
5106 			    len += buffer_off;
5107 			    buffer[len] = NUL;
5108 
5109 			    /* Check if the last character in buffer[] is
5110 			     * incomplete, keep these bytes for the next
5111 			     * round. */
5112 			    for (p = buffer; p < buffer + len; p += l)
5113 			    {
5114 				l = MB_CPTR2LEN(p);
5115 				if (l == 0)
5116 				    l = 1;  /* NUL byte? */
5117 				else if (MB_BYTE2LEN(*p) != l)
5118 				    break;
5119 			    }
5120 			    if (p == buffer)	/* no complete character */
5121 			    {
5122 				/* avoid getting stuck at an illegal byte */
5123 				if (len >= 12)
5124 				    ++p;
5125 				else
5126 				{
5127 				    buffer_off = len;
5128 				    continue;
5129 				}
5130 			    }
5131 			    c = *p;
5132 			    *p = NUL;
5133 			    msg_puts((char *)buffer);
5134 			    if (p < buffer + len)
5135 			    {
5136 				*p = c;
5137 				buffer_off = (buffer + len) - p;
5138 				mch_memmove(buffer, p, buffer_off);
5139 				continue;
5140 			    }
5141 			    buffer_off = 0;
5142 			}
5143 			else
5144 			{
5145 			    buffer[len] = NUL;
5146 			    msg_puts((char *)buffer);
5147 			}
5148 
5149 			windgoto(msg_row, msg_col);
5150 			cursor_on();
5151 			out_flush();
5152 			if (got_int)
5153 			    break;
5154 
5155 # ifdef ELAPSED_FUNC
5156 			if (wait_pid == 0)
5157 			{
5158 			    long	msec = ELAPSED_FUNC(start_tv);
5159 
5160 			    /* Avoid that we keep looping here without
5161 			     * checking for a CTRL-C for a long time.  Don't
5162 			     * break out too often to avoid losing typeahead. */
5163 			    if (msec > 2000)
5164 			    {
5165 				noread_cnt = 5;
5166 				break;
5167 			    }
5168 			}
5169 # endif
5170 		    }
5171 
5172 		    /* If we already detected the child has finished, continue
5173 		     * reading output for a short while.  Some text may be
5174 		     * buffered. */
5175 		    if (wait_pid == pid)
5176 		    {
5177 			if (noread_cnt < 5)
5178 			    continue;
5179 			break;
5180 		    }
5181 
5182 		    /*
5183 		     * Check if the child still exists, before checking for
5184 		     * typed characters (otherwise we would lose typeahead).
5185 		     */
5186 # ifdef __NeXT__
5187 		    wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
5188 # else
5189 		    wait_pid = waitpid(pid, &status, WNOHANG);
5190 # endif
5191 		    if ((wait_pid == (pid_t)-1 && errno == ECHILD)
5192 			    || (wait_pid == pid && WIFEXITED(status)))
5193 		    {
5194 			/* Don't break the loop yet, try reading more
5195 			 * characters from "fromshell_fd" first.  When using
5196 			 * pipes there might still be something to read and
5197 			 * then we'll break the loop at the "break" above. */
5198 			wait_pid = pid;
5199 		    }
5200 		    else
5201 			wait_pid = 0;
5202 
5203 # if defined(FEAT_XCLIPBOARD) && defined(FEAT_X11)
5204 		    /* Handle any X events, e.g. serving the clipboard. */
5205 		    clip_update();
5206 # endif
5207 		}
5208 finished:
5209 		p_more = p_more_save;
5210 		if (options & SHELL_READ)
5211 		{
5212 		    if (ga.ga_len > 0)
5213 		    {
5214 			append_ga_line(&ga);
5215 			/* remember that the NL was missing */
5216 			curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
5217 		    }
5218 		    else
5219 			curbuf->b_no_eol_lnum = 0;
5220 		    ga_clear(&ga);
5221 		}
5222 
5223 		/*
5224 		 * Give all typeahead that wasn't used back to ui_inchar().
5225 		 */
5226 		if (ta_len)
5227 		    ui_inchar_undo(ta_buf, ta_len);
5228 		State = old_State;
5229 		if (toshell_fd >= 0)
5230 		    close(toshell_fd);
5231 		close(fromshell_fd);
5232 	    }
5233 # if defined(FEAT_XCLIPBOARD) && defined(FEAT_X11)
5234 	    else
5235 	    {
5236 		long delay_msec = 1;
5237 
5238 		/*
5239 		 * Similar to the loop above, but only handle X events, no
5240 		 * I/O.
5241 		 */
5242 		for (;;)
5243 		{
5244 		    if (got_int)
5245 		    {
5246 			/* CTRL-C sends a signal to the child, we ignore it
5247 			 * ourselves */
5248 #  ifdef HAVE_SETSID
5249 			kill(-pid, SIGINT);
5250 #  else
5251 			kill(0, SIGINT);
5252 #  endif
5253 			got_int = FALSE;
5254 		    }
5255 # ifdef __NeXT__
5256 		    wait_pid = wait4(pid, &status, WNOHANG, (struct rusage *)0);
5257 # else
5258 		    wait_pid = waitpid(pid, &status, WNOHANG);
5259 # endif
5260 		    if ((wait_pid == (pid_t)-1 && errno == ECHILD)
5261 			    || (wait_pid == pid && WIFEXITED(status)))
5262 		    {
5263 			wait_pid = pid;
5264 			break;
5265 		    }
5266 
5267 		    /* Handle any X events, e.g. serving the clipboard. */
5268 		    clip_update();
5269 
5270 		    /* Wait for 1 to 10 msec. 1 is faster but gives the child
5271 		     * less time. */
5272 		    mch_delay(delay_msec, TRUE);
5273 		    if (++delay_msec > 10)
5274 			delay_msec = 10;
5275 		}
5276 	    }
5277 # endif
5278 
5279 	    /*
5280 	     * Wait until our child has exited.
5281 	     * Ignore wait() returning pids of other children and returning
5282 	     * because of some signal like SIGWINCH.
5283 	     * Don't wait if wait_pid was already set above, indicating the
5284 	     * child already exited.
5285 	     */
5286 	    if (wait_pid != pid)
5287 		wait_pid = wait4pid(pid, &status);
5288 
5289 # ifdef FEAT_GUI
5290 	    /* Close slave side of pty.  Only do this after the child has
5291 	     * exited, otherwise the child may hang when it tries to write on
5292 	     * the pty. */
5293 	    if (pty_master_fd >= 0)
5294 		close(pty_slave_fd);
5295 # endif
5296 
5297 	    /* Make sure the child that writes to the external program is
5298 	     * dead. */
5299 	    if (wpid > 0)
5300 	    {
5301 		kill(wpid, SIGKILL);
5302 		wait4pid(wpid, NULL);
5303 	    }
5304 
5305 # ifdef FEAT_JOB_CHANNEL
5306 	    --dont_check_job_ended;
5307 # endif
5308 
5309 	    /*
5310 	     * Set to raw mode right now, otherwise a CTRL-C after
5311 	     * catch_signals() will kill Vim.
5312 	     */
5313 	    if (tmode == TMODE_RAW)
5314 		settmode(TMODE_RAW);
5315 	    did_settmode = TRUE;
5316 	    set_signals();
5317 
5318 	    if (WIFEXITED(status))
5319 	    {
5320 		/* LINTED avoid "bitwise operation on signed value" */
5321 		retval = WEXITSTATUS(status);
5322 		if (retval != 0 && !emsg_silent)
5323 		{
5324 		    if (retval == EXEC_FAILED)
5325 		    {
5326 			msg_puts(_("\nCannot execute shell "));
5327 			msg_outtrans(p_sh);
5328 			msg_putchar('\n');
5329 		    }
5330 		    else if (!(options & SHELL_SILENT))
5331 		    {
5332 			msg_puts(_("\nshell returned "));
5333 			msg_outnum((long)retval);
5334 			msg_putchar('\n');
5335 		    }
5336 		}
5337 	    }
5338 	    else
5339 		msg_puts(_("\nCommand terminated\n"));
5340 	}
5341     }
5342 
5343 error:
5344     if (!did_settmode)
5345 	if (tmode == TMODE_RAW)
5346 	    settmode(TMODE_RAW);	/* set to raw mode */
5347 # ifdef FEAT_TITLE
5348     resettitle();
5349 # endif
5350     vim_free(argv);
5351     vim_free(tofree1);
5352     vim_free(tofree2);
5353 
5354     return retval;
5355 }
5356 #endif /* USE_SYSTEM */
5357 
5358     int
5359 mch_call_shell(
5360     char_u	*cmd,
5361     int		options)	/* SHELL_*, see vim.h */
5362 {
5363 #if defined(FEAT_GUI) && defined(FEAT_TERMINAL)
5364     if (gui.in_use && vim_strchr(p_go, GO_TERMINAL) != NULL)
5365 	return mch_call_shell_terminal(cmd, options);
5366 #endif
5367 #ifdef USE_SYSTEM
5368     return mch_call_shell_system(cmd, options);
5369 #else
5370     return mch_call_shell_fork(cmd, options);
5371 #endif
5372 }
5373 
5374 #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
5375     void
5376 mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal)
5377 {
5378     pid_t	pid;
5379     int		fd_in[2] = {-1, -1};	/* for stdin */
5380     int		fd_out[2] = {-1, -1};	/* for stdout */
5381     int		fd_err[2] = {-1, -1};	/* for stderr */
5382     int		pty_master_fd = -1;
5383     int		pty_slave_fd = -1;
5384     channel_T	*channel = NULL;
5385     int		use_null_for_in = options->jo_io[PART_IN] == JIO_NULL;
5386     int		use_null_for_out = options->jo_io[PART_OUT] == JIO_NULL;
5387     int		use_null_for_err = options->jo_io[PART_ERR] == JIO_NULL;
5388     int		use_file_for_in = options->jo_io[PART_IN] == JIO_FILE;
5389     int		use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE;
5390     int		use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE;
5391     int		use_buffer_for_in = options->jo_io[PART_IN] == JIO_BUFFER;
5392     int		use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
5393     SIGSET_DECL(curset)
5394 
5395     if (use_out_for_err && use_null_for_out)
5396 	use_null_for_err = TRUE;
5397 
5398     /* default is to fail */
5399     job->jv_status = JOB_FAILED;
5400 
5401     if (options->jo_pty
5402 	    && (!(use_file_for_in || use_null_for_in)
5403 		|| !(use_file_for_out || use_null_for_out)
5404 		|| !(use_out_for_err || use_file_for_err || use_null_for_err)))
5405 	open_pty(&pty_master_fd, &pty_slave_fd,
5406 					    &job->jv_tty_out, &job->jv_tty_in);
5407 
5408     /* TODO: without the channel feature connect the child to /dev/null? */
5409     /* Open pipes for stdin, stdout, stderr. */
5410     if (use_file_for_in)
5411     {
5412 	char_u *fname = options->jo_io_name[PART_IN];
5413 
5414 	fd_in[0] = mch_open((char *)fname, O_RDONLY, 0);
5415 	if (fd_in[0] < 0)
5416 	{
5417 	    semsg(_(e_notopen), fname);
5418 	    goto failed;
5419 	}
5420     }
5421     else
5422 	/* When writing buffer lines to the input don't use the pty, so that
5423 	 * the pipe can be closed when all lines were written. */
5424 	if (!use_null_for_in && (pty_master_fd < 0 || use_buffer_for_in)
5425 							    && pipe(fd_in) < 0)
5426 	    goto failed;
5427 
5428     if (use_file_for_out)
5429     {
5430 	char_u *fname = options->jo_io_name[PART_OUT];
5431 
5432 	fd_out[1] = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
5433 	if (fd_out[1] < 0)
5434 	{
5435 	    semsg(_(e_notopen), fname);
5436 	    goto failed;
5437 	}
5438     }
5439     else if (!use_null_for_out && pty_master_fd < 0 && pipe(fd_out) < 0)
5440 	goto failed;
5441 
5442     if (use_file_for_err)
5443     {
5444 	char_u *fname = options->jo_io_name[PART_ERR];
5445 
5446 	fd_err[1] = mch_open((char *)fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
5447 	if (fd_err[1] < 0)
5448 	{
5449 	    semsg(_(e_notopen), fname);
5450 	    goto failed;
5451 	}
5452     }
5453     else if (!use_out_for_err && !use_null_for_err
5454 				      && pty_master_fd < 0 && pipe(fd_err) < 0)
5455 	goto failed;
5456 
5457     if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
5458     {
5459 	if (options->jo_set & JO_CHANNEL)
5460 	{
5461 	    channel = options->jo_channel;
5462 	    if (channel != NULL)
5463 		++channel->ch_refcount;
5464 	}
5465 	else
5466 	    channel = add_channel();
5467 	if (channel == NULL)
5468 	    goto failed;
5469 	if (job->jv_tty_out != NULL)
5470 	    ch_log(channel, "using pty %s on fd %d",
5471 					       job->jv_tty_out, pty_master_fd);
5472     }
5473 
5474     BLOCK_SIGNALS(&curset);
5475     pid = fork();	/* maybe we should use vfork() */
5476     if (pid == -1)
5477     {
5478 	/* failed to fork */
5479 	UNBLOCK_SIGNALS(&curset);
5480 	goto failed;
5481     }
5482     if (pid == 0)
5483     {
5484 	int	null_fd = -1;
5485 	int	stderr_works = TRUE;
5486 
5487 	/* child */
5488 	reset_signals();		/* handle signals normally */
5489 	UNBLOCK_SIGNALS(&curset);
5490 
5491 # ifdef FEAT_JOB_CHANNEL
5492 	if (ch_log_active())
5493 	    /* close the log file in the child */
5494 	    ch_logfile((char_u *)"", (char_u *)"");
5495 # endif
5496 
5497 # ifdef HAVE_SETSID
5498 	/* Create our own process group, so that the child and all its
5499 	 * children can be kill()ed.  Don't do this when using pipes,
5500 	 * because stdin is not a tty, we would lose /dev/tty. */
5501 	(void)setsid();
5502 # endif
5503 
5504 # ifdef FEAT_TERMINAL
5505 	if (options->jo_term_rows > 0)
5506 	{
5507 	    char *term = (char *)T_NAME;
5508 
5509 #ifdef FEAT_GUI
5510 	    if (term_is_gui(T_NAME))
5511 		/* In the GUI 'term' is not what we want, use $TERM. */
5512 		term = getenv("TERM");
5513 #endif
5514 	    /* Use 'term' or $TERM if it starts with "xterm", otherwise fall
5515 	     * back to "xterm". */
5516 	    if (term == NULL || *term == NUL || STRNCMP(term, "xterm", 5) != 0)
5517 		term = "xterm";
5518 	    set_child_environment(
5519 		    (long)options->jo_term_rows,
5520 		    (long)options->jo_term_cols,
5521 		    term,
5522 		    is_terminal);
5523 	}
5524 	else
5525 # endif
5526 	    set_default_child_environment(is_terminal);
5527 
5528 	if (options->jo_env != NULL)
5529 	{
5530 	    dict_T	*dict = options->jo_env;
5531 	    hashitem_T	*hi;
5532 	    int		todo = (int)dict->dv_hashtab.ht_used;
5533 
5534 	    for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
5535 		if (!HASHITEM_EMPTY(hi))
5536 		{
5537 		    typval_T *item = &dict_lookup(hi)->di_tv;
5538 
5539 		    vim_setenv((char_u*)hi->hi_key, tv_get_string(item));
5540 		    --todo;
5541 		}
5542 	}
5543 
5544 	if (use_null_for_in || use_null_for_out || use_null_for_err)
5545 	{
5546 	    null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
5547 	    if (null_fd < 0)
5548 	    {
5549 		perror("opening /dev/null failed");
5550 		_exit(OPEN_NULL_FAILED);
5551 	    }
5552 	}
5553 
5554 	if (pty_slave_fd >= 0)
5555 	{
5556 	    /* push stream discipline modules */
5557 	    setup_slavepty(pty_slave_fd);
5558 #  ifdef TIOCSCTTY
5559 	    /* Try to become controlling tty (probably doesn't work,
5560 	     * unless run by root) */
5561 	    ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
5562 #  endif
5563 	}
5564 
5565 	/* set up stdin for the child */
5566 	close(0);
5567 	if (use_null_for_in && null_fd >= 0)
5568 	    vim_ignored = dup(null_fd);
5569 	else if (fd_in[0] < 0)
5570 	    vim_ignored = dup(pty_slave_fd);
5571 	else
5572 	    vim_ignored = dup(fd_in[0]);
5573 
5574 	/* set up stderr for the child */
5575 	close(2);
5576 	if (use_null_for_err && null_fd >= 0)
5577 	{
5578 	    vim_ignored = dup(null_fd);
5579 	    stderr_works = FALSE;
5580 	}
5581 	else if (use_out_for_err)
5582 	    vim_ignored = dup(fd_out[1]);
5583 	else if (fd_err[1] < 0)
5584 	    vim_ignored = dup(pty_slave_fd);
5585 	else
5586 	    vim_ignored = dup(fd_err[1]);
5587 
5588 	/* set up stdout for the child */
5589 	close(1);
5590 	if (use_null_for_out && null_fd >= 0)
5591 	    vim_ignored = dup(null_fd);
5592 	else if (fd_out[1] < 0)
5593 	    vim_ignored = dup(pty_slave_fd);
5594 	else
5595 	    vim_ignored = dup(fd_out[1]);
5596 
5597 	if (fd_in[0] >= 0)
5598 	    close(fd_in[0]);
5599 	if (fd_in[1] >= 0)
5600 	    close(fd_in[1]);
5601 	if (fd_out[0] >= 0)
5602 	    close(fd_out[0]);
5603 	if (fd_out[1] >= 0)
5604 	    close(fd_out[1]);
5605 	if (fd_err[0] >= 0)
5606 	    close(fd_err[0]);
5607 	if (fd_err[1] >= 0)
5608 	    close(fd_err[1]);
5609 	if (pty_master_fd >= 0)
5610 	{
5611 	    close(pty_master_fd); /* not used in the child */
5612 	    close(pty_slave_fd);  /* was duped above */
5613 	}
5614 
5615 	if (null_fd >= 0)
5616 	    close(null_fd);
5617 
5618 	if (options->jo_cwd != NULL && mch_chdir((char *)options->jo_cwd) != 0)
5619 	    _exit(EXEC_FAILED);
5620 
5621 	/* See above for type of argv. */
5622 	execvp(argv[0], argv);
5623 
5624 	if (stderr_works)
5625 	    perror("executing job failed");
5626 # ifdef EXITFREE
5627 	/* calling free_all_mem() here causes problems. Ignore valgrind
5628 	 * reporting possibly leaked memory. */
5629 # endif
5630 	_exit(EXEC_FAILED);	    /* exec failed, return failure code */
5631     }
5632 
5633     /* parent */
5634     UNBLOCK_SIGNALS(&curset);
5635 
5636     job->jv_pid = pid;
5637     job->jv_status = JOB_STARTED;
5638     job->jv_channel = channel;  /* ch_refcount was set above */
5639 
5640     if (pty_master_fd >= 0)
5641 	close(pty_slave_fd); /* not used in the parent */
5642     /* close child stdin, stdout and stderr */
5643     if (fd_in[0] >= 0)
5644 	close(fd_in[0]);
5645     if (fd_out[1] >= 0)
5646 	close(fd_out[1]);
5647     if (fd_err[1] >= 0)
5648 	close(fd_err[1]);
5649     if (channel != NULL)
5650     {
5651 	int in_fd = INVALID_FD;
5652 	int out_fd = INVALID_FD;
5653 	int err_fd = INVALID_FD;
5654 
5655 	if (!(use_file_for_in || use_null_for_in))
5656 	    in_fd = fd_in[1] >= 0 ? fd_in[1] : pty_master_fd;
5657 
5658 	if (!(use_file_for_out || use_null_for_out))
5659 	    out_fd = fd_out[0] >= 0 ? fd_out[0] : pty_master_fd;
5660 
5661 	// When using pty_master_fd only set it for stdout, do not duplicate
5662 	// it for stderr, it only needs to be read once.
5663 	if (!(use_out_for_err || use_file_for_err || use_null_for_err))
5664 	{
5665 	    if (fd_err[0] >= 0)
5666 		err_fd = fd_err[0];
5667 	    else if (out_fd != pty_master_fd)
5668 		err_fd = pty_master_fd;
5669 	}
5670 
5671 	channel_set_pipes(channel, in_fd, out_fd, err_fd);
5672 	channel_set_job(channel, job, options);
5673     }
5674     else
5675     {
5676 	if (fd_in[1] >= 0)
5677 	    close(fd_in[1]);
5678 	if (fd_out[0] >= 0)
5679 	    close(fd_out[0]);
5680 	if (fd_err[0] >= 0)
5681 	    close(fd_err[0]);
5682 	if (pty_master_fd >= 0)
5683 	    close(pty_master_fd);
5684     }
5685 
5686     /* success! */
5687     return;
5688 
5689 failed:
5690     channel_unref(channel);
5691     if (fd_in[0] >= 0)
5692 	close(fd_in[0]);
5693     if (fd_in[1] >= 0)
5694 	close(fd_in[1]);
5695     if (fd_out[0] >= 0)
5696 	close(fd_out[0]);
5697     if (fd_out[1] >= 0)
5698 	close(fd_out[1]);
5699     if (fd_err[0] >= 0)
5700 	close(fd_err[0]);
5701     if (fd_err[1] >= 0)
5702 	close(fd_err[1]);
5703     if (pty_master_fd >= 0)
5704 	close(pty_master_fd);
5705     if (pty_slave_fd >= 0)
5706 	close(pty_slave_fd);
5707 }
5708 
5709     static char_u *
5710 get_signal_name(int sig)
5711 {
5712     int		i;
5713     char_u	numbuf[NUMBUFLEN];
5714 
5715     if (sig == SIGKILL)
5716 	return vim_strsave((char_u *)"kill");
5717 
5718     for (i = 0; signal_info[i].sig != -1; i++)
5719 	if (sig == signal_info[i].sig)
5720 	    return strlow_save((char_u *)signal_info[i].name);
5721 
5722     vim_snprintf((char *)numbuf, NUMBUFLEN, "%d", sig);
5723     return vim_strsave(numbuf);
5724 }
5725 
5726     char *
5727 mch_job_status(job_T *job)
5728 {
5729 # ifdef HAVE_UNION_WAIT
5730     union wait	status;
5731 # else
5732     int		status = -1;
5733 # endif
5734     pid_t	wait_pid = 0;
5735 
5736 # ifdef __NeXT__
5737     wait_pid = wait4(job->jv_pid, &status, WNOHANG, (struct rusage *)0);
5738 # else
5739     wait_pid = waitpid(job->jv_pid, &status, WNOHANG);
5740 # endif
5741     if (wait_pid == -1)
5742     {
5743 	/* process must have exited */
5744 	if (job->jv_status < JOB_ENDED)
5745 	    ch_log(job->jv_channel, "Job no longer exists: %s",
5746 							      strerror(errno));
5747 	goto return_dead;
5748     }
5749     if (wait_pid == 0)
5750 	return "run";
5751     if (WIFEXITED(status))
5752     {
5753 	/* LINTED avoid "bitwise operation on signed value" */
5754 	job->jv_exitval = WEXITSTATUS(status);
5755 	if (job->jv_status < JOB_ENDED)
5756 	    ch_log(job->jv_channel, "Job exited with %d", job->jv_exitval);
5757 	goto return_dead;
5758     }
5759     if (WIFSIGNALED(status))
5760     {
5761 	job->jv_exitval = -1;
5762 	job->jv_termsig = get_signal_name(WTERMSIG(status));
5763 	if (job->jv_status < JOB_ENDED && job->jv_termsig != NULL)
5764 	    ch_log(job->jv_channel, "Job terminated by signal \"%s\"",
5765 							      job->jv_termsig);
5766 	goto return_dead;
5767     }
5768     return "run";
5769 
5770 return_dead:
5771     if (job->jv_status < JOB_ENDED)
5772 	job->jv_status = JOB_ENDED;
5773     return "dead";
5774 }
5775 
5776     job_T *
5777 mch_detect_ended_job(job_T *job_list)
5778 {
5779 # ifdef HAVE_UNION_WAIT
5780     union wait	status;
5781 # else
5782     int		status = -1;
5783 # endif
5784     pid_t	wait_pid = 0;
5785     job_T	*job;
5786 
5787 # ifndef USE_SYSTEM
5788     /* Do not do this when waiting for a shell command to finish, we would get
5789      * the exit value here (and discard it), the exit value obtained there
5790      * would then be wrong.  */
5791     if (dont_check_job_ended > 0)
5792 	return NULL;
5793 # endif
5794 
5795 # ifdef __NeXT__
5796     wait_pid = wait4(-1, &status, WNOHANG, (struct rusage *)0);
5797 # else
5798     wait_pid = waitpid(-1, &status, WNOHANG);
5799 # endif
5800     if (wait_pid <= 0)
5801 	/* no process ended */
5802 	return NULL;
5803     for (job = job_list; job != NULL; job = job->jv_next)
5804     {
5805 	if (job->jv_pid == wait_pid)
5806 	{
5807 	    if (WIFEXITED(status))
5808 		/* LINTED avoid "bitwise operation on signed value" */
5809 		job->jv_exitval = WEXITSTATUS(status);
5810 	    else if (WIFSIGNALED(status))
5811 	    {
5812 		job->jv_exitval = -1;
5813 		job->jv_termsig = get_signal_name(WTERMSIG(status));
5814 	    }
5815 	    if (job->jv_status < JOB_ENDED)
5816 	    {
5817 		ch_log(job->jv_channel, "Job ended");
5818 		job->jv_status = JOB_ENDED;
5819 	    }
5820 	    return job;
5821 	}
5822     }
5823     return NULL;
5824 }
5825 
5826 /*
5827  * Send a (deadly) signal to "job".
5828  * Return FAIL if "how" is not a valid name.
5829  */
5830     int
5831 mch_signal_job(job_T *job, char_u *how)
5832 {
5833     int	    sig = -1;
5834 
5835     if (*how == NUL || STRCMP(how, "term") == 0)
5836 	sig = SIGTERM;
5837     else if (STRCMP(how, "hup") == 0)
5838 	sig = SIGHUP;
5839     else if (STRCMP(how, "quit") == 0)
5840 	sig = SIGQUIT;
5841     else if (STRCMP(how, "int") == 0)
5842 	sig = SIGINT;
5843     else if (STRCMP(how, "kill") == 0)
5844 	sig = SIGKILL;
5845 #ifdef SIGWINCH
5846     else if (STRCMP(how, "winch") == 0)
5847 	sig = SIGWINCH;
5848 #endif
5849     else if (isdigit(*how))
5850 	sig = atoi((char *)how);
5851     else
5852 	return FAIL;
5853 
5854     // Never kill ourselves!
5855     if (job->jv_pid != 0)
5856     {
5857 	// TODO: have an option to only kill the process, not the group?
5858 	kill(-job->jv_pid, sig);
5859 	kill(job->jv_pid, sig);
5860     }
5861 
5862     return OK;
5863 }
5864 
5865 /*
5866  * Clear the data related to "job".
5867  */
5868     void
5869 mch_clear_job(job_T *job)
5870 {
5871     /* call waitpid because child process may become zombie */
5872 # ifdef __NeXT__
5873     (void)wait4(job->jv_pid, NULL, WNOHANG, (struct rusage *)0);
5874 # else
5875     (void)waitpid(job->jv_pid, NULL, WNOHANG);
5876 # endif
5877 }
5878 #endif
5879 
5880 #if defined(FEAT_TERMINAL) || defined(PROTO)
5881     int
5882 mch_create_pty_channel(job_T *job, jobopt_T *options)
5883 {
5884     int		pty_master_fd = -1;
5885     int		pty_slave_fd = -1;
5886     channel_T	*channel;
5887 
5888     open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_out, &job->jv_tty_in);
5889     close(pty_slave_fd);
5890 
5891     channel = add_channel();
5892     if (channel == NULL)
5893     {
5894 	close(pty_master_fd);
5895 	return FAIL;
5896     }
5897     if (job->jv_tty_out != NULL)
5898 	ch_log(channel, "using pty %s on fd %d",
5899 					       job->jv_tty_out, pty_master_fd);
5900     job->jv_channel = channel;  /* ch_refcount was set by add_channel() */
5901     channel->ch_keep_open = TRUE;
5902 
5903     /* Only set the pty_master_fd for stdout, do not duplicate it for stderr,
5904      * it only needs to be read once. */
5905     channel_set_pipes(channel, pty_master_fd, pty_master_fd, INVALID_FD);
5906     channel_set_job(channel, job, options);
5907     return OK;
5908 }
5909 #endif
5910 
5911 /*
5912  * Check for CTRL-C typed by reading all available characters.
5913  * In cooked mode we should get SIGINT, no need to check.
5914  */
5915     void
5916 mch_breakcheck(int force)
5917 {
5918     if ((curr_tmode == TMODE_RAW || force)
5919 			       && RealWaitForChar(read_cmd_fd, 0L, NULL, NULL))
5920 	fill_input_buf(FALSE);
5921 }
5922 
5923 /*
5924  * Wait "msec" msec until a character is available from the mouse, keyboard,
5925  * from inbuf[].
5926  * "msec" == -1 will block forever.
5927  * Invokes timer callbacks when needed.
5928  * When "ignore_input" is TRUE even check for pending input when input is
5929  * already available.
5930  * "interrupted" (if not NULL) is set to TRUE when no character is available
5931  * but something else needs to be done.
5932  * Returns TRUE when a character is available.
5933  * When a GUI is being used, this will never get called -- webb
5934  */
5935     static int
5936 WaitForChar(long msec, int *interrupted, int ignore_input)
5937 {
5938 #ifdef FEAT_TIMERS
5939     return ui_wait_for_chars_or_timer(
5940 		    msec, WaitForCharOrMouse, interrupted, ignore_input) == OK;
5941 #else
5942     return WaitForCharOrMouse(msec, interrupted, ignore_input);
5943 #endif
5944 }
5945 
5946 /*
5947  * Wait "msec" msec until a character is available from the mouse or keyboard
5948  * or from inbuf[].
5949  * "msec" == -1 will block forever.
5950  * for "ignore_input" see WaitForCharOr().
5951  * "interrupted" (if not NULL) is set to TRUE when no character is available
5952  * but something else needs to be done.
5953  * When a GUI is being used, this will never get called -- webb
5954  */
5955     static int
5956 WaitForCharOrMouse(long msec, int *interrupted, int ignore_input)
5957 {
5958 #ifdef FEAT_MOUSE_GPM
5959     int		gpm_process_wanted;
5960 #endif
5961 #ifdef FEAT_XCLIPBOARD
5962     int		rest;
5963 #endif
5964     int		avail;
5965 
5966     if (!ignore_input && input_available())	    /* something in inbuf[] */
5967 	return 1;
5968 
5969 #if defined(FEAT_MOUSE_DEC)
5970     /* May need to query the mouse position. */
5971     if (WantQueryMouse)
5972     {
5973 	WantQueryMouse = FALSE;
5974 	if (!no_query_mouse_for_testing)
5975 	    mch_write((char_u *)IF_EB("\033[1'|", ESC_STR "[1'|"), 5);
5976     }
5977 #endif
5978 
5979     /*
5980      * For FEAT_MOUSE_GPM and FEAT_XCLIPBOARD we loop here to process mouse
5981      * events.  This is a bit complicated, because they might both be defined.
5982      */
5983 #if defined(FEAT_MOUSE_GPM) || defined(FEAT_XCLIPBOARD)
5984 # ifdef FEAT_XCLIPBOARD
5985     rest = 0;
5986     if (do_xterm_trace())
5987 	rest = msec;
5988 # endif
5989     do
5990     {
5991 # ifdef FEAT_XCLIPBOARD
5992 	if (rest != 0)
5993 	{
5994 	    msec = XT_TRACE_DELAY;
5995 	    if (rest >= 0 && rest < XT_TRACE_DELAY)
5996 		msec = rest;
5997 	    if (rest >= 0)
5998 		rest -= msec;
5999 	}
6000 # endif
6001 # ifdef FEAT_SOUND_CANBERRA
6002 	// Invoke any pending sound callbacks.
6003 	if (has_sound_callback_in_queue())
6004 	    invoke_sound_callback();
6005 # endif
6006 # ifdef FEAT_MOUSE_GPM
6007 	gpm_process_wanted = 0;
6008 	avail = RealWaitForChar(read_cmd_fd, msec,
6009 					     &gpm_process_wanted, interrupted);
6010 	if (!avail && !gpm_process_wanted)
6011 # else
6012 	avail = RealWaitForChar(read_cmd_fd, msec, NULL, interrupted);
6013 	if (!avail)
6014 # endif
6015 	{
6016 	    if (!ignore_input && input_available())
6017 		return 1;
6018 # ifdef FEAT_XCLIPBOARD
6019 	    if (rest == 0 || !do_xterm_trace())
6020 # endif
6021 		break;
6022 	}
6023     }
6024     while (FALSE
6025 # ifdef FEAT_MOUSE_GPM
6026 	   || (gpm_process_wanted && mch_gpm_process() == 0)
6027 # endif
6028 # ifdef FEAT_XCLIPBOARD
6029 	   || (!avail && rest != 0)
6030 # endif
6031 	  )
6032 	;
6033 
6034 #else
6035     avail = RealWaitForChar(read_cmd_fd, msec, NULL, interrupted);
6036 #endif
6037     return avail;
6038 }
6039 
6040 #ifndef VMS
6041 /*
6042  * Wait "msec" msec until a character is available from file descriptor "fd".
6043  * "msec" == 0 will check for characters once.
6044  * "msec" == -1 will block until a character is available.
6045  * When a GUI is being used, this will not be used for input -- webb
6046  * Or when a Linux GPM mouse event is waiting.
6047  * Or when a clientserver message is on the queue.
6048  * "interrupted" (if not NULL) is set to TRUE when no character is available
6049  * but something else needs to be done.
6050  */
6051 #if defined(__BEOS__)
6052     int
6053 #else
6054     static int
6055 #endif
6056 RealWaitForChar(int fd, long msec, int *check_for_gpm UNUSED, int *interrupted)
6057 {
6058     int		ret;
6059     int		result;
6060 #if defined(FEAT_XCLIPBOARD) || defined(USE_XSMP) || defined(FEAT_MZSCHEME)
6061     static int	busy = FALSE;
6062 
6063     /* May retry getting characters after an event was handled. */
6064 # define MAY_LOOP
6065 
6066 # ifdef ELAPSED_FUNC
6067     /* Remember at what time we started, so that we know how much longer we
6068      * should wait after being interrupted. */
6069     long	start_msec = msec;
6070     elapsed_T	start_tv;
6071 
6072     if (msec > 0)
6073 	ELAPSED_INIT(start_tv);
6074 # endif
6075 
6076     /* Handle being called recursively.  This may happen for the session
6077      * manager stuff, it may save the file, which does a breakcheck. */
6078     if (busy)
6079 	return 0;
6080 #endif
6081 
6082 #ifdef MAY_LOOP
6083     for (;;)
6084 #endif
6085     {
6086 #ifdef MAY_LOOP
6087 	int		finished = TRUE; /* default is to 'loop' just once */
6088 # ifdef FEAT_MZSCHEME
6089 	int		mzquantum_used = FALSE;
6090 # endif
6091 #endif
6092 #ifndef HAVE_SELECT
6093 			/* each channel may use in, out and err */
6094 	struct pollfd   fds[6 + 3 * MAX_OPEN_CHANNELS];
6095 	int		nfd;
6096 # ifdef FEAT_XCLIPBOARD
6097 	int		xterm_idx = -1;
6098 # endif
6099 # ifdef FEAT_MOUSE_GPM
6100 	int		gpm_idx = -1;
6101 # endif
6102 # ifdef USE_XSMP
6103 	int		xsmp_idx = -1;
6104 # endif
6105 	int		towait = (int)msec;
6106 
6107 # ifdef FEAT_MZSCHEME
6108 	mzvim_check_threads();
6109 	if (mzthreads_allowed() && p_mzq > 0 && (msec < 0 || msec > p_mzq))
6110 	{
6111 	    towait = (int)p_mzq;    /* don't wait longer than 'mzquantum' */
6112 	    mzquantum_used = TRUE;
6113 	}
6114 # endif
6115 	fds[0].fd = fd;
6116 	fds[0].events = POLLIN;
6117 	nfd = 1;
6118 
6119 # ifdef FEAT_XCLIPBOARD
6120 	may_restore_clipboard();
6121 	if (xterm_Shell != (Widget)0)
6122 	{
6123 	    xterm_idx = nfd;
6124 	    fds[nfd].fd = ConnectionNumber(xterm_dpy);
6125 	    fds[nfd].events = POLLIN;
6126 	    nfd++;
6127 	}
6128 # endif
6129 # ifdef FEAT_MOUSE_GPM
6130 	if (check_for_gpm != NULL && gpm_flag && gpm_fd >= 0)
6131 	{
6132 	    gpm_idx = nfd;
6133 	    fds[nfd].fd = gpm_fd;
6134 	    fds[nfd].events = POLLIN;
6135 	    nfd++;
6136 	}
6137 # endif
6138 # ifdef USE_XSMP
6139 	if (xsmp_icefd != -1)
6140 	{
6141 	    xsmp_idx = nfd;
6142 	    fds[nfd].fd = xsmp_icefd;
6143 	    fds[nfd].events = POLLIN;
6144 	    nfd++;
6145 	}
6146 # endif
6147 #ifdef FEAT_JOB_CHANNEL
6148 	nfd = channel_poll_setup(nfd, &fds, &towait);
6149 #endif
6150 	if (interrupted != NULL)
6151 	    *interrupted = FALSE;
6152 
6153 	ret = poll(fds, nfd, towait);
6154 
6155 	result = ret > 0 && (fds[0].revents & POLLIN);
6156 	if (result == 0 && interrupted != NULL && ret > 0)
6157 	    *interrupted = TRUE;
6158 
6159 # ifdef FEAT_MZSCHEME
6160 	if (ret == 0 && mzquantum_used)
6161 	    /* MzThreads scheduling is required and timeout occurred */
6162 	    finished = FALSE;
6163 # endif
6164 
6165 # ifdef FEAT_XCLIPBOARD
6166 	if (xterm_Shell != (Widget)0 && (fds[xterm_idx].revents & POLLIN))
6167 	{
6168 	    xterm_update();      /* Maybe we should hand out clipboard */
6169 	    if (--ret == 0 && !input_available())
6170 		/* Try again */
6171 		finished = FALSE;
6172 	}
6173 # endif
6174 # ifdef FEAT_MOUSE_GPM
6175 	if (gpm_idx >= 0 && (fds[gpm_idx].revents & POLLIN))
6176 	    *check_for_gpm = 1;
6177 # endif
6178 # ifdef USE_XSMP
6179 	if (xsmp_idx >= 0 && (fds[xsmp_idx].revents & (POLLIN | POLLHUP)))
6180 	{
6181 	    if (fds[xsmp_idx].revents & POLLIN)
6182 	    {
6183 		busy = TRUE;
6184 		xsmp_handle_requests();
6185 		busy = FALSE;
6186 	    }
6187 	    else if (fds[xsmp_idx].revents & POLLHUP)
6188 	    {
6189 		if (p_verbose > 0)
6190 		    verb_msg(_("XSMP lost ICE connection"));
6191 		xsmp_close();
6192 	    }
6193 	    if (--ret == 0)
6194 		finished = FALSE;	/* Try again */
6195 	}
6196 # endif
6197 #ifdef FEAT_JOB_CHANNEL
6198 	// also call when ret == 0, we may be polling a keep-open channel
6199 	if (ret >= 0)
6200 	    channel_poll_check(ret, &fds);
6201 #endif
6202 
6203 #else /* HAVE_SELECT */
6204 
6205 	struct timeval  tv;
6206 	struct timeval	*tvp;
6207 	// These are static because they can take 8 Kbyte each and cause the
6208 	// signal stack to run out with -O3.
6209 	static fd_set	rfds, wfds, efds;
6210 	int		maxfd;
6211 	long		towait = msec;
6212 
6213 # ifdef FEAT_MZSCHEME
6214 	mzvim_check_threads();
6215 	if (mzthreads_allowed() && p_mzq > 0 && (msec < 0 || msec > p_mzq))
6216 	{
6217 	    towait = p_mzq;	/* don't wait longer than 'mzquantum' */
6218 	    mzquantum_used = TRUE;
6219 	}
6220 # endif
6221 
6222 	if (towait >= 0)
6223 	{
6224 	    tv.tv_sec = towait / 1000;
6225 	    tv.tv_usec = (towait % 1000) * (1000000/1000);
6226 	    tvp = &tv;
6227 	}
6228 	else
6229 	    tvp = NULL;
6230 
6231 	/*
6232 	 * Select on ready for reading and exceptional condition (end of file).
6233 	 */
6234 select_eintr:
6235 	FD_ZERO(&rfds);
6236 	FD_ZERO(&wfds);
6237 	FD_ZERO(&efds);
6238 	FD_SET(fd, &rfds);
6239 # if !defined(__QNX__) && !defined(__CYGWIN32__)
6240 	/* For QNX select() always returns 1 if this is set.  Why? */
6241 	FD_SET(fd, &efds);
6242 # endif
6243 	maxfd = fd;
6244 
6245 # ifdef FEAT_XCLIPBOARD
6246 	may_restore_clipboard();
6247 	if (xterm_Shell != (Widget)0)
6248 	{
6249 	    FD_SET(ConnectionNumber(xterm_dpy), &rfds);
6250 	    if (maxfd < ConnectionNumber(xterm_dpy))
6251 		maxfd = ConnectionNumber(xterm_dpy);
6252 
6253 	    /* An event may have already been read but not handled.  In
6254 	     * particulary, XFlush may cause this. */
6255 	    xterm_update();
6256 	}
6257 # endif
6258 # ifdef FEAT_MOUSE_GPM
6259 	if (check_for_gpm != NULL && gpm_flag && gpm_fd >= 0)
6260 	{
6261 	    FD_SET(gpm_fd, &rfds);
6262 	    FD_SET(gpm_fd, &efds);
6263 	    if (maxfd < gpm_fd)
6264 		maxfd = gpm_fd;
6265 	}
6266 # endif
6267 # ifdef USE_XSMP
6268 	if (xsmp_icefd != -1)
6269 	{
6270 	    FD_SET(xsmp_icefd, &rfds);
6271 	    FD_SET(xsmp_icefd, &efds);
6272 	    if (maxfd < xsmp_icefd)
6273 		maxfd = xsmp_icefd;
6274 	}
6275 # endif
6276 # ifdef FEAT_JOB_CHANNEL
6277 	maxfd = channel_select_setup(maxfd, &rfds, &wfds, &tv, &tvp);
6278 # endif
6279 	if (interrupted != NULL)
6280 	    *interrupted = FALSE;
6281 
6282 	ret = select(maxfd + 1, SELECT_TYPE_ARG234 &rfds,
6283 		      SELECT_TYPE_ARG234 &wfds, SELECT_TYPE_ARG234 &efds, tvp);
6284 	result = ret > 0 && FD_ISSET(fd, &rfds);
6285 	if (result)
6286 	    --ret;
6287 	else if (interrupted != NULL && ret > 0)
6288 	    *interrupted = TRUE;
6289 
6290 # ifdef EINTR
6291 	if (ret == -1 && errno == EINTR)
6292 	{
6293 	    /* Check whether window has been resized, EINTR may be caused by
6294 	     * SIGWINCH. */
6295 	    if (do_resize)
6296 		handle_resize();
6297 
6298 	    /* Interrupted by a signal, need to try again.  We ignore msec
6299 	     * here, because we do want to check even after a timeout if
6300 	     * characters are available.  Needed for reading output of an
6301 	     * external command after the process has finished. */
6302 	    goto select_eintr;
6303 	}
6304 # endif
6305 # ifdef __TANDEM
6306 	if (ret == -1 && errno == ENOTSUP)
6307 	{
6308 	    FD_ZERO(&rfds);
6309 	    FD_ZERO(&efds);
6310 	    ret = 0;
6311 	}
6312 # endif
6313 # ifdef FEAT_MZSCHEME
6314 	if (ret == 0 && mzquantum_used)
6315 	    /* loop if MzThreads must be scheduled and timeout occurred */
6316 	    finished = FALSE;
6317 # endif
6318 
6319 # ifdef FEAT_XCLIPBOARD
6320 	if (ret > 0 && xterm_Shell != (Widget)0
6321 		&& FD_ISSET(ConnectionNumber(xterm_dpy), &rfds))
6322 	{
6323 	    xterm_update();	      /* Maybe we should hand out clipboard */
6324 	    /* continue looping when we only got the X event and the input
6325 	     * buffer is empty */
6326 	    if (--ret == 0 && !input_available())
6327 	    {
6328 		/* Try again */
6329 		finished = FALSE;
6330 	    }
6331 	}
6332 # endif
6333 # ifdef FEAT_MOUSE_GPM
6334 	if (ret > 0 && gpm_flag && check_for_gpm != NULL && gpm_fd >= 0)
6335 	{
6336 	    if (FD_ISSET(gpm_fd, &efds))
6337 		gpm_close();
6338 	    else if (FD_ISSET(gpm_fd, &rfds))
6339 		*check_for_gpm = 1;
6340 	}
6341 # endif
6342 # ifdef USE_XSMP
6343 	if (ret > 0 && xsmp_icefd != -1)
6344 	{
6345 	    if (FD_ISSET(xsmp_icefd, &efds))
6346 	    {
6347 		if (p_verbose > 0)
6348 		    verb_msg(_("XSMP lost ICE connection"));
6349 		xsmp_close();
6350 		if (--ret == 0)
6351 		    finished = FALSE;   /* keep going if event was only one */
6352 	    }
6353 	    else if (FD_ISSET(xsmp_icefd, &rfds))
6354 	    {
6355 		busy = TRUE;
6356 		xsmp_handle_requests();
6357 		busy = FALSE;
6358 		if (--ret == 0)
6359 		    finished = FALSE;   /* keep going if event was only one */
6360 	    }
6361 	}
6362 # endif
6363 #ifdef FEAT_JOB_CHANNEL
6364 	/* also call when ret == 0, we may be polling a keep-open channel */
6365 	if (ret >= 0)
6366 	    ret = channel_select_check(ret, &rfds, &wfds);
6367 #endif
6368 
6369 #endif /* HAVE_SELECT */
6370 
6371 #ifdef MAY_LOOP
6372 	if (finished || msec == 0)
6373 	    break;
6374 
6375 # ifdef FEAT_CLIENTSERVER
6376 	if (server_waiting())
6377 	    break;
6378 # endif
6379 
6380 	/* We're going to loop around again, find out for how long */
6381 	if (msec > 0)
6382 	{
6383 # ifdef ELAPSED_FUNC
6384 	    /* Compute remaining wait time. */
6385 	    msec = start_msec - ELAPSED_FUNC(start_tv);
6386 # else
6387 	    /* Guess we got interrupted halfway. */
6388 	    msec = msec / 2;
6389 # endif
6390 	    if (msec <= 0)
6391 		break;	/* waited long enough */
6392 	}
6393 #endif
6394     }
6395 
6396     return result;
6397 }
6398 
6399 /*
6400  * Expand a path into all matching files and/or directories.  Handles "*",
6401  * "?", "[a-z]", "**", etc.
6402  * "path" has backslashes before chars that are not to be expanded.
6403  * Returns the number of matches found.
6404  */
6405     int
6406 mch_expandpath(
6407     garray_T	*gap,
6408     char_u	*path,
6409     int		flags)		/* EW_* flags */
6410 {
6411     return unix_expandpath(gap, path, 0, flags, FALSE);
6412 }
6413 
6414 /*
6415  * mch_expand_wildcards() - this code does wild-card pattern matching using
6416  * the shell
6417  *
6418  * return OK for success, FAIL for error (you may lose some memory) and put
6419  * an error message in *file.
6420  *
6421  * num_pat is number of input patterns
6422  * pat is array of pointers to input patterns
6423  * num_file is pointer to number of matched file names
6424  * file is pointer to array of pointers to matched file names
6425  */
6426 
6427 #ifndef SEEK_SET
6428 # define SEEK_SET 0
6429 #endif
6430 #ifndef SEEK_END
6431 # define SEEK_END 2
6432 #endif
6433 
6434 #define SHELL_SPECIAL (char_u *)"\t \"&'$;<>()\\|"
6435 
6436     int
6437 mch_expand_wildcards(
6438     int		   num_pat,
6439     char_u	 **pat,
6440     int		  *num_file,
6441     char_u	***file,
6442     int		   flags)	/* EW_* flags */
6443 {
6444     int		i;
6445     size_t	len;
6446     long	llen;
6447     char_u	*p;
6448     int		dir;
6449 
6450     /*
6451      * This is the non-OS/2 implementation (really Unix).
6452      */
6453     int		j;
6454     char_u	*tempname;
6455     char_u	*command;
6456     FILE	*fd;
6457     char_u	*buffer;
6458 #define STYLE_ECHO	0	/* use "echo", the default */
6459 #define STYLE_GLOB	1	/* use "glob", for csh */
6460 #define STYLE_VIMGLOB	2	/* use "vimglob", for Posix sh */
6461 #define STYLE_PRINT	3	/* use "print -N", for zsh */
6462 #define STYLE_BT	4	/* `cmd` expansion, execute the pattern
6463 				 * directly */
6464     int		shell_style = STYLE_ECHO;
6465     int		check_spaces;
6466     static int	did_find_nul = FALSE;
6467     int		ampersand = FALSE;
6468 		/* vimglob() function to define for Posix shell */
6469     static char *sh_vimglob_func = "vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
6470 
6471     *num_file = 0;	/* default: no files found */
6472     *file = NULL;
6473 
6474     /*
6475      * If there are no wildcards, just copy the names to allocated memory.
6476      * Saves a lot of time, because we don't have to start a new shell.
6477      */
6478     if (!have_wildcard(num_pat, pat))
6479 	return save_patterns(num_pat, pat, num_file, file);
6480 
6481 # ifdef HAVE_SANDBOX
6482     /* Don't allow any shell command in the sandbox. */
6483     if (sandbox != 0 && check_secure())
6484 	return FAIL;
6485 # endif
6486 
6487     /*
6488      * Don't allow the use of backticks in secure and restricted mode.
6489      */
6490     if (secure || restricted)
6491 	for (i = 0; i < num_pat; ++i)
6492 	    if (vim_strchr(pat[i], '`') != NULL
6493 		    && (check_restricted() || check_secure()))
6494 		return FAIL;
6495 
6496     /*
6497      * get a name for the temp file
6498      */
6499     if ((tempname = vim_tempname('o', FALSE)) == NULL)
6500     {
6501 	emsg(_(e_notmp));
6502 	return FAIL;
6503     }
6504 
6505     /*
6506      * Let the shell expand the patterns and write the result into the temp
6507      * file.
6508      * STYLE_BT:	NL separated
6509      *	    If expanding `cmd` execute it directly.
6510      * STYLE_GLOB:	NUL separated
6511      *	    If we use *csh, "glob" will work better than "echo".
6512      * STYLE_PRINT:	NL or NUL separated
6513      *	    If we use *zsh, "print -N" will work better than "glob".
6514      * STYLE_VIMGLOB:	NL separated
6515      *	    If we use *sh*, we define "vimglob()".
6516      * STYLE_ECHO:	space separated.
6517      *	    A shell we don't know, stay safe and use "echo".
6518      */
6519     if (num_pat == 1 && *pat[0] == '`'
6520 	    && (len = STRLEN(pat[0])) > 2
6521 	    && *(pat[0] + len - 1) == '`')
6522 	shell_style = STYLE_BT;
6523     else if ((len = STRLEN(p_sh)) >= 3)
6524     {
6525 	if (STRCMP(p_sh + len - 3, "csh") == 0)
6526 	    shell_style = STYLE_GLOB;
6527 	else if (STRCMP(p_sh + len - 3, "zsh") == 0)
6528 	    shell_style = STYLE_PRINT;
6529     }
6530     if (shell_style == STYLE_ECHO && strstr((char *)gettail(p_sh),
6531 								"sh") != NULL)
6532 	shell_style = STYLE_VIMGLOB;
6533 
6534     /* Compute the length of the command.  We need 2 extra bytes: for the
6535      * optional '&' and for the NUL.
6536      * Worst case: "unset nonomatch; print -N >" plus two is 29 */
6537     len = STRLEN(tempname) + 29;
6538     if (shell_style == STYLE_VIMGLOB)
6539 	len += STRLEN(sh_vimglob_func);
6540 
6541     for (i = 0; i < num_pat; ++i)
6542     {
6543 	/* Count the length of the patterns in the same way as they are put in
6544 	 * "command" below. */
6545 #ifdef USE_SYSTEM
6546 	len += STRLEN(pat[i]) + 3;	/* add space and two quotes */
6547 #else
6548 	++len;				/* add space */
6549 	for (j = 0; pat[i][j] != NUL; ++j)
6550 	{
6551 	    if (vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
6552 		++len;		/* may add a backslash */
6553 	    ++len;
6554 	}
6555 #endif
6556     }
6557     command = alloc(len);
6558     if (command == NULL)
6559     {
6560 	/* out of memory */
6561 	vim_free(tempname);
6562 	return FAIL;
6563     }
6564 
6565     /*
6566      * Build the shell command:
6567      * - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
6568      *	 recognizes this).
6569      * - Add the shell command to print the expanded names.
6570      * - Add the temp file name.
6571      * - Add the file name patterns.
6572      */
6573     if (shell_style == STYLE_BT)
6574     {
6575 	/* change `command; command& ` to (command; command ) */
6576 	STRCPY(command, "(");
6577 	STRCAT(command, pat[0] + 1);		/* exclude first backtick */
6578 	p = command + STRLEN(command) - 1;
6579 	*p-- = ')';				/* remove last backtick */
6580 	while (p > command && VIM_ISWHITE(*p))
6581 	    --p;
6582 	if (*p == '&')				/* remove trailing '&' */
6583 	{
6584 	    ampersand = TRUE;
6585 	    *p = ' ';
6586 	}
6587 	STRCAT(command, ">");
6588     }
6589     else
6590     {
6591 	if (flags & EW_NOTFOUND)
6592 	    STRCPY(command, "set nonomatch; ");
6593 	else
6594 	    STRCPY(command, "unset nonomatch; ");
6595 	if (shell_style == STYLE_GLOB)
6596 	    STRCAT(command, "glob >");
6597 	else if (shell_style == STYLE_PRINT)
6598 	    STRCAT(command, "print -N >");
6599 	else if (shell_style == STYLE_VIMGLOB)
6600 	    STRCAT(command, sh_vimglob_func);
6601 	else
6602 	    STRCAT(command, "echo >");
6603     }
6604 
6605     STRCAT(command, tempname);
6606 
6607     if (shell_style != STYLE_BT)
6608 	for (i = 0; i < num_pat; ++i)
6609 	{
6610 	    /* When using system() always add extra quotes, because the shell
6611 	     * is started twice.  Otherwise put a backslash before special
6612 	     * characters, except inside ``. */
6613 #ifdef USE_SYSTEM
6614 	    STRCAT(command, " \"");
6615 	    STRCAT(command, pat[i]);
6616 	    STRCAT(command, "\"");
6617 #else
6618 	    int intick = FALSE;
6619 
6620 	    p = command + STRLEN(command);
6621 	    *p++ = ' ';
6622 	    for (j = 0; pat[i][j] != NUL; ++j)
6623 	    {
6624 		if (pat[i][j] == '`')
6625 		    intick = !intick;
6626 		else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL)
6627 		{
6628 		    /* Remove a backslash, take char literally.  But keep
6629 		     * backslash inside backticks, before a special character
6630 		     * and before a backtick. */
6631 		    if (intick
6632 			  || vim_strchr(SHELL_SPECIAL, pat[i][j + 1]) != NULL
6633 			  || pat[i][j + 1] == '`')
6634 			*p++ = '\\';
6635 		    ++j;
6636 		}
6637 		else if (!intick
6638 			 && ((flags & EW_KEEPDOLLAR) == 0 || pat[i][j] != '$')
6639 			      && vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
6640 		    /* Put a backslash before a special character, but not
6641 		     * when inside ``. And not for $var when EW_KEEPDOLLAR is
6642 		     * set. */
6643 		    *p++ = '\\';
6644 
6645 		/* Copy one character. */
6646 		*p++ = pat[i][j];
6647 	    }
6648 	    *p = NUL;
6649 #endif
6650 	}
6651     if (flags & EW_SILENT)
6652 	show_shell_mess = FALSE;
6653     if (ampersand)
6654 	STRCAT(command, "&");		/* put the '&' after the redirection */
6655 
6656     /*
6657      * Using zsh -G: If a pattern has no matches, it is just deleted from
6658      * the argument list, otherwise zsh gives an error message and doesn't
6659      * expand any other pattern.
6660      */
6661     if (shell_style == STYLE_PRINT)
6662 	extra_shell_arg = (char_u *)"-G";   /* Use zsh NULL_GLOB option */
6663 
6664     /*
6665      * If we use -f then shell variables set in .cshrc won't get expanded.
6666      * vi can do it, so we will too, but it is only necessary if there is a "$"
6667      * in one of the patterns, otherwise we can still use the fast option.
6668      */
6669     else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat))
6670 	extra_shell_arg = (char_u *)"-f";	/* Use csh fast option */
6671 
6672     /*
6673      * execute the shell command
6674      */
6675     i = call_shell(command, SHELL_EXPAND | SHELL_SILENT);
6676 
6677     /* When running in the background, give it some time to create the temp
6678      * file, but don't wait for it to finish. */
6679     if (ampersand)
6680 	mch_delay(10L, TRUE);
6681 
6682     extra_shell_arg = NULL;		/* cleanup */
6683     show_shell_mess = TRUE;
6684     vim_free(command);
6685 
6686     if (i != 0)				/* mch_call_shell() failed */
6687     {
6688 	mch_remove(tempname);
6689 	vim_free(tempname);
6690 	/*
6691 	 * With interactive completion, the error message is not printed.
6692 	 * However with USE_SYSTEM, I don't know how to turn off error messages
6693 	 * from the shell, so screen may still get messed up -- webb.
6694 	 */
6695 #ifndef USE_SYSTEM
6696 	if (!(flags & EW_SILENT))
6697 #endif
6698 	{
6699 	    redraw_later_clear();	/* probably messed up screen */
6700 	    msg_putchar('\n');		/* clear bottom line quickly */
6701 	    cmdline_row = Rows - 1;	/* continue on last line */
6702 #ifdef USE_SYSTEM
6703 	    if (!(flags & EW_SILENT))
6704 #endif
6705 	    {
6706 		msg(_(e_wildexpand));
6707 		msg_start();		/* don't overwrite this message */
6708 	    }
6709 	}
6710 	/* If a `cmd` expansion failed, don't list `cmd` as a match, even when
6711 	 * EW_NOTFOUND is given */
6712 	if (shell_style == STYLE_BT)
6713 	    return FAIL;
6714 	goto notfound;
6715     }
6716 
6717     /*
6718      * read the names from the file into memory
6719      */
6720     fd = fopen((char *)tempname, READBIN);
6721     if (fd == NULL)
6722     {
6723 	/* Something went wrong, perhaps a file name with a special char. */
6724 	if (!(flags & EW_SILENT))
6725 	{
6726 	    msg(_(e_wildexpand));
6727 	    msg_start();		/* don't overwrite this message */
6728 	}
6729 	vim_free(tempname);
6730 	goto notfound;
6731     }
6732     fseek(fd, 0L, SEEK_END);
6733     llen = ftell(fd);			/* get size of temp file */
6734     fseek(fd, 0L, SEEK_SET);
6735     if (llen < 0)
6736 	/* just in case ftell() would fail */
6737 	buffer = NULL;
6738     else
6739 	buffer = alloc(llen + 1);
6740     if (buffer == NULL)
6741     {
6742 	/* out of memory */
6743 	mch_remove(tempname);
6744 	vim_free(tempname);
6745 	fclose(fd);
6746 	return FAIL;
6747     }
6748     len = llen;
6749     i = fread((char *)buffer, 1, len, fd);
6750     fclose(fd);
6751     mch_remove(tempname);
6752     if (i != (int)len)
6753     {
6754 	/* unexpected read error */
6755 	semsg(_(e_notread), tempname);
6756 	vim_free(tempname);
6757 	vim_free(buffer);
6758 	return FAIL;
6759     }
6760     vim_free(tempname);
6761 
6762 # ifdef __CYGWIN__
6763     /* Translate <CR><NL> into <NL>.  Caution, buffer may contain NUL. */
6764     p = buffer;
6765     for (i = 0; i < (int)len; ++i)
6766 	if (!(buffer[i] == CAR && buffer[i + 1] == NL))
6767 	    *p++ = buffer[i];
6768     len = p - buffer;
6769 # endif
6770 
6771 
6772     /* file names are separated with Space */
6773     if (shell_style == STYLE_ECHO)
6774     {
6775 	buffer[len] = '\n';		/* make sure the buffer ends in NL */
6776 	p = buffer;
6777 	for (i = 0; *p != '\n'; ++i)	/* count number of entries */
6778 	{
6779 	    while (*p != ' ' && *p != '\n')
6780 		++p;
6781 	    p = skipwhite(p);		/* skip to next entry */
6782 	}
6783     }
6784     /* file names are separated with NL */
6785     else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB)
6786     {
6787 	buffer[len] = NUL;		/* make sure the buffer ends in NUL */
6788 	p = buffer;
6789 	for (i = 0; *p != NUL; ++i)	/* count number of entries */
6790 	{
6791 	    while (*p != '\n' && *p != NUL)
6792 		++p;
6793 	    if (*p != NUL)
6794 		++p;
6795 	    p = skipwhite(p);		/* skip leading white space */
6796 	}
6797     }
6798     /* file names are separated with NUL */
6799     else
6800     {
6801 	/*
6802 	 * Some versions of zsh use spaces instead of NULs to separate
6803 	 * results.  Only do this when there is no NUL before the end of the
6804 	 * buffer, otherwise we would never be able to use file names with
6805 	 * embedded spaces when zsh does use NULs.
6806 	 * When we found a NUL once, we know zsh is OK, set did_find_nul and
6807 	 * don't check for spaces again.
6808 	 */
6809 	check_spaces = FALSE;
6810 	if (shell_style == STYLE_PRINT && !did_find_nul)
6811 	{
6812 	    /* If there is a NUL, set did_find_nul, else set check_spaces */
6813 	    buffer[len] = NUL;
6814 	    if (len && (int)STRLEN(buffer) < (int)len)
6815 		did_find_nul = TRUE;
6816 	    else
6817 		check_spaces = TRUE;
6818 	}
6819 
6820 	/*
6821 	 * Make sure the buffer ends with a NUL.  For STYLE_PRINT there
6822 	 * already is one, for STYLE_GLOB it needs to be added.
6823 	 */
6824 	if (len && buffer[len - 1] == NUL)
6825 	    --len;
6826 	else
6827 	    buffer[len] = NUL;
6828 	i = 0;
6829 	for (p = buffer; p < buffer + len; ++p)
6830 	    if (*p == NUL || (*p == ' ' && check_spaces))   /* count entry */
6831 	    {
6832 		++i;
6833 		*p = NUL;
6834 	    }
6835 	if (len)
6836 	    ++i;			/* count last entry */
6837     }
6838     if (i == 0)
6839     {
6840 	/*
6841 	 * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
6842 	 * /bin/sh will happily expand it to nothing rather than returning an
6843 	 * error; and hey, it's good to check anyway -- webb.
6844 	 */
6845 	vim_free(buffer);
6846 	goto notfound;
6847     }
6848     *num_file = i;
6849     *file = ALLOC_MULT(char_u *, i);
6850     if (*file == NULL)
6851     {
6852 	/* out of memory */
6853 	vim_free(buffer);
6854 	return FAIL;
6855     }
6856 
6857     /*
6858      * Isolate the individual file names.
6859      */
6860     p = buffer;
6861     for (i = 0; i < *num_file; ++i)
6862     {
6863 	(*file)[i] = p;
6864 	/* Space or NL separates */
6865 	if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
6866 					      || shell_style == STYLE_VIMGLOB)
6867 	{
6868 	    while (!(shell_style == STYLE_ECHO && *p == ' ')
6869 						   && *p != '\n' && *p != NUL)
6870 		++p;
6871 	    if (p == buffer + len)		/* last entry */
6872 		*p = NUL;
6873 	    else
6874 	    {
6875 		*p++ = NUL;
6876 		p = skipwhite(p);		/* skip to next entry */
6877 	    }
6878 	}
6879 	else		/* NUL separates */
6880 	{
6881 	    while (*p && p < buffer + len)	/* skip entry */
6882 		++p;
6883 	    ++p;				/* skip NUL */
6884 	}
6885     }
6886 
6887     /*
6888      * Move the file names to allocated memory.
6889      */
6890     for (j = 0, i = 0; i < *num_file; ++i)
6891     {
6892 	/* Require the files to exist.	Helps when using /bin/sh */
6893 	if (!(flags & EW_NOTFOUND) && mch_getperm((*file)[i]) < 0)
6894 	    continue;
6895 
6896 	/* check if this entry should be included */
6897 	dir = (mch_isdir((*file)[i]));
6898 	if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
6899 	    continue;
6900 
6901 	/* Skip files that are not executable if we check for that. */
6902 	if (!dir && (flags & EW_EXEC)
6903 		    && !mch_can_exe((*file)[i], NULL, !(flags & EW_SHELLCMD)))
6904 	    continue;
6905 
6906 	p = alloc(STRLEN((*file)[i]) + 1 + dir);
6907 	if (p)
6908 	{
6909 	    STRCPY(p, (*file)[i]);
6910 	    if (dir)
6911 		add_pathsep(p);	    /* add '/' to a directory name */
6912 	    (*file)[j++] = p;
6913 	}
6914     }
6915     vim_free(buffer);
6916     *num_file = j;
6917 
6918     if (*num_file == 0)	    /* rejected all entries */
6919     {
6920 	VIM_CLEAR(*file);
6921 	goto notfound;
6922     }
6923 
6924     return OK;
6925 
6926 notfound:
6927     if (flags & EW_NOTFOUND)
6928 	return save_patterns(num_pat, pat, num_file, file);
6929     return FAIL;
6930 }
6931 
6932 #endif /* VMS */
6933 
6934     static int
6935 save_patterns(
6936     int		num_pat,
6937     char_u	**pat,
6938     int		*num_file,
6939     char_u	***file)
6940 {
6941     int		i;
6942     char_u	*s;
6943 
6944     *file = ALLOC_MULT(char_u *, num_pat);
6945     if (*file == NULL)
6946 	return FAIL;
6947     for (i = 0; i < num_pat; i++)
6948     {
6949 	s = vim_strsave(pat[i]);
6950 	if (s != NULL)
6951 	    /* Be compatible with expand_filename(): halve the number of
6952 	     * backslashes. */
6953 	    backslash_halve(s);
6954 	(*file)[i] = s;
6955     }
6956     *num_file = num_pat;
6957     return OK;
6958 }
6959 
6960 /*
6961  * Return TRUE if the string "p" contains a wildcard that mch_expandpath() can
6962  * expand.
6963  */
6964     int
6965 mch_has_exp_wildcard(char_u *p)
6966 {
6967     for ( ; *p; MB_PTR_ADV(p))
6968     {
6969 	if (*p == '\\' && p[1] != NUL)
6970 	    ++p;
6971 	else
6972 	    if (vim_strchr((char_u *)
6973 #ifdef VMS
6974 				    "*?%"
6975 #else
6976 				    "*?[{'"
6977 #endif
6978 						, *p) != NULL)
6979 	    return TRUE;
6980     }
6981     return FALSE;
6982 }
6983 
6984 /*
6985  * Return TRUE if the string "p" contains a wildcard.
6986  * Don't recognize '~' at the end as a wildcard.
6987  */
6988     int
6989 mch_has_wildcard(char_u *p)
6990 {
6991     for ( ; *p; MB_PTR_ADV(p))
6992     {
6993 	if (*p == '\\' && p[1] != NUL)
6994 	    ++p;
6995 	else
6996 	    if (vim_strchr((char_u *)
6997 #ifdef VMS
6998 				    "*?%$"
6999 #else
7000 				    "*?[{`'$"
7001 #endif
7002 						, *p) != NULL
7003 		|| (*p == '~' && p[1] != NUL))
7004 	    return TRUE;
7005     }
7006     return FALSE;
7007 }
7008 
7009     static int
7010 have_wildcard(int num, char_u **file)
7011 {
7012     int	    i;
7013 
7014     for (i = 0; i < num; i++)
7015 	if (mch_has_wildcard(file[i]))
7016 	    return 1;
7017     return 0;
7018 }
7019 
7020     static int
7021 have_dollars(int num, char_u **file)
7022 {
7023     int	    i;
7024 
7025     for (i = 0; i < num; i++)
7026 	if (vim_strchr(file[i], '$') != NULL)
7027 	    return TRUE;
7028     return FALSE;
7029 }
7030 
7031 #if !defined(HAVE_RENAME) || defined(PROTO)
7032 /*
7033  * Scaled-down version of rename(), which is missing in Xenix.
7034  * This version can only move regular files and will fail if the
7035  * destination exists.
7036  */
7037     int
7038 mch_rename(const char *src, const char *dest)
7039 {
7040     struct stat	    st;
7041 
7042     if (stat(dest, &st) >= 0)	    /* fail if destination exists */
7043 	return -1;
7044     if (link(src, dest) != 0)	    /* link file to new name */
7045 	return -1;
7046     if (mch_remove(src) == 0)	    /* delete link to old name */
7047 	return 0;
7048     return -1;
7049 }
7050 #endif /* !HAVE_RENAME */
7051 
7052 #if defined(FEAT_MOUSE_GPM) || defined(PROTO)
7053 /*
7054  * Initializes connection with gpm (if it isn't already opened)
7055  * Return 1 if succeeded (or connection already opened), 0 if failed
7056  */
7057     static int
7058 gpm_open(void)
7059 {
7060     static Gpm_Connect gpm_connect; /* Must it be kept till closing ? */
7061 
7062     if (!gpm_flag)
7063     {
7064 	gpm_connect.eventMask = (GPM_UP | GPM_DRAG | GPM_DOWN);
7065 	gpm_connect.defaultMask = ~GPM_HARD;
7066 	/* Default handling for mouse move*/
7067 	gpm_connect.minMod = 0; /* Handle any modifier keys */
7068 	gpm_connect.maxMod = 0xffff;
7069 	if (Gpm_Open(&gpm_connect, 0) > 0)
7070 	{
7071 	    /* gpm library tries to handling TSTP causes
7072 	     * problems. Anyways, we close connection to Gpm whenever
7073 	     * we are going to suspend or starting an external process
7074 	     * so we shouldn't  have problem with this
7075 	     */
7076 # ifdef SIGTSTP
7077 	    signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
7078 # endif
7079 	    return 1; /* succeed */
7080 	}
7081 	if (gpm_fd == -2)
7082 	    Gpm_Close(); /* We don't want to talk to xterm via gpm */
7083 	return 0;
7084     }
7085     return 1; /* already open */
7086 }
7087 
7088 /*
7089  * Returns TRUE if the GPM mouse is enabled.
7090  */
7091     int
7092 gpm_enabled(void)
7093 {
7094     return gpm_flag && gpm_fd >= 0;
7095 }
7096 
7097 /*
7098  * Closes connection to gpm
7099  */
7100     static void
7101 gpm_close(void)
7102 {
7103     if (gpm_enabled())
7104 	Gpm_Close();
7105 }
7106 
7107 /*
7108  * Reads gpm event and adds special keys to input buf. Returns length of
7109  * generated key sequence.
7110  * This function is styled after gui_send_mouse_event().
7111  */
7112     static int
7113 mch_gpm_process(void)
7114 {
7115     int			button;
7116     static Gpm_Event	gpm_event;
7117     char_u		string[6];
7118     int_u		vim_modifiers;
7119     int			row,col;
7120     unsigned char	buttons_mask;
7121     unsigned char	gpm_modifiers;
7122     static unsigned char old_buttons = 0;
7123 
7124     Gpm_GetEvent(&gpm_event);
7125 
7126 #ifdef FEAT_GUI
7127     /* Don't put events in the input queue now. */
7128     if (hold_gui_events)
7129 	return 0;
7130 #endif
7131 
7132     row = gpm_event.y - 1;
7133     col = gpm_event.x - 1;
7134 
7135     string[0] = ESC; /* Our termcode */
7136     string[1] = 'M';
7137     string[2] = 'G';
7138     switch (GPM_BARE_EVENTS(gpm_event.type))
7139     {
7140 	case GPM_DRAG:
7141 	    string[3] = MOUSE_DRAG;
7142 	    break;
7143 	case GPM_DOWN:
7144 	    buttons_mask = gpm_event.buttons & ~old_buttons;
7145 	    old_buttons = gpm_event.buttons;
7146 	    switch (buttons_mask)
7147 	    {
7148 		case GPM_B_LEFT:
7149 		    button = MOUSE_LEFT;
7150 		    break;
7151 		case GPM_B_MIDDLE:
7152 		    button = MOUSE_MIDDLE;
7153 		    break;
7154 		case GPM_B_RIGHT:
7155 		    button = MOUSE_RIGHT;
7156 		    break;
7157 		default:
7158 		    return 0;
7159 		    /*Don't know what to do. Can more than one button be
7160 		     * reported in one event? */
7161 	    }
7162 	    string[3] = (char_u)(button | 0x20);
7163 	    SET_NUM_MOUSE_CLICKS(string[3], gpm_event.clicks + 1);
7164 	    break;
7165 	case GPM_UP:
7166 	    string[3] = MOUSE_RELEASE;
7167 	    old_buttons &= ~gpm_event.buttons;
7168 	    break;
7169 	default:
7170 	    return 0;
7171     }
7172     /*This code is based on gui_x11_mouse_cb in gui_x11.c */
7173     gpm_modifiers = gpm_event.modifiers;
7174     vim_modifiers = 0x0;
7175     /* I ignore capslock stats. Aren't we all just hate capslock mixing with
7176      * Vim commands ? Besides, gpm_event.modifiers is unsigned char, and
7177      * K_CAPSSHIFT is defined 8, so it probably isn't even reported
7178      */
7179     if (gpm_modifiers & ((1 << KG_SHIFT) | (1 << KG_SHIFTR) | (1 << KG_SHIFTL)))
7180 	vim_modifiers |= MOUSE_SHIFT;
7181 
7182     if (gpm_modifiers & ((1 << KG_CTRL) | (1 << KG_CTRLR) | (1 << KG_CTRLL)))
7183 	vim_modifiers |= MOUSE_CTRL;
7184     if (gpm_modifiers & ((1 << KG_ALT) | (1 << KG_ALTGR)))
7185 	vim_modifiers |= MOUSE_ALT;
7186     string[3] |= vim_modifiers;
7187     string[4] = (char_u)(col + ' ' + 1);
7188     string[5] = (char_u)(row + ' ' + 1);
7189     add_to_input_buf(string, 6);
7190     return 6;
7191 }
7192 #endif /* FEAT_MOUSE_GPM */
7193 
7194 #ifdef FEAT_SYSMOUSE
7195 /*
7196  * Initialize connection with sysmouse.
7197  * Let virtual console inform us with SIGUSR2 for pending sysmouse
7198  * output, any sysmouse output than will be processed via sig_sysmouse().
7199  * Return OK if succeeded, FAIL if failed.
7200  */
7201     static int
7202 sysmouse_open(void)
7203 {
7204     struct mouse_info   mouse;
7205 
7206     mouse.operation = MOUSE_MODE;
7207     mouse.u.mode.mode = 0;
7208     mouse.u.mode.signal = SIGUSR2;
7209     if (ioctl(1, CONS_MOUSECTL, &mouse) != -1)
7210     {
7211 	signal(SIGUSR2, (RETSIGTYPE (*)())sig_sysmouse);
7212 	mouse.operation = MOUSE_SHOW;
7213 	ioctl(1, CONS_MOUSECTL, &mouse);
7214 	return OK;
7215     }
7216     return FAIL;
7217 }
7218 
7219 /*
7220  * Stop processing SIGUSR2 signals, and also make sure that
7221  * virtual console do not send us any sysmouse related signal.
7222  */
7223     static void
7224 sysmouse_close(void)
7225 {
7226     struct mouse_info	mouse;
7227 
7228     signal(SIGUSR2, restricted ? SIG_IGN : SIG_DFL);
7229     mouse.operation = MOUSE_MODE;
7230     mouse.u.mode.mode = 0;
7231     mouse.u.mode.signal = 0;
7232     ioctl(1, CONS_MOUSECTL, &mouse);
7233 }
7234 
7235 /*
7236  * Gets info from sysmouse and adds special keys to input buf.
7237  */
7238     static RETSIGTYPE
7239 sig_sysmouse SIGDEFARG(sigarg)
7240 {
7241     struct mouse_info	mouse;
7242     struct video_info	video;
7243     char_u		string[6];
7244     int			row, col;
7245     int			button;
7246     int			buttons;
7247     static int		oldbuttons = 0;
7248 
7249 #ifdef FEAT_GUI
7250     /* Don't put events in the input queue now. */
7251     if (hold_gui_events)
7252 	return;
7253 #endif
7254 
7255     mouse.operation = MOUSE_GETINFO;
7256     if (ioctl(1, FBIO_GETMODE, &video.vi_mode) != -1
7257 	    && ioctl(1, FBIO_MODEINFO, &video) != -1
7258 	    && ioctl(1, CONS_MOUSECTL, &mouse) != -1
7259 	    && video.vi_cheight > 0 && video.vi_cwidth > 0)
7260     {
7261 	row = mouse.u.data.y / video.vi_cheight;
7262 	col = mouse.u.data.x / video.vi_cwidth;
7263 	buttons = mouse.u.data.buttons;
7264 	string[0] = ESC; /* Our termcode */
7265 	string[1] = 'M';
7266 	string[2] = 'S';
7267 	if (oldbuttons == buttons && buttons != 0)
7268 	{
7269 	    button = MOUSE_DRAG;
7270 	}
7271 	else
7272 	{
7273 	    switch (buttons)
7274 	    {
7275 		case 0:
7276 		    button = MOUSE_RELEASE;
7277 		    break;
7278 		case 1:
7279 		    button = MOUSE_LEFT;
7280 		    break;
7281 		case 2:
7282 		    button = MOUSE_MIDDLE;
7283 		    break;
7284 		case 4:
7285 		    button = MOUSE_RIGHT;
7286 		    break;
7287 		default:
7288 		    return;
7289 	    }
7290 	    oldbuttons = buttons;
7291 	}
7292 	string[3] = (char_u)(button);
7293 	string[4] = (char_u)(col + ' ' + 1);
7294 	string[5] = (char_u)(row + ' ' + 1);
7295 	add_to_input_buf(string, 6);
7296     }
7297     return;
7298 }
7299 #endif /* FEAT_SYSMOUSE */
7300 
7301 #if defined(FEAT_LIBCALL) || defined(PROTO)
7302 typedef char_u * (*STRPROCSTR)(char_u *);
7303 typedef char_u * (*INTPROCSTR)(int);
7304 typedef int (*STRPROCINT)(char_u *);
7305 typedef int (*INTPROCINT)(int);
7306 
7307 /*
7308  * Call a DLL routine which takes either a string or int param
7309  * and returns an allocated string.
7310  */
7311     int
7312 mch_libcall(
7313     char_u	*libname,
7314     char_u	*funcname,
7315     char_u	*argstring,	/* NULL when using a argint */
7316     int		argint,
7317     char_u	**string_result,/* NULL when using number_result */
7318     int		*number_result)
7319 {
7320 # if defined(USE_DLOPEN)
7321     void	*hinstLib;
7322     char	*dlerr = NULL;
7323 # else
7324     shl_t	hinstLib;
7325 # endif
7326     STRPROCSTR	ProcAdd;
7327     INTPROCSTR	ProcAddI;
7328     char_u	*retval_str = NULL;
7329     int		retval_int = 0;
7330     int		success = FALSE;
7331 
7332     /*
7333      * Get a handle to the DLL module.
7334      */
7335 # if defined(USE_DLOPEN)
7336     /* First clear any error, it's not cleared by the dlopen() call. */
7337     (void)dlerror();
7338 
7339     hinstLib = dlopen((char *)libname, RTLD_LAZY
7340 #  ifdef RTLD_LOCAL
7341 	    | RTLD_LOCAL
7342 #  endif
7343 	    );
7344     if (hinstLib == NULL)
7345     {
7346 	/* "dlerr" must be used before dlclose() */
7347 	dlerr = (char *)dlerror();
7348 	if (dlerr != NULL)
7349 	    semsg(_("dlerror = \"%s\""), dlerr);
7350     }
7351 # else
7352     hinstLib = shl_load((const char*)libname, BIND_IMMEDIATE|BIND_VERBOSE, 0L);
7353 # endif
7354 
7355     /* If the handle is valid, try to get the function address. */
7356     if (hinstLib != NULL)
7357     {
7358 # ifdef USING_SETJMP
7359 	/*
7360 	 * Catch a crash when calling the library function.  For example when
7361 	 * using a number where a string pointer is expected.
7362 	 */
7363 	mch_startjmp();
7364 	if (SETJMP(lc_jump_env) != 0)
7365 	{
7366 	    success = FALSE;
7367 #  if defined(USE_DLOPEN)
7368 	    dlerr = NULL;
7369 #  endif
7370 	    mch_didjmp();
7371 	}
7372 	else
7373 # endif
7374 	{
7375 	    retval_str = NULL;
7376 	    retval_int = 0;
7377 
7378 	    if (argstring != NULL)
7379 	    {
7380 # if defined(USE_DLOPEN)
7381 		*(void **)(&ProcAdd) = dlsym(hinstLib, (const char *)funcname);
7382 		dlerr = (char *)dlerror();
7383 # else
7384 		if (shl_findsym(&hinstLib, (const char *)funcname,
7385 					TYPE_PROCEDURE, (void *)&ProcAdd) < 0)
7386 		    ProcAdd = NULL;
7387 # endif
7388 		if ((success = (ProcAdd != NULL
7389 # if defined(USE_DLOPEN)
7390 			    && dlerr == NULL
7391 # endif
7392 			    )))
7393 		{
7394 		    if (string_result == NULL)
7395 			retval_int = ((STRPROCINT)ProcAdd)(argstring);
7396 		    else
7397 			retval_str = (ProcAdd)(argstring);
7398 		}
7399 	    }
7400 	    else
7401 	    {
7402 # if defined(USE_DLOPEN)
7403 		*(void **)(&ProcAddI) = dlsym(hinstLib, (const char *)funcname);
7404 		dlerr = (char *)dlerror();
7405 # else
7406 		if (shl_findsym(&hinstLib, (const char *)funcname,
7407 				       TYPE_PROCEDURE, (void *)&ProcAddI) < 0)
7408 		    ProcAddI = NULL;
7409 # endif
7410 		if ((success = (ProcAddI != NULL
7411 # if defined(USE_DLOPEN)
7412 			    && dlerr == NULL
7413 # endif
7414 			    )))
7415 		{
7416 		    if (string_result == NULL)
7417 			retval_int = ((INTPROCINT)ProcAddI)(argint);
7418 		    else
7419 			retval_str = (ProcAddI)(argint);
7420 		}
7421 	    }
7422 
7423 	    /* Save the string before we free the library. */
7424 	    /* Assume that a "1" or "-1" result is an illegal pointer. */
7425 	    if (string_result == NULL)
7426 		*number_result = retval_int;
7427 	    else if (retval_str != NULL
7428 		    && retval_str != (char_u *)1
7429 		    && retval_str != (char_u *)-1)
7430 		*string_result = vim_strsave(retval_str);
7431 	}
7432 
7433 # ifdef USING_SETJMP
7434 	mch_endjmp();
7435 #  ifdef SIGHASARG
7436 	if (lc_signal != 0)
7437 	{
7438 	    int i;
7439 
7440 	    /* try to find the name of this signal */
7441 	    for (i = 0; signal_info[i].sig != -1; i++)
7442 		if (lc_signal == signal_info[i].sig)
7443 		    break;
7444 	    semsg("E368: got SIG%s in libcall()", signal_info[i].name);
7445 	}
7446 #  endif
7447 # endif
7448 
7449 # if defined(USE_DLOPEN)
7450 	/* "dlerr" must be used before dlclose() */
7451 	if (dlerr != NULL)
7452 	    semsg(_("dlerror = \"%s\""), dlerr);
7453 
7454 	/* Free the DLL module. */
7455 	(void)dlclose(hinstLib);
7456 # else
7457 	(void)shl_unload(hinstLib);
7458 # endif
7459     }
7460 
7461     if (!success)
7462     {
7463 	semsg(_(e_libcall), funcname);
7464 	return FAIL;
7465     }
7466 
7467     return OK;
7468 }
7469 #endif
7470 
7471 #if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) || defined(PROTO)
7472 static int	xterm_trace = -1;	/* default: disabled */
7473 static int	xterm_button;
7474 
7475 /*
7476  * Setup a dummy window for X selections in a terminal.
7477  */
7478     void
7479 setup_term_clip(void)
7480 {
7481     int		z = 0;
7482     char	*strp = "";
7483     Widget	AppShell;
7484 
7485     if (!x_connect_to_server())
7486 	return;
7487 
7488     open_app_context();
7489     if (app_context != NULL && xterm_Shell == (Widget)0)
7490     {
7491 	int (*oldhandler)();
7492 # if defined(USING_SETJMP)
7493 	int (*oldIOhandler)();
7494 # endif
7495 # ifdef ELAPSED_FUNC
7496 	elapsed_T start_tv;
7497 
7498 	if (p_verbose > 0)
7499 	    ELAPSED_INIT(start_tv);
7500 # endif
7501 
7502 	/* Ignore X errors while opening the display */
7503 	oldhandler = XSetErrorHandler(x_error_check);
7504 
7505 # if defined(USING_SETJMP)
7506 	/* Ignore X IO errors while opening the display */
7507 	oldIOhandler = XSetIOErrorHandler(x_IOerror_check);
7508 	mch_startjmp();
7509 	if (SETJMP(lc_jump_env) != 0)
7510 	{
7511 	    mch_didjmp();
7512 	    xterm_dpy = NULL;
7513 	}
7514 	else
7515 # endif
7516 	{
7517 	    xterm_dpy = XtOpenDisplay(app_context, xterm_display,
7518 		    "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
7519 	    if (xterm_dpy != NULL)
7520 		xterm_dpy_retry_count = 0;
7521 # if defined(USING_SETJMP)
7522 	    mch_endjmp();
7523 # endif
7524 	}
7525 
7526 # if defined(USING_SETJMP)
7527 	/* Now handle X IO errors normally. */
7528 	(void)XSetIOErrorHandler(oldIOhandler);
7529 # endif
7530 	/* Now handle X errors normally. */
7531 	(void)XSetErrorHandler(oldhandler);
7532 
7533 	if (xterm_dpy == NULL)
7534 	{
7535 	    if (p_verbose > 0)
7536 		verb_msg(_("Opening the X display failed"));
7537 	    return;
7538 	}
7539 
7540 	/* Catch terminating error of the X server connection. */
7541 	(void)XSetIOErrorHandler(x_IOerror_handler);
7542 
7543 # ifdef ELAPSED_FUNC
7544 	if (p_verbose > 0)
7545 	{
7546 	    verbose_enter();
7547 	    xopen_message(ELAPSED_FUNC(start_tv));
7548 	    verbose_leave();
7549 	}
7550 # endif
7551 
7552 	/* Create a Shell to make converters work. */
7553 	AppShell = XtVaAppCreateShell("vim_xterm", "Vim_xterm",
7554 		applicationShellWidgetClass, xterm_dpy,
7555 		NULL);
7556 	if (AppShell == (Widget)0)
7557 	    return;
7558 	xterm_Shell = XtVaCreatePopupShell("VIM",
7559 		topLevelShellWidgetClass, AppShell,
7560 		XtNmappedWhenManaged, 0,
7561 		XtNwidth, 1,
7562 		XtNheight, 1,
7563 		NULL);
7564 	if (xterm_Shell == (Widget)0)
7565 	    return;
7566 
7567 	x11_setup_atoms(xterm_dpy);
7568 	x11_setup_selection(xterm_Shell);
7569 	if (x11_display == NULL)
7570 	    x11_display = xterm_dpy;
7571 
7572 	XtRealizeWidget(xterm_Shell);
7573 	XSync(xterm_dpy, False);
7574 	xterm_update();
7575     }
7576     if (xterm_Shell != (Widget)0)
7577     {
7578 	clip_init(TRUE);
7579 	if (x11_window == 0 && (strp = getenv("WINDOWID")) != NULL)
7580 	    x11_window = (Window)atol(strp);
7581 	/* Check if $WINDOWID is valid. */
7582 	if (test_x11_window(xterm_dpy) == FAIL)
7583 	    x11_window = 0;
7584 	if (x11_window != 0)
7585 	    xterm_trace = 0;
7586     }
7587 }
7588 
7589     void
7590 start_xterm_trace(int button)
7591 {
7592     if (x11_window == 0 || xterm_trace < 0 || xterm_Shell == (Widget)0)
7593 	return;
7594     xterm_trace = 1;
7595     xterm_button = button;
7596     do_xterm_trace();
7597 }
7598 
7599 
7600     void
7601 stop_xterm_trace(void)
7602 {
7603     if (xterm_trace < 0)
7604 	return;
7605     xterm_trace = 0;
7606 }
7607 
7608 /*
7609  * Query the xterm pointer and generate mouse termcodes if necessary
7610  * return TRUE if dragging is active, else FALSE
7611  */
7612     static int
7613 do_xterm_trace(void)
7614 {
7615     Window		root, child;
7616     int			root_x, root_y;
7617     int			win_x, win_y;
7618     int			row, col;
7619     int_u		mask_return;
7620     char_u		buf[50];
7621     char_u		*strp;
7622     long		got_hints;
7623     static char_u	*mouse_code;
7624     static char_u	mouse_name[2] = {KS_MOUSE, KE_FILLER};
7625     static int		prev_row = 0, prev_col = 0;
7626     static XSizeHints	xterm_hints;
7627 
7628     if (xterm_trace <= 0)
7629 	return FALSE;
7630 
7631     if (xterm_trace == 1)
7632     {
7633 	/* Get the hints just before tracking starts.  The font size might
7634 	 * have changed recently. */
7635 	if (!XGetWMNormalHints(xterm_dpy, x11_window, &xterm_hints, &got_hints)
7636 		|| !(got_hints & PResizeInc)
7637 		|| xterm_hints.width_inc <= 1
7638 		|| xterm_hints.height_inc <= 1)
7639 	{
7640 	    xterm_trace = -1;  /* Not enough data -- disable tracing */
7641 	    return FALSE;
7642 	}
7643 
7644 	/* Rely on the same mouse code for the duration of this */
7645 	mouse_code = find_termcode(mouse_name);
7646 	prev_row = mouse_row;
7647 	prev_col = mouse_col;
7648 	xterm_trace = 2;
7649 
7650 	/* Find the offset of the chars, there might be a scrollbar on the
7651 	 * left of the window and/or a menu on the top (eterm etc.) */
7652 	XQueryPointer(xterm_dpy, x11_window, &root, &child, &root_x, &root_y,
7653 		      &win_x, &win_y, &mask_return);
7654 	xterm_hints.y = win_y - (xterm_hints.height_inc * mouse_row)
7655 			      - (xterm_hints.height_inc / 2);
7656 	if (xterm_hints.y <= xterm_hints.height_inc / 2)
7657 	    xterm_hints.y = 2;
7658 	xterm_hints.x = win_x - (xterm_hints.width_inc * mouse_col)
7659 			      - (xterm_hints.width_inc / 2);
7660 	if (xterm_hints.x <= xterm_hints.width_inc / 2)
7661 	    xterm_hints.x = 2;
7662 	return TRUE;
7663     }
7664     if (mouse_code == NULL || STRLEN(mouse_code) > 45)
7665     {
7666 	xterm_trace = 0;
7667 	return FALSE;
7668     }
7669 
7670     XQueryPointer(xterm_dpy, x11_window, &root, &child, &root_x, &root_y,
7671 		  &win_x, &win_y, &mask_return);
7672 
7673     row = check_row((win_y - xterm_hints.y) / xterm_hints.height_inc);
7674     col = check_col((win_x - xterm_hints.x) / xterm_hints.width_inc);
7675     if (row == prev_row && col == prev_col)
7676 	return TRUE;
7677 
7678     STRCPY(buf, mouse_code);
7679     strp = buf + STRLEN(buf);
7680     *strp++ = (xterm_button | MOUSE_DRAG) & ~0x20;
7681     *strp++ = (char_u)(col + ' ' + 1);
7682     *strp++ = (char_u)(row + ' ' + 1);
7683     *strp = 0;
7684     add_to_input_buf(buf, STRLEN(buf));
7685 
7686     prev_row = row;
7687     prev_col = col;
7688     return TRUE;
7689 }
7690 
7691 # if defined(FEAT_GUI) || defined(FEAT_XCLIPBOARD) || defined(PROTO)
7692 /*
7693  * Destroy the display, window and app_context.  Required for GTK.
7694  */
7695     void
7696 clear_xterm_clip(void)
7697 {
7698     if (xterm_Shell != (Widget)0)
7699     {
7700 	XtDestroyWidget(xterm_Shell);
7701 	xterm_Shell = (Widget)0;
7702     }
7703     if (xterm_dpy != NULL)
7704     {
7705 #  if 0
7706 	/* Lesstif and Solaris crash here, lose some memory */
7707 	XtCloseDisplay(xterm_dpy);
7708 #  endif
7709 	if (x11_display == xterm_dpy)
7710 	    x11_display = NULL;
7711 	xterm_dpy = NULL;
7712     }
7713 #  if 0
7714     if (app_context != (XtAppContext)NULL)
7715     {
7716 	/* Lesstif and Solaris crash here, lose some memory */
7717 	XtDestroyApplicationContext(app_context);
7718 	app_context = (XtAppContext)NULL;
7719     }
7720 #  endif
7721 }
7722 # endif
7723 
7724 /*
7725  * Catch up with GUI or X events.
7726  */
7727     static void
7728 clip_update(void)
7729 {
7730 # ifdef FEAT_GUI
7731     if (gui.in_use)
7732 	gui_mch_update();
7733     else
7734 # endif
7735     if (xterm_Shell != (Widget)0)
7736 	xterm_update();
7737 }
7738 
7739 /*
7740  * Catch up with any queued X events.  This may put keyboard input into the
7741  * input buffer, call resize call-backs, trigger timers etc.  If there is
7742  * nothing in the X event queue (& no timers pending), then we return
7743  * immediately.
7744  */
7745     static void
7746 xterm_update(void)
7747 {
7748     XEvent event;
7749 
7750     for (;;)
7751     {
7752 	XtInputMask mask = XtAppPending(app_context);
7753 
7754 	if (mask == 0 || vim_is_input_buf_full())
7755 	    break;
7756 
7757 	if (mask & XtIMXEvent)
7758 	{
7759 	    /* There is an event to process. */
7760 	    XtAppNextEvent(app_context, &event);
7761 #ifdef FEAT_CLIENTSERVER
7762 	    {
7763 		XPropertyEvent *e = (XPropertyEvent *)&event;
7764 
7765 		if (e->type == PropertyNotify && e->window == commWindow
7766 		   && e->atom == commProperty && e->state == PropertyNewValue)
7767 		    serverEventProc(xterm_dpy, &event, 0);
7768 	    }
7769 #endif
7770 	    XtDispatchEvent(&event);
7771 	}
7772 	else
7773 	{
7774 	    /* There is something else than an event to process. */
7775 	    XtAppProcessEvent(app_context, mask);
7776 	}
7777     }
7778 }
7779 
7780     int
7781 clip_xterm_own_selection(Clipboard_T *cbd)
7782 {
7783     if (xterm_Shell != (Widget)0)
7784 	return clip_x11_own_selection(xterm_Shell, cbd);
7785     return FAIL;
7786 }
7787 
7788     void
7789 clip_xterm_lose_selection(Clipboard_T *cbd)
7790 {
7791     if (xterm_Shell != (Widget)0)
7792 	clip_x11_lose_selection(xterm_Shell, cbd);
7793 }
7794 
7795     void
7796 clip_xterm_request_selection(Clipboard_T *cbd)
7797 {
7798     if (xterm_Shell != (Widget)0)
7799 	clip_x11_request_selection(xterm_Shell, xterm_dpy, cbd);
7800 }
7801 
7802     void
7803 clip_xterm_set_selection(Clipboard_T *cbd)
7804 {
7805     clip_x11_set_selection(cbd);
7806 }
7807 #endif
7808 
7809 
7810 #if defined(USE_XSMP) || defined(PROTO)
7811 /*
7812  * Code for X Session Management Protocol.
7813  */
7814 
7815 # if defined(FEAT_GUI) && defined(USE_XSMP_INTERACT)
7816 /*
7817  * This is our chance to ask the user if they want to save,
7818  * or abort the logout
7819  */
7820     static void
7821 xsmp_handle_interaction(SmcConn smc_conn, SmPointer client_data UNUSED)
7822 {
7823     cmdmod_T	save_cmdmod;
7824     int		cancel_shutdown = False;
7825 
7826     save_cmdmod = cmdmod;
7827     cmdmod.confirm = TRUE;
7828     if (check_changed_any(FALSE, FALSE))
7829 	/* Mustn't logout */
7830 	cancel_shutdown = True;
7831     cmdmod = save_cmdmod;
7832     setcursor();		/* position cursor */
7833     out_flush();
7834 
7835     /* Done interaction */
7836     SmcInteractDone(smc_conn, cancel_shutdown);
7837 
7838     /* Finish off
7839      * Only end save-yourself here if we're not cancelling shutdown;
7840      * we'll get a cancelled callback later in which we'll end it.
7841      * Hopefully get around glitchy SMs (like GNOME-1)
7842      */
7843     if (!cancel_shutdown)
7844     {
7845 	xsmp.save_yourself = False;
7846 	SmcSaveYourselfDone(smc_conn, True);
7847     }
7848 }
7849 # endif
7850 
7851 /*
7852  * Callback that starts save-yourself.
7853  */
7854     static void
7855 xsmp_handle_save_yourself(
7856     SmcConn	smc_conn,
7857     SmPointer	client_data UNUSED,
7858     int		save_type UNUSED,
7859     Bool	shutdown,
7860     int		interact_style UNUSED,
7861     Bool	fast UNUSED)
7862 {
7863     /* Handle already being in saveyourself */
7864     if (xsmp.save_yourself)
7865 	SmcSaveYourselfDone(smc_conn, True);
7866     xsmp.save_yourself = True;
7867     xsmp.shutdown = shutdown;
7868 
7869     /* First up, preserve all files */
7870     out_flush();
7871     ml_sync_all(FALSE, FALSE);	/* preserve all swap files */
7872 
7873     if (p_verbose > 0)
7874 	verb_msg(_("XSMP handling save-yourself request"));
7875 
7876 # if defined(FEAT_GUI) && defined(USE_XSMP_INTERACT)
7877     /* Now see if we can ask about unsaved files */
7878     if (shutdown && !fast && gui.in_use)
7879 	/* Need to interact with user, but need SM's permission */
7880 	SmcInteractRequest(smc_conn, SmDialogError,
7881 					xsmp_handle_interaction, client_data);
7882     else
7883 # endif
7884     {
7885 	/* Can stop the cycle here */
7886 	SmcSaveYourselfDone(smc_conn, True);
7887 	xsmp.save_yourself = False;
7888     }
7889 }
7890 
7891 
7892 /*
7893  * Callback to warn us of imminent death.
7894  */
7895     static void
7896 xsmp_die(SmcConn smc_conn UNUSED, SmPointer client_data UNUSED)
7897 {
7898     xsmp_close();
7899 
7900     /* quit quickly leaving swapfiles for modified buffers behind */
7901     getout_preserve_modified(0);
7902 }
7903 
7904 
7905 /*
7906  * Callback to tell us that save-yourself has completed.
7907  */
7908     static void
7909 xsmp_save_complete(
7910     SmcConn	smc_conn UNUSED,
7911     SmPointer	client_data UNUSED)
7912 {
7913     xsmp.save_yourself = False;
7914 }
7915 
7916 
7917 /*
7918  * Callback to tell us that an instigated shutdown was cancelled
7919  * (maybe even by us)
7920  */
7921     static void
7922 xsmp_shutdown_cancelled(
7923     SmcConn	smc_conn,
7924     SmPointer	client_data UNUSED)
7925 {
7926     if (xsmp.save_yourself)
7927 	SmcSaveYourselfDone(smc_conn, True);
7928     xsmp.save_yourself = False;
7929     xsmp.shutdown = False;
7930 }
7931 
7932 
7933 /*
7934  * Callback to tell us that a new ICE connection has been established.
7935  */
7936     static void
7937 xsmp_ice_connection(
7938     IceConn	iceConn,
7939     IcePointer	clientData UNUSED,
7940     Bool	opening,
7941     IcePointer	*watchData UNUSED)
7942 {
7943     /* Intercept creation of ICE connection fd */
7944     if (opening)
7945     {
7946 	xsmp_icefd = IceConnectionNumber(iceConn);
7947 	IceRemoveConnectionWatch(xsmp_ice_connection, NULL);
7948     }
7949 }
7950 
7951 
7952 /* Handle any ICE processing that's required; return FAIL if SM lost */
7953     int
7954 xsmp_handle_requests(void)
7955 {
7956     Bool rep;
7957 
7958     if (IceProcessMessages(xsmp.iceconn, NULL, &rep)
7959 						 == IceProcessMessagesIOError)
7960     {
7961 	/* Lost ICE */
7962 	if (p_verbose > 0)
7963 	    verb_msg(_("XSMP lost ICE connection"));
7964 	xsmp_close();
7965 	return FAIL;
7966     }
7967     else
7968 	return OK;
7969 }
7970 
7971 static int dummy;
7972 
7973 /* Set up X Session Management Protocol */
7974     void
7975 xsmp_init(void)
7976 {
7977     char		errorstring[80];
7978     SmcCallbacks	smcallbacks;
7979 #if 0
7980     SmPropValue		smname;
7981     SmProp		smnameprop;
7982     SmProp		*smprops[1];
7983 #endif
7984 
7985     if (p_verbose > 0)
7986 	verb_msg(_("XSMP opening connection"));
7987 
7988     xsmp.save_yourself = xsmp.shutdown = False;
7989 
7990     /* Set up SM callbacks - must have all, even if they're not used */
7991     smcallbacks.save_yourself.callback = xsmp_handle_save_yourself;
7992     smcallbacks.save_yourself.client_data = NULL;
7993     smcallbacks.die.callback = xsmp_die;
7994     smcallbacks.die.client_data = NULL;
7995     smcallbacks.save_complete.callback = xsmp_save_complete;
7996     smcallbacks.save_complete.client_data = NULL;
7997     smcallbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
7998     smcallbacks.shutdown_cancelled.client_data = NULL;
7999 
8000     /* Set up a watch on ICE connection creations.  The "dummy" argument is
8001      * apparently required for FreeBSD (we get a BUS error when using NULL). */
8002     if (IceAddConnectionWatch(xsmp_ice_connection, &dummy) == 0)
8003     {
8004 	if (p_verbose > 0)
8005 	    verb_msg(_("XSMP ICE connection watch failed"));
8006 	return;
8007     }
8008 
8009     /* Create an SM connection */
8010     xsmp.smcconn = SmcOpenConnection(
8011 	    NULL,
8012 	    NULL,
8013 	    SmProtoMajor,
8014 	    SmProtoMinor,
8015 	    SmcSaveYourselfProcMask | SmcDieProcMask
8016 		     | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
8017 	    &smcallbacks,
8018 	    NULL,
8019 	    &xsmp.clientid,
8020 	    sizeof(errorstring) - 1,
8021 	    errorstring);
8022     if (xsmp.smcconn == NULL)
8023     {
8024 	char errorreport[132];
8025 
8026 	if (p_verbose > 0)
8027 	{
8028 	    vim_snprintf(errorreport, sizeof(errorreport),
8029 			 _("XSMP SmcOpenConnection failed: %s"), errorstring);
8030 	    verb_msg(errorreport);
8031 	}
8032 	return;
8033     }
8034     xsmp.iceconn = SmcGetIceConnection(xsmp.smcconn);
8035 
8036 #if 0
8037     /* ID ourselves */
8038     smname.value = "vim";
8039     smname.length = 3;
8040     smnameprop.name = "SmProgram";
8041     smnameprop.type = "SmARRAY8";
8042     smnameprop.num_vals = 1;
8043     smnameprop.vals = &smname;
8044 
8045     smprops[0] = &smnameprop;
8046     SmcSetProperties(xsmp.smcconn, 1, smprops);
8047 #endif
8048 }
8049 
8050 
8051 /* Shut down XSMP comms. */
8052     void
8053 xsmp_close(void)
8054 {
8055     if (xsmp_icefd != -1)
8056     {
8057 	SmcCloseConnection(xsmp.smcconn, 0, NULL);
8058 	if (xsmp.clientid != NULL)
8059 	    free(xsmp.clientid);
8060 	xsmp.clientid = NULL;
8061 	xsmp_icefd = -1;
8062     }
8063 }
8064 #endif /* USE_XSMP */
8065 
8066 
8067 #ifdef EBCDIC
8068 /* Translate character to its CTRL- value */
8069 char CtrlTable[] =
8070 {
8071 /* 00 - 5E */
8072 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8073 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8074 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8075 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8076 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8077 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8078 /* ^ */ 0x1E,
8079 /* - */ 0x1F,
8080 /* 61 - 6C */
8081 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8082 /* _ */ 0x1F,
8083 /* 6E - 80 */
8084 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8085 /* a */ 0x01,
8086 /* b */ 0x02,
8087 /* c */ 0x03,
8088 /* d */ 0x37,
8089 /* e */ 0x2D,
8090 /* f */ 0x2E,
8091 /* g */ 0x2F,
8092 /* h */ 0x16,
8093 /* i */ 0x05,
8094 /* 8A - 90 */
8095 	0, 0, 0, 0, 0, 0, 0,
8096 /* j */ 0x15,
8097 /* k */ 0x0B,
8098 /* l */ 0x0C,
8099 /* m */ 0x0D,
8100 /* n */ 0x0E,
8101 /* o */ 0x0F,
8102 /* p */ 0x10,
8103 /* q */ 0x11,
8104 /* r */ 0x12,
8105 /* 9A - A1 */
8106 	0, 0, 0, 0, 0, 0, 0, 0,
8107 /* s */ 0x13,
8108 /* t */ 0x3C,
8109 /* u */ 0x3D,
8110 /* v */ 0x32,
8111 /* w */ 0x26,
8112 /* x */ 0x18,
8113 /* y */ 0x19,
8114 /* z */ 0x3F,
8115 /* AA - AC */
8116 	0, 0, 0,
8117 /* [ */ 0x27,
8118 /* AE - BC */
8119 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8120 /* ] */ 0x1D,
8121 /* BE - C0 */ 0, 0, 0,
8122 /* A */ 0x01,
8123 /* B */ 0x02,
8124 /* C */ 0x03,
8125 /* D */ 0x37,
8126 /* E */ 0x2D,
8127 /* F */ 0x2E,
8128 /* G */ 0x2F,
8129 /* H */ 0x16,
8130 /* I */ 0x05,
8131 /* CA - D0 */ 0, 0, 0, 0, 0, 0, 0,
8132 /* J */ 0x15,
8133 /* K */ 0x0B,
8134 /* L */ 0x0C,
8135 /* M */ 0x0D,
8136 /* N */ 0x0E,
8137 /* O */ 0x0F,
8138 /* P */ 0x10,
8139 /* Q */ 0x11,
8140 /* R */ 0x12,
8141 /* DA - DF */ 0, 0, 0, 0, 0, 0,
8142 /* \ */ 0x1C,
8143 /* E1 */ 0,
8144 /* S */ 0x13,
8145 /* T */ 0x3C,
8146 /* U */ 0x3D,
8147 /* V */ 0x32,
8148 /* W */ 0x26,
8149 /* X */ 0x18,
8150 /* Y */ 0x19,
8151 /* Z */ 0x3F,
8152 /* EA - FF*/ 0, 0, 0, 0, 0, 0,
8153 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8154 };
8155 
8156 char MetaCharTable[]=
8157 {/*   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
8158       0,  0,  0,  0,'\\', 0,'F',  0,'W','M','N',  0,  0,  0,  0,  0,
8159       0,  0,  0,  0,']',  0,  0,'G',  0,  0,'R','O',  0,  0,  0,  0,
8160     '@','A','B','C','D','E',  0,  0,'H','I','J','K','L',  0,  0,  0,
8161     'P','Q',  0,'S','T','U','V',  0,'X','Y','Z','[',  0,  0,'^',  0
8162 };
8163 
8164 
8165 /* TODO: Use characters NOT numbers!!! */
8166 char CtrlCharTable[]=
8167 {/*   0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F */
8168     124,193,194,195,  0,201,  0,  0,  0,  0,  0,210,211,212,213,214,
8169     215,216,217,226,  0,209,200,  0,231,232,  0,  0,224,189, 95,109,
8170       0,  0,  0,  0,  0,  0,230,173,  0,  0,  0,  0,  0,197,198,199,
8171       0,  0,229,  0,  0,  0,  0,196,  0,  0,  0,  0,227,228,  0,233,
8172 };
8173 
8174 
8175 #endif
8176