1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
4 * OS/2 port by Paul Slootman
5 * VMS merge by Zoltan Arpadffy
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.
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.
17 * A lot of this file was originally written by Juergen Weigert and later
18 * changed beyond recognition.
22 * Some systems have a prototype for select() that has (int *) instead of
23 * (fd_set *), which is wrong. This define removes that prototype. We define
24 * our own prototype below.
25 * Don't use it for the Mac, it causes a warning for precompiled headers.
26 * TODO: use a configure check for precompiled headers?
28 #if !defined(__APPLE__) && !defined(__TANDEM)
29 # define select select_declared_wrong
35 # include "if_mzsch.h"
42 #include "os_unixx.h" /* unix includes for os_unix.c only */
45 # include <X11/SM/SMlib.h>
49 * Use this prototype for select, some include files have a wrong prototype
54 # define select beos_select
58 #if defined(HAVE_SELECT)
59 extern int select
__ARGS((int, fd_set
*, fd_set
*, fd_set
*, struct timeval
*));
64 /* <linux/keyboard.h> contains defines conflicting with "keymap.h",
65 * I just copied relevant defines here. A cleaner solution would be to put gpm
66 * code into separate file and include there linux/keyboard.h
68 /* #include <linux/keyboard.h> */
77 # define KG_CAPSSHIFT 8
79 static void gpm_close
__ARGS((void));
80 static int gpm_open
__ARGS((void));
81 static int mch_gpm_process
__ARGS((void));
85 * end of autoconf section. To be extended...
88 /* Are the following #ifdefs still required? And why? Is that for X11? */
90 #if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
99 #if defined(SIGWINDOW) && !defined(SIGWINCH) /* hpux 9.01 has it */
100 # define SIGWINCH SIGWINDOW
104 # include <X11/Xlib.h>
105 # include <X11/Xutil.h>
106 # include <X11/Xatom.h>
107 # ifdef FEAT_XCLIPBOARD
108 # include <X11/Intrinsic.h>
109 # include <X11/Shell.h>
110 # include <X11/StringDefs.h>
111 static Widget xterm_Shell
= (Widget
)0;
112 static void xterm_update
__ARGS((void));
115 # if defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE)
116 Window x11_window
= 0;
118 Display
*x11_display
= NULL
;
121 static int get_x11_windis
__ARGS((void));
122 static void set_x11_title
__ARGS((char_u
*));
123 static void set_x11_icon
__ARGS((char_u
*));
128 static int get_x11_title
__ARGS((int));
129 static int get_x11_icon
__ARGS((int));
131 static char_u
*oldtitle
= NULL
;
132 static int did_set_title
= FALSE
;
133 static char_u
*oldicon
= NULL
;
134 static int did_set_icon
= FALSE
;
137 static void may_core_dump
__ARGS((void));
139 static int WaitForChar
__ARGS((long));
140 #if defined(__BEOS__)
141 int RealWaitForChar
__ARGS((int, long, int *));
143 static int RealWaitForChar
__ARGS((int, long, int *));
146 #ifdef FEAT_XCLIPBOARD
147 static int do_xterm_trace
__ARGS((void));
148 # define XT_TRACE_DELAY 50 /* delay for xterm tracing */
151 static void handle_resize
__ARGS((void));
153 #if defined(SIGWINCH)
154 static RETSIGTYPE sig_winch
__ARGS(SIGPROTOARG
);
157 static RETSIGTYPE catch_sigint
__ARGS(SIGPROTOARG
);
160 static RETSIGTYPE catch_sigpwr
__ARGS(SIGPROTOARG
);
162 #if defined(SIGALRM) && defined(FEAT_X11) \
163 && defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK)
164 # define SET_SIG_ALARM
165 static RETSIGTYPE sig_alarm
__ARGS(SIGPROTOARG
);
166 static int sig_alarm_called
;
168 static RETSIGTYPE deathtrap
__ARGS(SIGPROTOARG
);
170 static void catch_int_signal
__ARGS((void));
171 static void set_signals
__ARGS((void));
172 static void catch_signals
__ARGS((RETSIGTYPE (*func_deadly
)(), RETSIGTYPE (*func_other
)()));
174 static int have_wildcard
__ARGS((int, char_u
**));
175 static int have_dollars
__ARGS((int, char_u
**));
179 static int save_patterns
__ARGS((int num_pat
, char_u
**pat
, int *num_file
, char_u
***file
));
183 # define SIG_ERR ((RETSIGTYPE (*)())-1)
186 static int do_resize
= FALSE
;
188 static char_u
*extra_shell_arg
= NULL
;
189 static int show_shell_mess
= TRUE
;
191 static int deadly_signal
= 0; /* The signal we caught */
193 static int curr_tmode
= TMODE_COOK
; /* contains current terminal mode */
198 SmcConn smcconn
; /* The SM connection ID */
199 IceConn iceconn
; /* The ICE connection ID */
200 Bool save_yourself
; /* If we're in the middle of a save_yourself */
201 Bool shutdown
; /* If we're in shutdown mode */
204 static xsmp_config_T xsmp
;
207 #ifdef SYS_SIGLIST_DECLARED
210 * extern char *_sys_siglist[NSIG];
211 * on Irix, Linux, NetBSD and Solaris. It contains a nice list of strings
212 * that describe the signals. That is nearly what we want here. But
213 * autoconf does only check for sys_siglist (without the underscore), I
214 * do not want to change everything today.... jw.
215 * This is why AC_DECL_SYS_SIGLIST is commented out in configure.in
219 static struct signalinfo
221 int sig
; /* Signal number, eg. SIGSEGV etc */
222 char *name
; /* Signal name (not char_u!). */
223 char deadly
; /* Catch as a deadly signal? */
227 {SIGHUP
, "HUP", TRUE
},
230 {SIGQUIT
, "QUIT", TRUE
},
233 {SIGILL
, "ILL", TRUE
},
236 {SIGTRAP
, "TRAP", TRUE
},
239 {SIGABRT
, "ABRT", TRUE
},
242 {SIGEMT
, "EMT", TRUE
},
245 {SIGFPE
, "FPE", TRUE
},
248 {SIGBUS
, "BUS", TRUE
},
251 {SIGSEGV
, "SEGV", TRUE
},
254 {SIGSYS
, "SYS", TRUE
},
257 {SIGALRM
, "ALRM", FALSE
}, /* Perl's alarm() can trigger it */
260 {SIGTERM
, "TERM", TRUE
},
263 {SIGVTALRM
, "VTALRM", TRUE
},
265 #if defined(SIGPROF) && !defined(FEAT_MZSCHEME)
266 /* MzScheme uses SIGPROF for its own needs */
267 {SIGPROF
, "PROF", TRUE
},
270 {SIGXCPU
, "XCPU", TRUE
},
273 {SIGXFSZ
, "XFSZ", TRUE
},
276 {SIGUSR1
, "USR1", TRUE
},
279 {SIGUSR2
, "USR2", TRUE
},
282 {SIGINT
, "INT", FALSE
},
285 {SIGWINCH
, "WINCH", FALSE
},
288 {SIGTSTP
, "TSTP", FALSE
},
291 {SIGPIPE
, "PIPE", FALSE
},
293 {-1, "Unknown!", FALSE
}
301 write(1, (char *)s
, len
);
302 if (p_wd
) /* Unix is too fast, slow down a bit more */
303 RealWaitForChar(read_cmd_fd
, p_wd
, NULL
);
307 * mch_inchar(): low level input funcion.
308 * Get a characters from the keyboard.
309 * Return the number of characters that are available.
310 * If wtime == 0 do not wait for characters.
311 * If wtime == n wait a short time for characters.
312 * If wtime == -1 wait forever for characters.
315 mch_inchar(buf
, maxlen
, wtime
, tb_change_cnt
)
318 long wtime
; /* don't use "time", MIPS cannot handle it */
323 /* Check if window changed size while we were busy, perhaps the ":set
324 * columns=99" command was used. */
330 while (WaitForChar(wtime
) == 0) /* no character available */
332 if (!do_resize
) /* return if not interrupted by resize */
337 else /* wtime == -1 */
340 * If there is no character available within 'updatetime' seconds
341 * flush all the swap files to disk.
342 * Also done when interrupted by SIGWINCH.
344 if (WaitForChar(p_ut
) == 0)
347 if (trigger_cursorhold() && maxlen
>= 3
348 && !typebuf_changed(tb_change_cnt
))
352 buf
[2] = (int)KE_CURSORHOLD
;
360 for (;;) /* repeat until we got a character */
362 while (do_resize
) /* window changed size */
365 * we want to be interrupted by the winch signal
368 if (do_resize
) /* interrupted by SIGWINCH signal */
371 /* If input was put directly in typeahead buffer bail out here. */
372 if (typebuf_changed(tb_change_cnt
))
376 * For some terminals we only get one character at a time.
377 * We want the get all available characters, so we could keep on
378 * trying until none is available
379 * For some other terminals this is quite slow, that's why we don't do
382 len
= read_from_input_buf(buf
, (long)maxlen
);
388 for (i
= 0; i
< len
; i
++)
405 * return non-zero if a character is available
410 return WaitForChar(0L);
413 #if defined(HAVE_TOTAL_MEM) || defined(PROTO)
414 # ifdef HAVE_SYS_RESOURCE_H
415 # include <sys/resource.h>
417 # if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTL)
418 # include <sys/sysctl.h>
420 # if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
421 # include <sys/sysinfo.h>
425 * Return total amount of memory available. Doesn't change when memory has
430 mch_total_mem(special
)
434 return ulimit(3, 0L); /* always 32MB? */
442 /* BSD way of getting the amount of RAM available. */
445 len
= sizeof(physmem
);
446 if (sysctl(mib
, 2, &physmem
, &len
, NULL
, 0) == 0)
447 mem
= (long_u
)physmem
;
450 # if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO)
453 struct sysinfo sinfo
;
455 /* Linux way of getting amount of RAM available */
456 if (sysinfo(&sinfo
) == 0)
457 mem
= sinfo
.totalram
;
464 long pagesize
, pagecount
;
466 /* Solaris way of getting amount of RAM available */
467 pagesize
= sysconf(_SC_PAGESIZE
);
468 pagecount
= sysconf(_SC_PHYS_PAGES
);
469 if (pagesize
> 0 && pagecount
> 0)
470 mem
= (long_u
)pagesize
* pagecount
;
474 /* Return the minimum of the physical memory and the user limit, because
475 * using more than the user limit may cause Vim to be terminated. */
476 # if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)
480 if (getrlimit(RLIMIT_DATA
, &rlp
) == 0
481 && rlp
.rlim_cur
< ((rlim_t
)1 << (sizeof(long_u
) * 8 - 1))
482 # ifdef RLIM_INFINITY
483 && rlp
.rlim_cur
!= RLIM_INFINITY
485 && (long_u
)rlp
.rlim_cur
< mem
487 return (long_u
)rlp
.rlim_cur
;
493 return (long_u
)0x7fffffff;
499 mch_delay(msec
, ignoreinput
)
505 long total
= msec
; /* remember original value */
510 /* Go to cooked mode without echo, to allow SIGINT interrupting us
512 old_tmode
= curr_tmode
;
513 if (curr_tmode
== TMODE_RAW
)
514 settmode(TMODE_SLEEP
);
517 * Everybody sleeps in a different way...
518 * Prefer nanosleep(), some versions of usleep() can only sleep up to
524 /* if total is large enough, wait by portions in p_mzq */
531 #ifdef HAVE_NANOSLEEP
535 ts
.tv_sec
= msec
/ 1000;
536 ts
.tv_nsec
= (msec
% 1000) * 1000000;
537 (void)nanosleep(&ts
, NULL
);
543 usleep((unsigned int)(999 * 1000));
546 usleep((unsigned int)(msec
* 1000));
549 poll(NULL
, 0, (int)msec
);
557 tv
.tv_sec
= msec
/ 1000;
558 tv
.tv_usec
= (msec
% 1000) * 1000;
560 * NOTE: Solaris 2.6 has a bug that makes select() hang here. Get
561 * a patch from Sun to fix this. Reported by Gunnar Pedersen.
563 select(0, NULL
, NULL
, NULL
, &tv
);
565 # endif /* __EMX__ */
566 # endif /* HAVE_SELECT */
567 # endif /* HAVE_NANOSLEEP */
568 #endif /* HAVE_USLEEP */
580 #if 0 /* disabled, no longer needed now that regmatch() is not recursive */
581 # if defined(HAVE_GETRLIMIT)
582 # define HAVE_STACK_LIMIT
586 #if defined(HAVE_STACK_LIMIT) \
587 || (!defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGSTACK))
588 # define HAVE_CHECK_STACK_GROWTH
590 * Support for checking for an almost-out-of-stack-space situation.
594 * Return a pointer to an item on the stack. Used to find out if the stack
597 static void check_stack_growth
__ARGS((char *p
));
598 static int stack_grows_downwards
;
601 * Find out if the stack grows upwards or downwards.
602 * "p" points to a variable on the stack of the caller.
605 check_stack_growth(p
)
610 stack_grows_downwards
= (p
> (char *)&i
);
614 #if defined(HAVE_STACK_LIMIT) || defined(PROTO)
615 static char *stack_limit
= NULL
;
617 #if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H)
618 # include <pthread.h>
619 # include <pthread_np.h>
623 * Find out until how var the stack can grow without getting into trouble.
624 * Called when starting up and when switching to the signal stack in
634 /* Set the stack limit to 15/16 of the allowable size. Skip this when the
635 * limit doesn't fit in a long (rlim_cur might be "long long"). */
636 if (getrlimit(RLIMIT_STACK
, &rlp
) == 0
637 && rlp
.rlim_cur
< ((rlim_t
)1 << (sizeof(long_u
) * 8 - 1))
638 # ifdef RLIM_INFINITY
639 && rlp
.rlim_cur
!= RLIM_INFINITY
643 lim
= (long)rlp
.rlim_cur
;
644 #if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H)
649 /* On FreeBSD the initial thread always has a fixed stack size, no
650 * matter what the limits are set to. Normally it's 1 Mbyte. */
651 pthread_attr_init(&attr
);
652 if (pthread_attr_get_np(pthread_self(), &attr
) == 0)
654 pthread_attr_getstacksize(&attr
, &size
);
655 if (lim
> (long)size
)
658 pthread_attr_destroy(&attr
);
661 if (stack_grows_downwards
)
663 stack_limit
= (char *)((long)&i
- (lim
/ 16L * 15L));
664 if (stack_limit
>= (char *)&i
)
665 /* overflow, set to 1/16 of current stack position */
666 stack_limit
= (char *)((long)&i
/ 16L);
670 stack_limit
= (char *)((long)&i
+ (lim
/ 16L * 15L));
671 if (stack_limit
<= (char *)&i
)
672 stack_limit
= NULL
; /* overflow */
678 * Return FAIL when running out of stack space.
679 * "p" must point to any variable local to the caller that's on the stack.
685 if (stack_limit
!= NULL
)
687 if (stack_grows_downwards
)
692 else if (p
> stack_limit
)
699 #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
701 * Support for using the signal stack.
702 * This helps when we run out of stack space, which causes a SIGSEGV. The
703 * signal handler then must run on another stack, since the normal stack is
708 # define SIGSTKSZ 8000 /* just a guess of how much stack is needed... */
711 # ifdef HAVE_SIGALTSTACK
712 static stack_t sigstk
; /* for sigaltstack() */
714 static struct sigstack sigstk
; /* for sigstack() */
717 static void init_signal_stack
__ARGS((void));
718 static char *signal_stack
;
723 if (signal_stack
!= NULL
)
725 # ifdef HAVE_SIGALTSTACK
727 /* missing prototype. Adding it to osdef?.h.in doesn't work, because
728 * "struct sigaltstack" needs to be declared. */
729 extern int sigaltstack
__ARGS((const struct sigaltstack
*ss
, struct sigaltstack
*oss
));
733 sigstk
.ss_base
= signal_stack
;
735 sigstk
.ss_sp
= signal_stack
;
737 sigstk
.ss_size
= SIGSTKSZ
;
739 (void)sigaltstack(&sigstk
, NULL
);
741 sigstk
.ss_sp
= signal_stack
;
742 if (stack_grows_downwards
)
743 sigstk
.ss_sp
+= SIGSTKSZ
- 1;
744 sigstk
.ss_onstack
= 0;
745 (void)sigstack(&sigstk
, NULL
);
752 * We need correct potatotypes for a signal function, otherwise mean compilers
753 * will barf when the second argument to signal() is ``wrong''.
754 * Let me try it with a few tricky defines from my own osdef.h (jw).
756 #if defined(SIGWINCH)
759 sig_winch
SIGDEFARG(sigarg
)
761 /* this is not required on all systems, but it doesn't hurt anybody */
762 signal(SIGWINCH
, (RETSIGTYPE (*)())sig_winch
);
771 catch_sigint
SIGDEFARG(sigarg
)
773 /* this is not required on all systems, but it doesn't hurt anybody */
774 signal(SIGINT
, (RETSIGTYPE (*)())catch_sigint
);
783 catch_sigpwr
SIGDEFARG(sigarg
)
785 /* this is not required on all systems, but it doesn't hurt anybody */
786 signal(SIGPWR
, (RETSIGTYPE (*)())catch_sigpwr
);
788 * I'm not sure we get the SIGPWR signal when the system is really going
789 * down or when the batteries are almost empty. Just preserve the swap
790 * files and don't exit, that can't do any harm.
792 ml_sync_all(FALSE
, FALSE
);
799 * signal function for alarm().
803 sig_alarm
SIGDEFARG(sigarg
)
805 /* doesn't do anything, just to break a system call */
806 sig_alarm_called
= TRUE
;
811 #if (defined(HAVE_SETJMP_H) \
812 && ((defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) \
813 || defined(FEAT_LIBCALL))) \
816 * A simplistic version of setjmp() that only allows one level of using.
817 * Don't call twice before calling mch_endjmp()!.
820 * if (SETJMP(lc_jump_env) != 0)
830 * Note: Can't move SETJMP() here, because a function calling setjmp() must
831 * not return before the saved environment is used.
832 * Returns OK for normal return, FAIL when the protected code caused a
833 * problem and LONGJMP() was used.
853 # if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
854 /* On FreeBSD the signal stack has to be reset after using siglongjmp(),
855 * otherwise catching the signal only works once. */
862 * This function handles deadly signals.
863 * It tries to preserve any swap file and exit properly.
864 * (partly from Elvis).
867 deathtrap
SIGDEFARG(sigarg
)
869 static int entered
= 0; /* count the number of times we got here.
870 Note: when memory has been corrupted
871 this may get an arbitrary value! */
876 #if defined(HAVE_SETJMP_H)
878 * Catch a crash in protected code.
879 * Restores the environment saved in lc_jump_env, which looks like
880 * SETJMP() returns 1.
884 # if defined(SIGHASARG)
887 lc_active
= FALSE
; /* don't jump again */
888 LONGJMP(lc_jump_env
, 1);
894 /* When SIGHUP, SIGQUIT, etc. are blocked: postpone the effect and return
895 * here. This avoids that a non-reentrant function is interrupted, e.g.,
896 * free(). Calling free() again may then cause a crash. */
918 && !vim_handle_signal(sigarg
))
922 /* Remember how often we have been called. */
926 /* Set the v:dying variable. */
927 set_vim_var_nr(VV_DYING
, (long)entered
);
930 #ifdef HAVE_STACK_LIMIT
931 /* Since we are now using the signal stack, need to reset the stack
932 * limit. Otherwise using a regexp will fail. */
937 /* This is for opening gdb the moment Vim crashes.
938 * You need to manually adjust the file name and Vim executable name.
939 * Suggested by SungHyun Nam. */
941 # define VI_GDB_FILE "/tmp/vimgdb"
942 # define VIM_NAME "/usr/bin/vim"
943 FILE *fp
= fopen(VI_GDB_FILE
, "w");
951 , VIM_NAME
, getpid());
953 system("xterm -e gdb -x "VI_GDB_FILE
);
960 /* try to find the name of this signal */
961 for (i
= 0; signal_info
[i
].sig
!= -1; i
++)
962 if (sigarg
== signal_info
[i
].sig
)
964 deadly_signal
= sigarg
;
967 full_screen
= FALSE
; /* don't write message to the GUI, it might be
968 * part of the problem... */
970 * If something goes wrong after entering here, we may get here again.
971 * When this happens, give a message and try to exit nicely (resetting the
972 * terminal mode, etc.)
973 * When this happens twice, just exit, don't even try to give a message,
974 * stack may be corrupt or something weird.
975 * When this still happens again (or memory was corrupted in such a way
976 * that "entered" was clobbered) use _exit(), don't try freeing resources.
980 reset_signals(); /* don't catch any signals anymore */
988 OUT_STR(_("Vim: Double signal, exiting\n"));
994 sprintf((char *)IObuff
, _("Vim: Caught deadly signal %s\n"),
995 signal_info
[i
].name
);
997 sprintf((char *)IObuff
, _("Vim: Caught deadly signal\n"));
999 preserve_exit(); /* preserve files and exit */
1012 * On Solaris with multi-threading, suspending might not work immediately.
1013 * Catch the SIGCONT signal, which will be used as an indication whether the
1014 * suspending has been done or not.
1016 static int sigcont_received
;
1017 static RETSIGTYPE sigcont_handler
__ARGS(SIGPROTOARG
);
1020 * signal handler for SIGCONT
1024 sigcont_handler
SIGDEFARG(sigarg
)
1026 sigcont_received
= TRUE
;
1032 * If the machine has job control, use it to suspend the program,
1033 * otherwise fake it by starting a new shell.
1038 /* BeOS does have SIGTSTP, but it doesn't work. */
1039 #if defined(SIGTSTP) && !defined(__BEOS__)
1040 out_flush(); /* needed to make cursor visible on some systems */
1041 settmode(TMODE_COOK
);
1042 out_flush(); /* needed to disable mouse on some systems */
1044 # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
1045 /* Since we are going to sleep, we can't respond to requests for the X
1046 * selections. Lose them, otherwise other applications will hang. But
1047 * first copy the text to cut buffer 0. */
1048 if (clip_star
.owned
|| clip_plus
.owned
)
1050 x11_export_final_selection();
1051 if (clip_star
.owned
)
1052 clip_lose_selection(&clip_star
);
1053 if (clip_plus
.owned
)
1054 clip_lose_selection(&clip_plus
);
1055 if (x11_display
!= NULL
)
1056 XFlush(x11_display
);
1061 sigcont_received
= FALSE
;
1063 kill(0, SIGTSTP
); /* send ourselves a STOP signal */
1065 /* When we didn't suspend immediately in the kill(), do it now. Happens
1066 * on multi-threaded Solaris. */
1067 if (!sigcont_received
)
1073 * Set oldtitle to NULL, so the current title is obtained again.
1078 settmode(TMODE_RAW
);
1079 need_check_timestamps
= TRUE
;
1080 did_check_timestamps
= FALSE
;
1095 #ifdef MACOS_CONVERT
1103 #if defined(SIGWINCH)
1105 * WINDOW CHANGE signal is handled with sig_winch().
1107 signal(SIGWINCH
, (RETSIGTYPE (*)())sig_winch
);
1111 * We want the STOP signal to work, to make mch_suspend() work.
1112 * For "rvim" the STOP signal is ignored.
1115 signal(SIGTSTP
, restricted
? SIG_IGN
: SIG_DFL
);
1118 signal(SIGCONT
, sigcont_handler
);
1122 * We want to ignore breaking of PIPEs.
1125 signal(SIGPIPE
, SIG_IGN
);
1133 * Ignore alarm signals (Perl's alarm() generates it).
1136 signal(SIGALRM
, SIG_IGN
);
1140 * Catch SIGPWR (power failure?) to preserve the swap files, so that no
1141 * work will be lost.
1144 signal(SIGPWR
, (RETSIGTYPE (*)())catch_sigpwr
);
1148 * Arrange for other signals to gracefully shutdown Vim.
1150 catch_signals(deathtrap
, SIG_ERR
);
1152 #if defined(FEAT_GUI) && defined(SIGHUP)
1154 * When the GUI is running, ignore the hangup signal.
1157 signal(SIGHUP
, SIG_IGN
);
1161 #if defined(SIGINT) || defined(PROTO)
1163 * Catch CTRL-C (only works while in Cooked mode).
1168 signal(SIGINT
, (RETSIGTYPE (*)())catch_sigint
);
1175 catch_signals(SIG_DFL
, SIG_DFL
);
1177 /* SIGCONT isn't in the list, because its default action is ignore */
1178 signal(SIGCONT
, SIG_DFL
);
1183 catch_signals(func_deadly
, func_other
)
1184 RETSIGTYPE (*func_deadly
)();
1185 RETSIGTYPE (*func_other
)();
1189 for (i
= 0; signal_info
[i
].sig
!= -1; i
++)
1190 if (signal_info
[i
].deadly
)
1192 #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION)
1193 struct sigaction sa
;
1195 /* Setup to use the alternate stack for the signal function. */
1196 sa
.sa_handler
= func_deadly
;
1197 sigemptyset(&sa
.sa_mask
);
1198 # if defined(__linux__) && defined(_REENTRANT)
1199 /* On Linux, with glibc compiled for kernel 2.2, there is a bug in
1200 * thread handling in combination with using the alternate stack:
1201 * pthread library functions try to use the stack pointer to
1202 * identify the current thread, causing a SEGV signal, which
1203 * recursively calls deathtrap() and hangs. */
1206 sa
.sa_flags
= SA_ONSTACK
;
1208 sigaction(signal_info
[i
].sig
, &sa
, NULL
);
1210 # if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGVEC)
1213 /* Setup to use the alternate stack for the signal function. */
1214 sv
.sv_handler
= func_deadly
;
1216 sv
.sv_flags
= SV_ONSTACK
;
1217 sigvec(signal_info
[i
].sig
, &sv
, NULL
);
1219 signal(signal_info
[i
].sig
, func_deadly
);
1223 else if (func_other
!= SIG_ERR
)
1224 signal(signal_info
[i
].sig
, func_other
);
1228 * Handling of SIGHUP, SIGQUIT and SIGTERM:
1229 * "when" == a signal: when busy, postpone, otherwise return TRUE
1230 * "when" == SIGNAL_BLOCK: Going to be busy, block signals
1231 * "when" == SIGNAL_UNBLOCK: Going wait, unblock signals
1232 * Returns TRUE when Vim should exit.
1235 vim_handle_signal(sig
)
1238 static int got_signal
= 0;
1239 static int blocked
= TRUE
;
1243 case SIGNAL_BLOCK
: blocked
= TRUE
;
1246 case SIGNAL_UNBLOCK
: blocked
= FALSE
;
1247 if (got_signal
!= 0)
1249 kill(getpid(), got_signal
);
1254 default: if (!blocked
)
1255 return TRUE
; /* exit! */
1260 got_int
= TRUE
; /* break any loops */
1267 * Check_win checks whether we have an interactive stdout.
1271 mch_check_win(argc
, argv
)
1277 * Store argv[0], may be used for $VIM. Only use it if it is an absolute
1278 * name, mostly it's just "vim" and found in the path, which is unusable.
1280 if (mch_isFullName(argv
[0]))
1281 exe_name
= vim_strsave((char_u
*)argv
[0]);
1289 * Return TRUE if the input comes from a terminal, FALSE otherwise.
1294 if (isatty(read_cmd_fd
))
1301 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) \
1302 && (defined(FEAT_XCLIPBOARD) || defined(FEAT_TITLE))
1304 static void xopen_message
__ARGS((struct timeval
*tvp
));
1307 * Give a message about the elapsed time for opening the X window.
1311 struct timeval
*tvp
; /* must contain start time */
1313 struct timeval end_tv
;
1315 /* Compute elapsed time. */
1316 gettimeofday(&end_tv
, NULL
);
1317 smsg((char_u
*)_("Opening the X display took %ld msec"),
1318 (end_tv
.tv_sec
- tvp
->tv_sec
) * 1000L
1319 + (end_tv
.tv_usec
- tvp
->tv_usec
) / 1000L);
1324 #if defined(FEAT_X11) && (defined(FEAT_TITLE) || defined(FEAT_XCLIPBOARD))
1326 * A few functions shared by X11 title and clipboard code.
1328 static int x_error_handler
__ARGS((Display
*dpy
, XErrorEvent
*error_event
));
1329 static int x_error_check
__ARGS((Display
*dpy
, XErrorEvent
*error_event
));
1330 static int x_connect_to_server
__ARGS((void));
1331 static int test_x11_window
__ARGS((Display
*dpy
));
1333 static int got_x_error
= FALSE
;
1336 * X Error handler, otherwise X just exits! (very rude) -- webb
1339 x_error_handler(dpy
, error_event
)
1341 XErrorEvent
*error_event
;
1343 XGetErrorText(dpy
, error_event
->error_code
, (char *)IObuff
, IOSIZE
);
1344 STRCAT(IObuff
, _("\nVim: Got X error\n"));
1346 /* We cannot print a message and continue, because no X calls are allowed
1347 * here (causes my system to hang). Silently continuing might be an
1349 preserve_exit(); /* preserve files and exit */
1351 return 0; /* NOTREACHED */
1355 * Another X Error handler, just used to check for errors.
1359 x_error_check(dpy
, error_event
)
1361 XErrorEvent
*error_event
;
1367 #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
1368 # if defined(HAVE_SETJMP_H)
1370 * An X IO Error handler, used to catch error while opening the display.
1372 static int x_IOerror_check
__ARGS((Display
*dpy
));
1376 x_IOerror_check(dpy
)
1379 /* This function should not return, it causes exit(). Longjump instead. */
1380 LONGJMP(lc_jump_env
, 1);
1387 * An X IO Error handler, used to catch terminal errors.
1389 static int x_IOerror_handler
__ARGS((Display
*dpy
));
1393 x_IOerror_handler(dpy
)
1399 xterm_Shell
= (Widget
)0;
1401 /* This function should not return, it causes exit(). Longjump instead. */
1402 LONGJMP(x_jump_env
, 1);
1409 * Return TRUE when connection to the X server is desired.
1412 x_connect_to_server()
1414 regmatch_T regmatch
;
1416 #if defined(FEAT_CLIENTSERVER)
1417 if (x_force_connect
)
1423 /* Check for a match with "exclude:" from 'clipboard'. */
1424 if (clip_exclude_prog
!= NULL
)
1426 regmatch
.rm_ic
= FALSE
; /* Don't ignore case */
1427 regmatch
.regprog
= clip_exclude_prog
;
1428 if (vim_regexec(®match
, T_NAME
, (colnr_T
)0))
1435 * Test if "dpy" and x11_window are valid by getting the window title.
1436 * I don't actually want it yet, so there may be a simpler call to use, but
1437 * this will cause the error handler x_error_check() to be called if anything
1438 * is wrong, such as the window pointer being invalid (as can happen when the
1439 * user changes his DISPLAY, but not his WINDOWID) -- webb
1442 test_x11_window(dpy
)
1445 int (*old_handler
)();
1446 XTextProperty text_prop
;
1448 old_handler
= XSetErrorHandler(x_error_check
);
1449 got_x_error
= FALSE
;
1450 if (XGetWMName(dpy
, x11_window
, &text_prop
))
1451 XFree((void *)text_prop
.value
);
1453 (void)XSetErrorHandler(old_handler
);
1455 if (p_verbose
> 0 && got_x_error
)
1456 verb_msg((char_u
*)_("Testing the X display failed"));
1458 return (got_x_error
? FAIL
: OK
);
1466 static int get_x11_thing
__ARGS((int get_title
, int test_only
));
1469 * try to get x11 window and display
1471 * return FAIL for failure, OK otherwise
1477 static int result
= -1;
1478 #define XD_NONE 0 /* x11_display not set here */
1479 #define XD_HERE 1 /* x11_display opened here */
1480 #define XD_GUI 2 /* x11_display used from gui.dpy */
1481 #define XD_XTERM 3 /* x11_display used from xterm_dpy */
1482 static int x11_display_from
= XD_NONE
;
1483 static int did_set_error_handler
= FALSE
;
1485 if (!did_set_error_handler
)
1487 /* X just exits if it finds an error otherwise! */
1488 (void)XSetErrorHandler(x_error_handler
);
1489 did_set_error_handler
= TRUE
;
1492 #if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
1496 * If the X11 display was opened here before, for the window where Vim
1497 * was started, close that one now to avoid a memory leak.
1499 if (x11_display_from
== XD_HERE
&& x11_display
!= NULL
)
1501 XCloseDisplay(x11_display
);
1502 x11_display_from
= XD_NONE
;
1504 if (gui_get_x11_windis(&x11_window
, &x11_display
) == OK
)
1506 x11_display_from
= XD_GUI
;
1512 else if (x11_display_from
== XD_GUI
)
1514 /* GUI must have stopped somehow, clear x11_display */
1517 x11_display_from
= XD_NONE
;
1521 /* When started with the "-X" argument, don't try connecting. */
1522 if (!x_connect_to_server())
1526 * If WINDOWID not set, should try another method to find out
1527 * what the current window number is. The only code I know for
1528 * this is very complicated.
1529 * We assume that zero is invalid for WINDOWID.
1531 if (x11_window
== 0 && (winid
= getenv("WINDOWID")) != NULL
)
1532 x11_window
= (Window
)atol(winid
);
1534 #ifdef FEAT_XCLIPBOARD
1535 if (xterm_dpy
!= NULL
&& x11_window
!= 0)
1537 /* Checked it already. */
1538 if (x11_display_from
== XD_XTERM
)
1542 * If the X11 display was opened here before, for the window where Vim
1543 * was started, close that one now to avoid a memory leak.
1545 if (x11_display_from
== XD_HERE
&& x11_display
!= NULL
)
1546 XCloseDisplay(x11_display
);
1547 x11_display
= xterm_dpy
;
1548 x11_display_from
= XD_XTERM
;
1549 if (test_x11_window(x11_display
) == FAIL
)
1551 /* probably bad $WINDOWID */
1554 x11_display_from
= XD_NONE
;
1561 if (x11_window
== 0 || x11_display
== NULL
)
1564 if (result
!= -1) /* Have already been here and set this */
1565 return result
; /* Don't do all these X calls again */
1567 if (x11_window
!= 0 && x11_display
== NULL
)
1569 #ifdef SET_SIG_ALARM
1570 RETSIGTYPE (*sig_save
)();
1572 #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1573 struct timeval start_tv
;
1576 gettimeofday(&start_tv
, NULL
);
1579 #ifdef SET_SIG_ALARM
1581 * Opening the Display may hang if the DISPLAY setting is wrong, or
1582 * the network connection is bad. Set an alarm timer to get out.
1584 sig_alarm_called
= FALSE
;
1585 sig_save
= (RETSIGTYPE (*)())signal(SIGALRM
,
1586 (RETSIGTYPE (*)())sig_alarm
);
1589 x11_display
= XOpenDisplay(NULL
);
1591 #ifdef SET_SIG_ALARM
1593 signal(SIGALRM
, (RETSIGTYPE (*)())sig_save
);
1594 if (p_verbose
> 0 && sig_alarm_called
)
1595 verb_msg((char_u
*)_("Opening the X display timed out"));
1597 if (x11_display
!= NULL
)
1599 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1603 xopen_message(&start_tv
);
1607 if (test_x11_window(x11_display
) == FAIL
)
1609 /* Maybe window id is bad */
1611 XCloseDisplay(x11_display
);
1615 x11_display_from
= XD_HERE
;
1618 if (x11_window
== 0 || x11_display
== NULL
)
1619 return (result
= FAIL
);
1620 return (result
= OK
);
1624 * Determine original x11 Window Title
1627 get_x11_title(test_only
)
1630 return get_x11_thing(TRUE
, test_only
);
1634 * Determine original x11 Window icon
1637 get_x11_icon(test_only
)
1642 retval
= get_x11_thing(FALSE
, test_only
);
1644 /* could not get old icon, use terminal name */
1645 if (oldicon
== NULL
&& !test_only
)
1647 if (STRNCMP(T_NAME
, "builtin_", 8) == 0)
1648 oldicon
= T_NAME
+ 8;
1657 get_x11_thing(get_title
, test_only
)
1658 int get_title
; /* get title string */
1661 XTextProperty text_prop
;
1665 if (get_x11_windis() == OK
)
1667 /* Get window/icon name if any */
1669 status
= XGetWMName(x11_display
, x11_window
, &text_prop
);
1671 status
= XGetWMIconName(x11_display
, x11_window
, &text_prop
);
1674 * If terminal is xterm, then x11_window may be a child window of the
1675 * outer xterm window that actually contains the window/icon name, so
1676 * keep traversing up the tree until a window with a title/icon is
1679 /* Previously this was only done for xterm and alikes. I don't see a
1680 * reason why it would fail for other terminal emulators.
1681 * if (term_is_xterm) */
1685 Window win
= x11_window
;
1687 unsigned int num_children
;
1689 while (!status
|| text_prop
.value
== NULL
)
1691 if (!XQueryTree(x11_display
, win
, &root
, &parent
, &children
,
1695 XFree((void *)children
);
1696 if (parent
== root
|| parent
== 0)
1701 status
= XGetWMName(x11_display
, win
, &text_prop
);
1703 status
= XGetWMIconName(x11_display
, win
, &text_prop
);
1706 if (status
&& text_prop
.value
!= NULL
)
1711 #ifdef FEAT_XFONTSET
1712 if (text_prop
.encoding
== XA_STRING
)
1716 oldtitle
= vim_strsave((char_u
*)text_prop
.value
);
1718 oldicon
= vim_strsave((char_u
*)text_prop
.value
);
1719 #ifdef FEAT_XFONTSET
1724 Status transform_status
;
1727 transform_status
= XmbTextPropertyToTextList(x11_display
,
1730 if (transform_status
>= Success
&& n
> 0 && cl
[0])
1733 oldtitle
= vim_strsave((char_u
*) cl
[0]);
1735 oldicon
= vim_strsave((char_u
*) cl
[0]);
1736 XFreeStringList(cl
);
1741 oldtitle
= vim_strsave((char_u
*)text_prop
.value
);
1743 oldicon
= vim_strsave((char_u
*)text_prop
.value
);
1748 XFree((void *)text_prop
.value
);
1754 /* Are Xutf8 functions available? Avoid error from old compilers. */
1755 #if defined(X_HAVE_UTF8_STRING) && defined(FEAT_MBYTE)
1756 # if X_HAVE_UTF8_STRING
1757 # define USE_UTF8_STRING
1762 * Set x11 Window Title
1764 * get_x11_windis() must be called before this and have returned OK
1767 set_x11_title(title
)
1770 /* XmbSetWMProperties() and Xutf8SetWMProperties() should use a STRING
1771 * when possible, COMPOUND_TEXT otherwise. COMPOUND_TEXT isn't
1772 * supported everywhere and STRING doesn't work for multi-byte titles.
1774 #ifdef USE_UTF8_STRING
1776 Xutf8SetWMProperties(x11_display
, x11_window
, (const char *)title
,
1777 NULL
, NULL
, 0, NULL
, NULL
, NULL
);
1781 #if XtSpecificationRelease >= 4
1782 # ifdef FEAT_XFONTSET
1783 XmbSetWMProperties(x11_display
, x11_window
, (const char *)title
,
1784 NULL
, NULL
, 0, NULL
, NULL
, NULL
);
1786 XTextProperty text_prop
;
1787 char *c_title
= (char *)title
;
1789 /* directly from example 3-18 "basicwin" of Xlib Programming Manual */
1790 (void)XStringListToTextProperty(&c_title
, 1, &text_prop
);
1791 XSetWMProperties(x11_display
, x11_window
, &text_prop
,
1792 NULL
, NULL
, 0, NULL
, NULL
, NULL
);
1795 XStoreName(x11_display
, x11_window
, (char *)title
);
1798 XFlush(x11_display
);
1802 * Set x11 Window icon
1804 * get_x11_windis() must be called before this and have returned OK
1810 /* See above for comments about using X*SetWMProperties(). */
1811 #ifdef USE_UTF8_STRING
1813 Xutf8SetWMProperties(x11_display
, x11_window
, NULL
, (const char *)icon
,
1814 NULL
, 0, NULL
, NULL
, NULL
);
1818 #if XtSpecificationRelease >= 4
1819 # ifdef FEAT_XFONTSET
1820 XmbSetWMProperties(x11_display
, x11_window
, NULL
, (const char *)icon
,
1821 NULL
, 0, NULL
, NULL
, NULL
);
1823 XTextProperty text_prop
;
1824 char *c_icon
= (char *)icon
;
1826 (void)XStringListToTextProperty(&c_icon
, 1, &text_prop
);
1827 XSetWMProperties(x11_display
, x11_window
, NULL
, &text_prop
,
1828 NULL
, 0, NULL
, NULL
, NULL
);
1831 XSetIconName(x11_display
, x11_window
, (char *)icon
);
1834 XFlush(x11_display
);
1837 #else /* FEAT_X11 */
1841 get_x11_title(test_only
)
1848 get_x11_icon(test_only
)
1853 if (STRNCMP(T_NAME
, "builtin_", 8) == 0)
1854 oldicon
= T_NAME
+ 8;
1861 #endif /* FEAT_X11 */
1864 mch_can_restore_title()
1866 return get_x11_title(TRUE
);
1870 mch_can_restore_icon()
1872 return get_x11_icon(TRUE
);
1876 * Set the window title and icon.
1879 mch_settitle(title
, icon
)
1884 static int recursive
= 0;
1886 if (T_NAME
== NULL
) /* no terminal name (yet) */
1888 if (title
== NULL
&& icon
== NULL
) /* nothing to do */
1891 /* When one of the X11 functions causes a deadly signal, we get here again
1892 * recursively. Avoid hanging then (something is probably locked). */
1898 * if the window ID and the display is known, we may use X11 calls
1901 if (get_x11_windis() == OK
)
1904 # if defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK)
1911 * Note: if "t_TS" is set, title is set with escape sequence rather
1912 * than x11 calls, because the x11 calls don't always work
1914 if ((type
|| *T_TS
!= NUL
) && title
!= NULL
)
1916 if (oldtitle
== NULL
1920 ) /* first call but not in GUI, save title */
1921 (void)get_x11_title(FALSE
);
1923 if (*T_TS
!= NUL
) /* it's OK if t_fs is empty */
1924 term_settitle(title
);
1927 # ifdef FEAT_GUI_GTK
1928 if (!gui
.in_use
) /* don't do this if GTK+ is running */
1930 set_x11_title(title
); /* x11 */
1932 #if defined(FEAT_GUI_GTK) \
1933 || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
1935 gui_mch_settitle(title
, icon
);
1937 did_set_title
= TRUE
;
1940 if ((type
|| *T_CIS
!= NUL
) && icon
!= NULL
)
1946 ) /* first call, save icon */
1947 get_x11_icon(FALSE
);
1951 out_str(T_CIS
); /* set icon start */
1953 out_str(T_CIE
); /* set icon end */
1958 # ifdef FEAT_GUI_GTK
1959 if (!gui
.in_use
) /* don't do this if GTK+ is running */
1961 set_x11_icon(icon
); /* x11 */
1963 did_set_icon
= TRUE
;
1969 * Restore the window/icon title.
1970 * "which" is one of:
1971 * 1 only restore title
1972 * 2 only restore icon
1973 * 3 restore title and icon
1976 mch_restore_title(which
)
1979 /* only restore the title or icon when it has been set */
1980 mch_settitle(((which
& 1) && did_set_title
) ?
1981 (oldtitle
? oldtitle
: p_titleold
) : NULL
,
1982 ((which
& 2) && did_set_icon
) ? oldicon
: NULL
);
1985 #endif /* FEAT_TITLE */
1988 * Return TRUE if "name" looks like some xterm name.
1989 * Seiichi Sato mentioned that "mlterm" works like xterm.
1997 return (STRNICMP(name
, "xterm", 5) == 0
1998 || STRNICMP(name
, "nxterm", 6) == 0
1999 || STRNICMP(name
, "kterm", 5) == 0
2000 || STRNICMP(name
, "mlterm", 6) == 0
2001 || STRNICMP(name
, "rxvt", 4) == 0
2002 || STRCMP(name
, "builtin_xterm") == 0);
2005 #if defined(FEAT_MOUSE_TTY) || defined(PROTO)
2007 * Return non-zero when using an xterm mouse, according to 'ttymouse'.
2008 * Return 1 for "xterm".
2009 * Return 2 for "xterm2".
2014 if (ttym_flags
== TTYM_XTERM2
)
2016 if (ttym_flags
== TTYM_XTERM
)
2028 return (STRNICMP(name
, "iris-ansi", 9) == 0
2029 || STRCMP(name
, "builtin_iris-ansi") == 0);
2037 return FALSE
; /* actually all ANSI comp. terminals should be here */
2038 /* catch VT100 - VT5xx */
2039 return ((STRNICMP(name
, "vt", 2) == 0
2040 && vim_strchr((char_u
*)"12345", name
[2]) != NULL
)
2041 || STRCMP(name
, "builtin_vt320") == 0);
2045 * Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
2046 * This should include all windowed terminal emulators.
2049 vim_is_fastterm(name
)
2054 if (vim_is_xterm(name
) || vim_is_vt300(name
) || vim_is_iris(name
))
2056 return ( STRNICMP(name
, "hpterm", 6) == 0
2057 || STRNICMP(name
, "sun-cmd", 7) == 0
2058 || STRNICMP(name
, "screen", 6) == 0
2059 || STRNICMP(name
, "dtterm", 6) == 0);
2063 * Insert user name in s[len].
2064 * Return OK if a name found.
2067 mch_get_user_name(s
, len
)
2072 vim_strncpy(s
, (char_u
*)cuserid(NULL
), len
- 1);
2075 return mch_get_uname(getuid(), s
, len
);
2080 * Insert user name for "uid" in s[len].
2081 * Return OK if a name found.
2084 mch_get_uname(uid
, s
, len
)
2089 #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
2092 if ((pw
= getpwuid(uid
)) != NULL
2093 && pw
->pw_name
!= NULL
&& *(pw
->pw_name
) != NUL
)
2095 vim_strncpy(s
, (char_u
*)pw
->pw_name
, len
- 1);
2099 sprintf((char *)s
, "%d", (int)uid
); /* assumes s is long enough */
2100 return FAIL
; /* a number is not a name */
2104 * Insert host name is s[len].
2107 #ifdef HAVE_SYS_UTSNAME_H
2109 mch_get_host_name(s
, len
)
2113 struct utsname vutsname
;
2115 if (uname(&vutsname
) < 0)
2118 vim_strncpy(s
, (char_u
*)vutsname
.nodename
, len
- 1);
2120 #else /* HAVE_SYS_UTSNAME_H */
2122 # ifdef HAVE_SYS_SYSTEMINFO_H
2123 # define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len)
2127 mch_get_host_name(s
, len
)
2132 vaxc$
gethostname((char *)s
, len
);
2134 gethostname((char *)s
, len
);
2136 s
[len
- 1] = NUL
; /* make sure it's terminated */
2138 #endif /* HAVE_SYS_UTSNAME_H */
2146 return (long)getpid();
2149 #if !defined(HAVE_STRERROR) && defined(USE_GETCWD)
2150 static char *strerror
__ARGS((int));
2156 extern int sys_nerr
;
2157 extern char *sys_errlist
[];
2160 if (err
> 0 && err
< sys_nerr
)
2161 return (sys_errlist
[err
]);
2162 sprintf(er
, "Error %d", err
);
2168 * Get name of current directory into buffer 'buf' of length 'len' bytes.
2169 * Return OK for success, FAIL for failure.
2172 mch_dirname(buf
, len
)
2176 #if defined(USE_GETCWD)
2177 if (getcwd((char *)buf
, len
) == NULL
)
2179 STRCPY(buf
, strerror(errno
));
2184 return (getwd((char *)buf
) != NULL
? OK
: FAIL
);
2188 #if defined(OS2) || defined(PROTO)
2190 * Replace all slashes by backslashes.
2191 * When 'shellslash' set do it the other way around.
2207 * Get absolute file name into "buf[len]".
2209 * return FAIL for failure, OK for success
2212 mch_FullName(fname
, buf
, len
, force
)
2213 char_u
*fname
, *buf
;
2215 int force
; /* also expand when already absolute path */
2219 int only_drive
; /* file name is only a drive letter */
2223 static int dont_fchdir
= FALSE
; /* TRUE when fchdir() doesn't work */
2225 char_u olddir
[MAXPATHL
];
2230 fname
= vms_fixfilename(fname
);
2233 /* expand it if forced or not an absolute path */
2234 if (force
|| !mch_isFullName(fname
))
2237 * If the file name has a path, change to that directory for a moment,
2238 * and then do the getwd() (and get back to where we were).
2239 * This will get the correct path name with "../" things.
2243 if (((p
= vim_strrchr(fname
, '/')) != NULL
)
2244 || ((p
= vim_strrchr(fname
, '\\')) != NULL
)
2245 || (((p
= vim_strchr(fname
, ':')) != NULL
) && ++only_drive
))
2247 if ((p
= vim_strrchr(fname
, '/')) != NULL
)
2252 * Use fchdir() if possible, it's said to be faster and more
2253 * reliable. But on SunOS 4 it might not work. Check this by
2254 * doing a fchdir() right now.
2258 fd
= open(".", O_RDONLY
| O_EXTRA
, 0);
2259 if (fd
>= 0 && fchdir(fd
) < 0)
2263 dont_fchdir
= TRUE
; /* don't try again */
2268 /* Only change directory when we are sure we can return to where
2269 * we are now. After doing "su" chdir(".") might not work. */
2274 (mch_dirname(olddir
, MAXPATHL
) == FAIL
2275 || mch_chdir((char *)olddir
) != 0))
2277 p
= NULL
; /* can't get current dir: don't chdir */
2284 * compensate for case where ':' from "D:" was the only
2285 * path separator detected in the file name; the _next_
2286 * character has to be removed, and then restored later.
2291 /* The directory is copied into buf[], to be able to remove
2292 * the file name without changing it (could be a string in
2293 * read-only memory) */
2294 if (p
- fname
>= len
)
2298 vim_strncpy(buf
, fname
, p
- fname
);
2299 if (mch_chdir((char *)buf
))
2315 if (mch_dirname(buf
, len
) == FAIL
)
2330 l
= mch_chdir((char *)olddir
);
2332 EMSG(_(e_prev_dir
));
2341 if (l
> 0 && buf
[l
- 1] != '/' && *fname
!= NUL
2342 && STRCMP(fname
, ".") != 0)
2348 /* Catch file names which are too long. */
2349 if (retval
== FAIL
|| STRLEN(buf
) + STRLEN(fname
) >= len
)
2352 /* Do not append ".", "/dir/." is equal to "/dir". */
2353 if (STRCMP(fname
, ".") != 0)
2360 * Return TRUE if "fname" does not depend on the current directory.
2363 mch_isFullName(fname
)
2367 return _fnisabs(fname
);
2370 return ( fname
[0] == '/' || fname
[0] == '.' ||
2371 strchr((char *)fname
,':') || strchr((char *)fname
,'"') ||
2372 (strchr((char *)fname
,'[') && strchr((char *)fname
,']'))||
2373 (strchr((char *)fname
,'<') && strchr((char *)fname
,'>')) );
2375 return (*fname
== '/' || *fname
== '~');
2380 #if defined(USE_FNAME_CASE) || defined(PROTO)
2382 * Set the case of the file name, if it already exists. This will cause the
2383 * file name to remain exactly the same.
2384 * Only required for file systems where case is ingored and preserved.
2388 fname_case(name
, len
)
2390 int len
; /* buffer size, only used when name gets longer */
2393 char_u
*slash
, *tail
;
2397 if (lstat((char *)name
, &st
) >= 0)
2399 /* Open the directory where the file is located. */
2400 slash
= vim_strrchr(name
, '/');
2403 dirp
= opendir(".");
2409 dirp
= opendir((char *)name
);
2416 while ((dp
= readdir(dirp
)) != NULL
)
2418 /* Only accept names that differ in case and are the same byte
2419 * length. TODO: accept different length name. */
2420 if (STRICMP(tail
, dp
->d_name
) == 0
2421 && STRLEN(tail
) == STRLEN(dp
->d_name
))
2423 char_u newname
[MAXPATHL
+ 1];
2426 /* Verify the inode is equal. */
2427 vim_strncpy(newname
, name
, MAXPATHL
);
2428 vim_strncpy(newname
+ (tail
- name
), (char_u
*)dp
->d_name
,
2429 MAXPATHL
- (tail
- name
));
2430 if (lstat((char *)newname
, &st2
) >= 0
2431 && st
.st_ino
== st2
.st_ino
2432 && st
.st_dev
== st2
.st_dev
)
2434 STRCPY(tail
, dp
->d_name
);
2447 * Get file permissions for 'name'.
2448 * Returns -1 when it doesn't exist.
2456 /* Keep the #ifdef outside of stat(), it may be a macro. */
2458 if (stat((char *)vms_fixfilename(name
), &statb
))
2460 if (stat((char *)name
, &statb
))
2463 return statb
.st_mode
;
2467 * set file permission for 'name' to 'perm'
2469 * return FAIL for failure, OK otherwise
2472 mch_setperm(name
, perm
)
2476 return (chmod((char *)
2478 vms_fixfilename(name
),
2482 (mode_t
)perm
) == 0 ? OK
: FAIL
);
2485 #if defined(HAVE_ACL) || defined(PROTO)
2486 # ifdef HAVE_SYS_ACL_H
2487 # include <sys/acl.h>
2489 # ifdef HAVE_SYS_ACCESS_H
2490 # include <sys/access.h>
2493 # ifdef HAVE_SOLARIS_ACL
2494 typedef struct vim_acl_solaris_T
{
2496 aclent_t
*acl_entry
;
2497 } vim_acl_solaris_T
;
2501 * Return a pointer to the ACL of file "fname" in allocated memory.
2502 * Return NULL if the ACL is not available for whatever reason.
2508 vim_acl_T ret
= NULL
;
2509 #ifdef HAVE_POSIX_ACL
2510 ret
= (vim_acl_T
)acl_get_file((char *)fname
, ACL_TYPE_ACCESS
);
2512 #ifdef HAVE_SOLARIS_ACL
2513 vim_acl_solaris_T
*aclent
;
2515 aclent
= malloc(sizeof(vim_acl_solaris_T
));
2516 if ((aclent
->acl_cnt
= acl((char *)fname
, GETACLCNT
, 0, NULL
)) < 0)
2521 aclent
->acl_entry
= malloc(aclent
->acl_cnt
* sizeof(aclent_t
));
2522 if (acl((char *)fname
, GETACL
, aclent
->acl_cnt
, aclent
->acl_entry
) < 0)
2524 free(aclent
->acl_entry
);
2528 ret
= (vim_acl_T
)aclent
;
2530 #if defined(HAVE_AIX_ACL)
2534 aclsize
= sizeof(struct acl
);
2535 aclent
= malloc(aclsize
);
2536 if (statacl((char *)fname
, STX_NORMAL
, aclent
, aclsize
) < 0)
2538 if (errno
== ENOSPC
)
2540 aclsize
= aclent
->acl_len
;
2541 aclent
= realloc(aclent
, aclsize
);
2542 if (statacl((char *)fname
, STX_NORMAL
, aclent
, aclsize
) < 0)
2554 ret
= (vim_acl_T
)aclent
;
2555 #endif /* HAVE_AIX_ACL */
2556 #endif /* HAVE_SOLARIS_ACL */
2557 #endif /* HAVE_POSIX_ACL */
2562 * Set the ACL of file "fname" to "acl" (unless it's NULL).
2565 mch_set_acl(fname
, aclent
)
2571 #ifdef HAVE_POSIX_ACL
2572 acl_set_file((char *)fname
, ACL_TYPE_ACCESS
, (acl_t
)aclent
);
2574 #ifdef HAVE_SOLARIS_ACL
2575 acl((char *)fname
, SETACL
, ((vim_acl_solaris_T
*)aclent
)->acl_cnt
,
2576 ((vim_acl_solaris_T
*)aclent
)->acl_entry
);
2579 chacl((char *)fname
, aclent
, ((struct acl
*)aclent
)->acl_len
);
2580 #endif /* HAVE_AIX_ACL */
2581 #endif /* HAVE_SOLARIS_ACL */
2582 #endif /* HAVE_POSIX_ACL */
2586 mch_free_acl(aclent
)
2591 #ifdef HAVE_POSIX_ACL
2592 acl_free((acl_t
)aclent
);
2594 #ifdef HAVE_SOLARIS_ACL
2595 free(((vim_acl_solaris_T
*)aclent
)->acl_entry
);
2600 #endif /* HAVE_AIX_ACL */
2601 #endif /* HAVE_SOLARIS_ACL */
2602 #endif /* HAVE_POSIX_ACL */
2607 * Set hidden flag for "name".
2614 /* can't hide a file */
2618 * return TRUE if "name" is a directory
2619 * return FALSE if "name" is not a directory
2620 * return FALSE for error
2628 if (*name
== NUL
) /* Some stat()s don't flag "" as an error. */
2630 if (stat((char *)name
, &statb
))
2632 #ifdef _POSIX_SOURCE
2633 return (S_ISDIR(statb
.st_mode
) ? TRUE
: FALSE
);
2635 return ((statb
.st_mode
& S_IFMT
) == S_IFDIR
? TRUE
: FALSE
);
2639 static int executable_file
__ARGS((char_u
*name
));
2642 * Return 1 if "name" is an executable file, 0 if not or it doesn't exist.
2645 executable_file(name
)
2650 if (stat((char *)name
, &st
))
2652 return S_ISREG(st
.st_mode
) && mch_access((char *)name
, X_OK
) == 0;
2656 * Return 1 if "name" can be found in $PATH and executed, 0 if not.
2657 * Return -1 if unknown.
2667 /* If it's an absolute or relative path don't need to use $PATH. */
2668 if (mch_isFullName(name
) || (name
[0] == '.' && (name
[1] == '/'
2669 || (name
[1] == '.' && name
[2] == '/'))))
2670 return executable_file(name
);
2672 p
= (char_u
*)getenv("PATH");
2673 if (p
== NULL
|| *p
== NUL
)
2675 buf
= alloc((unsigned)(STRLEN(name
) + STRLEN(p
) + 2));
2680 * Walk through all entries in $PATH to check if "name" exists there and
2681 * is an executable file.
2685 e
= (char_u
*)strchr((char *)p
, ':');
2688 if (e
- p
<= 1) /* empty entry means current dir */
2692 vim_strncpy(buf
, p
, e
- p
);
2696 retval
= executable_file(buf
);
2710 * Check what "name" is:
2711 * NODE_NORMAL: file or directory (or doesn't exist)
2712 * NODE_WRITABLE: writable device, socket, fifo, etc.
2713 * NODE_OTHER: non-writable things
2721 if (stat((char *)name
, &st
))
2723 if (S_ISREG(st
.st_mode
) || S_ISDIR(st
.st_mode
))
2726 if (S_ISBLK(st
.st_mode
)) /* block device isn't writable */
2729 /* Everything else is writable? */
2730 return NODE_WRITABLE
;
2736 #ifdef HAVE_CHECK_STACK_GROWTH
2739 check_stack_growth((char *)&i
);
2741 # ifdef HAVE_STACK_LIMIT
2748 * Setup an alternative stack for signals. Helps to catch signals when
2749 * running out of stack space.
2750 * Use of sigaltstack() is preferred, it's more portable.
2751 * Ignore any errors.
2753 #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
2754 signal_stack
= malloc(SIGSTKSZ
);
2755 init_signal_stack();
2759 #if defined(EXITFREE) || defined(PROTO)
2763 # if defined(FEAT_CLIPBOARD) && defined(FEAT_X11)
2764 if (clip_star
.owned
)
2765 clip_lose_selection(&clip_star
);
2766 if (clip_plus
.owned
)
2767 clip_lose_selection(&clip_plus
);
2769 # if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) || defined(PROTO)
2770 if (xterm_Shell
!= (Widget
)0)
2771 XtDestroyWidget(xterm_Shell
);
2772 if (xterm_dpy
!= NULL
)
2773 XtCloseDisplay(xterm_dpy
);
2774 if (app_context
!= (XtAppContext
)NULL
)
2775 XtDestroyApplicationContext(app_context
);
2778 if (x11_display
!= NULL
&& x11_display
!= xterm_dpy
)
2779 XCloseDisplay(x11_display
);
2781 # if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
2782 vim_free(signal_stack
);
2783 signal_stack
= NULL
;
2792 static void exit_scroll
__ARGS((void));
2795 * Output a newline when exiting.
2796 * Make sure the newline goes to the same stream as the text.
2803 if (newline_on_exit
|| msg_didout
)
2805 if (msg_use_printf())
2817 restore_cterm_colors(); /* get original colors back */
2818 msg_clr_eos_force(); /* clear the rest of the display */
2819 windgoto((int)Rows
- 1, 0); /* may have moved the cursor */
2829 #if defined(FEAT_X11) && defined(FEAT_CLIPBOARD)
2830 x11_export_final_selection();
2837 settmode(TMODE_COOK
);
2839 mch_restore_title(3); /* restore xterm title and icon name */
2842 * When t_ti is not empty but it doesn't cause swapping terminal
2843 * pages, need to output a newline when msg_didout is set. But when
2844 * t_ti does swap pages it should not go to the shell page. Do this
2845 * before stoptermcap().
2847 if (swapping_screen() && !newline_on_exit
)
2850 /* Stop termcap: May need to check for T_CRV response, which
2851 * requires RAW mode. */
2855 * A newline is only required after a message in the alternate screen.
2856 * This is set to TRUE by wait_return().
2858 if (!swapping_screen() || newline_on_exit
)
2861 /* Cursor may have been switched off without calling starttermcap()
2862 * when doing "vim -u vimrc" and vimrc contains ":q". */
2867 ml_close_all(TRUE
); /* remove all memfiles */
2874 #ifdef MACOS_CONVERT
2879 /* A core dump won't be created if the signal handler
2880 * doesn't return, so we can't call exit() */
2881 if (deadly_signal
!= 0)
2885 #ifdef FEAT_NETBEANS_INTG
2887 netbeans_send_disconnect();
2900 if (deadly_signal
!= 0)
2902 signal(deadly_signal
, SIG_DFL
);
2903 kill(getpid(), deadly_signal
); /* Die using the signal we caught */
2913 static int first
= TRUE
;
2915 /* Why is NeXT excluded here (and not in os_unixx.h)? */
2916 #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
2918 * for "new" tty systems
2920 # ifdef HAVE_TERMIOS_H
2921 static struct termios told
;
2922 struct termios tnew
;
2924 static struct termio told
;
2931 # if defined(HAVE_TERMIOS_H)
2932 tcgetattr(read_cmd_fd
, &told
);
2934 ioctl(read_cmd_fd
, TCGETA
, &told
);
2939 if (tmode
== TMODE_RAW
)
2942 * ~ICRNL enables typing ^V^M
2944 tnew
.c_iflag
&= ~ICRNL
;
2945 tnew
.c_lflag
&= ~(ICANON
| ECHO
| ISIG
| ECHOE
2946 # if defined(IEXTEN) && !defined(__MINT__)
2947 | IEXTEN
/* IEXTEN enables typing ^V on SOLARIS */
2948 /* but it breaks function keys on MINT */
2951 # ifdef ONLCR /* don't map NL -> CR NL, we do it ourselves */
2952 tnew
.c_oflag
&= ~ONLCR
;
2954 tnew
.c_cc
[VMIN
] = 1; /* return after 1 char */
2955 tnew
.c_cc
[VTIME
] = 0; /* don't wait */
2957 else if (tmode
== TMODE_SLEEP
)
2958 tnew
.c_lflag
&= ~(ECHO
);
2960 # if defined(HAVE_TERMIOS_H)
2964 /* A signal may cause tcsetattr() to fail (e.g., SIGCONT). Retry a
2966 while (tcsetattr(read_cmd_fd
, TCSANOW
, &tnew
) == -1
2967 && errno
== EINTR
&& n
> 0)
2971 ioctl(read_cmd_fd
, TCSETA
, &tnew
);
2977 * for "old" tty systems
2980 # define TIOCSETN TIOCSETP /* for hpux 9.0 */
2982 static struct sgttyb ttybold
;
2983 struct sgttyb ttybnew
;
2988 ioctl(read_cmd_fd
, TIOCGETP
, &ttybold
);
2992 if (tmode
== TMODE_RAW
)
2994 ttybnew
.sg_flags
&= ~(CRMOD
| ECHO
);
2995 ttybnew
.sg_flags
|= RAW
;
2997 else if (tmode
== TMODE_SLEEP
)
2998 ttybnew
.sg_flags
&= ~(ECHO
);
2999 ioctl(read_cmd_fd
, TIOCSETN
, &ttybnew
);
3005 * Try to get the code for "t_kb" from the stty setting
3007 * Even if termcap claims a backspace key, the user's setting *should*
3008 * prevail. stty knows more about reality than termcap does, and if
3009 * somebody's usual erase key is DEL (which, for most BSD users, it will
3010 * be), they're going to get really annoyed if their erase key starts
3011 * doing forward deletes for no reason. (Eric Fischer)
3019 /* Why is NeXT excluded here (and not in os_unixx.h)? */
3020 #if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
3021 /* for "new" tty systems */
3022 # ifdef HAVE_TERMIOS_H
3023 struct termios keys
;
3028 # if defined(HAVE_TERMIOS_H)
3029 if (tcgetattr(read_cmd_fd
, &keys
) != -1)
3031 if (ioctl(read_cmd_fd
, TCGETA
, &keys
) != -1)
3034 buf
[0] = keys
.c_cc
[VERASE
];
3035 intr_char
= keys
.c_cc
[VINTR
];
3037 /* for "old" tty systems */
3040 if (ioctl(read_cmd_fd
, TIOCGETP
, &keys
) != -1)
3042 buf
[0] = keys
.sg_erase
;
3043 intr_char
= keys
.sg_kill
;
3046 add_termcode((char_u
*)"kb", buf
, FALSE
);
3049 * If <BS> and <DEL> are now the same, redefine <DEL>.
3051 p
= find_termcode((char_u
*)"kD");
3052 if (p
!= NULL
&& p
[0] == buf
[0] && p
[1] == buf
[1])
3056 } /* to keep cindent happy */
3062 #if defined(FEAT_MOUSE_TTY) || defined(PROTO)
3064 * Set mouse clicks on or off.
3070 static int ison
= FALSE
;
3071 int xterm_mouse_vers
;
3073 if (on
== ison
) /* return quickly if nothing to do */
3076 xterm_mouse_vers
= use_xterm_mouse();
3077 if (xterm_mouse_vers
> 0)
3079 if (on
) /* enable mouse events, use mouse tracking if available */
3080 out_str_nf((char_u
*)
3081 (xterm_mouse_vers
> 1
3082 ? IF_EB("\033[?1002h", ESC_STR
"[?1002h")
3083 : IF_EB("\033[?1000h", ESC_STR
"[?1000h")));
3084 else /* disable mouse events, could probably always send the same */
3085 out_str_nf((char_u
*)
3086 (xterm_mouse_vers
> 1
3087 ? IF_EB("\033[?1002l", ESC_STR
"[?1002l")
3088 : IF_EB("\033[?1000l", ESC_STR
"[?1000l")));
3092 # ifdef FEAT_MOUSE_DEC
3093 else if (ttym_flags
== TTYM_DEC
)
3095 if (on
) /* enable mouse events */
3096 out_str_nf((char_u
*)"\033[1;2'z\033[1;3'{");
3097 else /* disable mouse events */
3098 out_str_nf((char_u
*)"\033['z");
3103 # ifdef FEAT_MOUSE_GPM
3119 # ifdef FEAT_MOUSE_JSB
3124 /* D - Enable Mouse up/down messages
3125 * L - Enable Left Button Reporting
3126 * M - Enable Middle Button Reporting
3127 * R - Enable Right Button Reporting
3128 * K - Enable SHIFT and CTRL key Reporting
3129 * + - Enable Advanced messaging of mouse moves and up/down messages
3131 * # - Numeric value of mouse pointer required
3132 * 0 = Multiview 2000 cursor, used as standard
3134 * 2 = Windows I Beam
3135 * 3 = Windows Hour Glass
3136 * 4 = Windows Cross Hair
3137 * 5 = Windows UP Arrow
3139 #ifdef JSBTERM_MOUSE_NONADVANCED /* Disables full feedback of pointer movements */
3140 out_str_nf((char_u
*)IF_EB("\033[0~ZwLMRK1Q\033\\",
3141 ESC_STR
"[0~ZwLMRK1Q" ESC_STR
"\\"));
3143 out_str_nf((char_u
*)IF_EB("\033[0~ZwLMRK+1Q\033\\",
3144 ESC_STR
"[0~ZwLMRK+1Q" ESC_STR
"\\"));
3150 out_str_nf((char_u
*)IF_EB("\033[0~ZwQ\033\\",
3151 ESC_STR
"[0~ZwQ" ESC_STR
"\\"));
3156 # ifdef FEAT_MOUSE_PTERM
3159 /* 1 = button press, 6 = release, 7 = drag, 1h...9l = right button */
3161 out_str_nf("\033[>1h\033[>6h\033[>7h\033[>1h\033[>9l");
3163 out_str_nf("\033[>1l\033[>6l\033[>7l\033[>1l\033[>9h");
3170 * Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
3173 check_mouse_termcode()
3175 # ifdef FEAT_MOUSE_XTERM
3176 if (use_xterm_mouse()
3182 set_mouse_termcode(KS_MOUSE
, (char_u
*)(term_is_8bit(T_NAME
)
3183 ? IF_EB("\233M", CSI_STR
"M")
3184 : IF_EB("\033[M", ESC_STR
"[M")));
3185 if (*p_mouse
!= NUL
)
3187 /* force mouse off and maybe on to send possibly new mouse
3188 * activation sequence to the xterm, with(out) drag tracing. */
3189 mch_setmouse(FALSE
);
3194 del_mouse_termcode(KS_MOUSE
);
3197 # ifdef FEAT_MOUSE_GPM
3198 if (!use_xterm_mouse()
3203 set_mouse_termcode(KS_MOUSE
, (char_u
*)IF_EB("\033MG", ESC_STR
"MG"));
3206 # ifdef FEAT_MOUSE_JSB
3207 /* conflicts with xterm mouse: "\033[" and "\033[M" ??? */
3208 if (!use_xterm_mouse()
3213 set_mouse_termcode(KS_JSBTERM_MOUSE
,
3214 (char_u
*)IF_EB("\033[0~zw", ESC_STR
"[0~zw"));
3216 del_mouse_termcode(KS_JSBTERM_MOUSE
);
3219 # ifdef FEAT_MOUSE_NET
3220 /* There is no conflict, but one may type "ESC }" from Insert mode. Don't
3221 * define it in the GUI or when using an xterm. */
3222 if (!use_xterm_mouse()
3227 set_mouse_termcode(KS_NETTERM_MOUSE
,
3228 (char_u
*)IF_EB("\033}", ESC_STR
"}"));
3230 del_mouse_termcode(KS_NETTERM_MOUSE
);
3233 # ifdef FEAT_MOUSE_DEC
3234 /* conflicts with xterm mouse: "\033[" and "\033[M" */
3235 if (!use_xterm_mouse()
3240 set_mouse_termcode(KS_DEC_MOUSE
, (char_u
*)(term_is_8bit(T_NAME
)
3241 ? IF_EB("\233", CSI_STR
) : IF_EB("\033[", ESC_STR
"[")));
3243 del_mouse_termcode(KS_DEC_MOUSE
);
3245 # ifdef FEAT_MOUSE_PTERM
3246 /* same as the dec mouse */
3247 if (!use_xterm_mouse()
3252 set_mouse_termcode(KS_PTERM_MOUSE
,
3253 (char_u
*) IF_EB("\033[", ESC_STR
"["));
3255 del_mouse_termcode(KS_PTERM_MOUSE
);
3261 * set screen mode, always fails.
3268 EMSG(_(e_screenmode
));
3275 * Try to get the current window size:
3276 * 1. with an ioctl(), most accurate method
3277 * 2. from the environment variables LINES and COLUMNS
3278 * 3. from the termcap
3279 * 4. keep using the old values
3280 * Return OK when size could be determined, FAIL otherwise.
3290 * For OS/2 use _scrsize().
3303 * 1. try using an ioctl. It is the most accurate method.
3305 * Try using TIOCGWINSZ first, some systems that have it also define
3306 * TIOCGSIZE but don't have a struct ttysize.
3313 /* When stdout is not a tty, use stdin for the ioctl(). */
3314 if (!isatty(fd
) && isatty(read_cmd_fd
))
3316 if (ioctl(fd
, TIOCGWINSZ
, &ws
) == 0)
3318 columns
= ws
.ws_col
;
3322 # else /* TIOCGWINSZ */
3328 /* When stdout is not a tty, use stdin for the ioctl(). */
3329 if (!isatty(fd
) && isatty(read_cmd_fd
))
3331 if (ioctl(fd
, TIOCGSIZE
, &ts
) == 0)
3333 columns
= ts
.ts_cols
;
3337 # endif /* TIOCGSIZE */
3338 # endif /* TIOCGWINSZ */
3341 * 2. get size from environment
3342 * When being POSIX compliant ('|' flag in 'cpoptions') this overrules
3343 * the ioctl() values!
3345 if (columns
== 0 || rows
== 0 || vim_strchr(p_cpo
, CPO_TSIZE
) != NULL
)
3347 if ((p
= (char_u
*)getenv("LINES")))
3348 rows
= atoi((char *)p
);
3349 if ((p
= (char_u
*)getenv("COLUMNS")))
3350 columns
= atoi((char *)p
);
3355 * 3. try reading "co" and "li" entries from termcap
3357 if (columns
== 0 || rows
== 0)
3358 getlinecol(&columns
, &rows
);
3362 * 4. If everything fails, use the old values
3364 if (columns
<= 0 || rows
<= 0)
3373 * Try to set the window size to Rows and Columns.
3381 * NOTE: if you get an error here that term_set_winsize() is
3382 * undefined, check the output of configure. It could probably not
3383 * find a ncurses, termcap or termlib library.
3385 term_set_winsize((int)Rows
, (int)Columns
);
3387 screen_start(); /* don't know where cursor is now */
3394 * Rows and/or Columns has changed.
3399 /* Nothing to do. */
3403 static void append_ga_line
__ARGS((garray_T
*gap
));
3406 * Append the text in "gap" below the cursor line and clear "gap".
3412 /* Remove trailing CR. */
3415 && ((char_u
*)gap
->ga_data
)[gap
->ga_len
- 1] == CAR
)
3417 ga_append(gap
, NUL
);
3418 ml_append(curwin
->w_cursor
.lnum
++, gap
->ga_data
, 0, FALSE
);
3424 mch_call_shell(cmd
, options
)
3426 int options
; /* SHELL_*, see vim.h */
3432 int tmode
= cur_tmode
;
3433 #ifdef USE_SYSTEM /* use system() to start the shell: simple but slow */
3436 char_u
*newcmd
; /* only needed for unix */
3439 * Set the preferred shell in the EMXSHELL environment variable (but
3440 * only if it is different from what is already in the environment).
3441 * Emx then takes care of whether to use "/c" or "-c" in an
3442 * intelligent way. Simply pass the whole thing to emx's system() call.
3443 * Emx also starts an interactive shell if system() is passed an empty
3448 if (((old
= (char_u
*)getenv("EMXSHELL")) == NULL
) || STRCMP(old
, p_sh
))
3450 /* should check HAVE_SETENV, but I know we don't have it. */
3451 p
= alloc(10 + strlen(p_sh
));
3454 sprintf((char *)p
, "EMXSHELL=%s", p_sh
);
3455 putenv((char *)p
); /* don't free the pointer! */
3462 if (options
& SHELL_COOKED
)
3463 settmode(TMODE_COOK
); /* set to normal mode */
3467 x
= system(""); /* this starts an interactive shell in emx */
3469 x
= system((char *)cmd
);
3470 /* system() returns -1 when error occurs in starting shell */
3471 if (x
== -1 && !emsg_silent
)
3473 MSG_PUTS(_("\nCannot execute shell "));
3477 # else /* not __EMX__ */
3479 x
= system((char *)p_sh
);
3483 if (ofn
= strchr((char *)cmd
, '>'))
3485 if (ifn
= strchr((char *)cmd
, '<'))
3490 p
= strchr(ifn
,' '); /* chop off any trailing spaces */
3495 x
= vms_sys((char *)cmd
, ofn
, ifn
);
3497 x
= system((char *)cmd
);
3499 newcmd
= lalloc(STRLEN(p_sh
)
3500 + (extra_shell_arg
== NULL
? 0 : STRLEN(extra_shell_arg
))
3501 + STRLEN(p_shcf
) + STRLEN(cmd
) + 4, TRUE
);
3506 sprintf((char *)newcmd
, "%s %s %s %s", p_sh
,
3507 extra_shell_arg
== NULL
? "" : (char *)extra_shell_arg
,
3510 x
= system((char *)newcmd
);
3516 x
= vms_sys_status(x
);
3521 MSG_PUTS(_("\nCannot execute shell sh\n"));
3522 # endif /* __EMX__ */
3523 else if (x
&& !(options
& SHELL_SILENT
))
3525 MSG_PUTS(_("\nshell returned "));
3526 msg_outnum((long)x
);
3530 if (tmode
== TMODE_RAW
)
3531 settmode(TMODE_RAW
); /* set to raw mode */
3537 #else /* USE_SYSTEM */ /* don't use system(), use fork()/exec() */
3539 # define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
3540 127, some shells use that already */
3542 char_u
*newcmd
= NULL
;
3546 # ifdef HAVE_UNION_WAIT
3557 int pty_master_fd
= -1; /* for pty's */
3559 int pty_slave_fd
= -1;
3562 int fd_toshell
[2]; /* for pipes */
3563 int fd_fromshell
[2];
3564 int pipe_error
= FALSE
;
3568 static char envbuf_Rows
[20];
3569 static char envbuf_Columns
[20];
3571 int did_settmode
= FALSE
; /* settmode(TMODE_RAW) called */
3574 if (options
& SHELL_COOKED
)
3575 settmode(TMODE_COOK
); /* set to normal mode */
3577 newcmd
= vim_strsave(p_sh
);
3578 if (newcmd
== NULL
) /* out of memory */
3582 * Do this loop twice:
3583 * 1: find number of arguments
3584 * 2: separate them and build argv[]
3586 for (i
= 0; i
< 2; ++i
)
3594 argv
[argc
] = (char *)p
;
3596 while (*p
&& (inquote
|| (*p
!= ' ' && *p
!= TAB
)))
3610 argv
= (char **)alloc((unsigned)((argc
+ 4) * sizeof(char *)));
3611 if (argv
== NULL
) /* out of memory */
3617 if (extra_shell_arg
!= NULL
)
3618 argv
[argc
++] = (char *)extra_shell_arg
;
3619 argv
[argc
++] = (char *)p_shcf
;
3620 argv
[argc
++] = (char *)cmd
;
3625 * For the GUI, when writing the output into the buffer and when reading
3626 * input from the buffer: Try using a pseudo-tty to get the stdin/stdout
3627 * of the executed command into the Vim window. Or use a pipe.
3629 if ((options
& (SHELL_READ
|SHELL_WRITE
))
3631 || (gui
.in_use
&& show_shell_mess
)
3637 * Try to open a master pty.
3638 * If this works, open the slave pty.
3639 * If the slave can't be opened, close the master pty.
3641 if (p_guipty
&& !(options
& (SHELL_READ
|SHELL_WRITE
)))
3643 pty_master_fd
= OpenPTY(&tty_name
); /* open pty */
3644 if (pty_master_fd
>= 0 && ((pty_slave_fd
=
3645 open(tty_name
, O_RDWR
| O_EXTRA
, 0)) < 0))
3647 close(pty_master_fd
);
3652 * If not opening a pty or it didn't work, try using pipes.
3654 if (pty_master_fd
< 0)
3657 pipe_error
= (pipe(fd_toshell
) < 0);
3658 if (!pipe_error
) /* pipe create OK */
3660 pipe_error
= (pipe(fd_fromshell
) < 0);
3661 if (pipe_error
) /* pipe create failed */
3663 close(fd_toshell
[0]);
3664 close(fd_toshell
[1]);
3669 MSG_PUTS(_("\nCannot create pipes\n"));
3675 if (!pipe_error
) /* pty or pipe opened or not used */
3678 beos_cleanup_read_thread();
3681 if ((pid
= fork()) == -1) /* maybe we should use vfork() */
3683 MSG_PUTS(_("\nCannot fork\n"));
3684 if ((options
& (SHELL_READ
|SHELL_WRITE
))
3686 || (gui
.in_use
&& show_shell_mess
)
3691 if (pty_master_fd
>= 0) /* close the pseudo tty */
3693 close(pty_master_fd
);
3694 close(pty_slave_fd
);
3696 else /* close the pipes */
3699 close(fd_toshell
[0]);
3700 close(fd_toshell
[1]);
3701 close(fd_fromshell
[0]);
3702 close(fd_fromshell
[1]);
3706 else if (pid
== 0) /* child */
3708 reset_signals(); /* handle signals normally */
3710 if (!show_shell_mess
|| (options
& SHELL_EXPAND
))
3715 * Don't want to show any message from the shell. Can't just
3716 * close stdout and stderr though, because some systems will
3717 * break if you try to write to them after that, so we must
3718 * use dup() to replace them with something else -- webb
3719 * Connect stdin to /dev/null too, so ":n `cat`" doesn't hang,
3720 * waiting for input.
3722 fd
= open("/dev/null", O_RDWR
| O_EXTRA
, 0);
3728 * If any of these open()'s and dup()'s fail, we just continue
3729 * anyway. It's not fatal, and on most systems it will make
3730 * no difference at all. On a few it will cause the execvp()
3731 * to exit with a non-zero status even when the completion
3732 * could be done, which is nothing too serious. If the open()
3733 * or dup() failed we'd just do the same thing ourselves
3738 dup(fd
); /* To replace stdin (file descriptor 0) */
3739 dup(fd
); /* To replace stdout (file descriptor 1) */
3740 dup(fd
); /* To replace stderr (file descriptor 2) */
3742 /* Don't need this now that we've duplicated it */
3746 else if ((options
& (SHELL_READ
|SHELL_WRITE
))
3754 /* Create our own process group, so that the child and all its
3755 * children can be kill()ed. Don't do this when using pipes,
3756 * because stdin is not a tty, we would loose /dev/tty. */
3761 if (pty_slave_fd
>= 0)
3763 /* push stream discipline modules */
3764 if (options
& SHELL_COOKED
)
3765 SetupSlavePTY(pty_slave_fd
);
3767 /* Try to become controlling tty (probably doesn't work,
3768 * unless run by root) */
3769 ioctl(pty_slave_fd
, TIOCSCTTY
, (char *)NULL
);
3773 /* Simulate to have a dumb terminal (for now) */
3775 setenv("TERM", "dumb", 1);
3776 sprintf((char *)envbuf
, "%ld", Rows
);
3777 setenv("ROWS", (char *)envbuf
, 1);
3778 sprintf((char *)envbuf
, "%ld", Rows
);
3779 setenv("LINES", (char *)envbuf
, 1);
3780 sprintf((char *)envbuf
, "%ld", Columns
);
3781 setenv("COLUMNS", (char *)envbuf
, 1);
3784 * Putenv does not copy the string, it has to remain valid.
3785 * Use a static array to avoid loosing allocated memory.
3787 putenv("TERM=dumb");
3788 sprintf(envbuf_Rows
, "ROWS=%ld", Rows
);
3789 putenv(envbuf_Rows
);
3790 sprintf(envbuf_Rows
, "LINES=%ld", Rows
);
3791 putenv(envbuf_Rows
);
3792 sprintf(envbuf_Columns
, "COLUMNS=%ld", Columns
);
3793 putenv(envbuf_Columns
);
3797 * stderr is only redirected when using the GUI, so that a
3798 * program like gpg can still access the terminal to get a
3799 * passphrase using stderr.
3802 if (pty_master_fd
>= 0)
3804 close(pty_master_fd
); /* close master side of pty */
3806 /* set up stdin/stdout/stderr for the child */
3817 close(pty_slave_fd
); /* has been dupped, close it now */
3822 /* set up stdin for the child */
3823 close(fd_toshell
[1]);
3826 close(fd_toshell
[0]);
3828 /* set up stdout for the child */
3829 close(fd_fromshell
[0]);
3831 dup(fd_fromshell
[1]);
3832 close(fd_fromshell
[1]);
3837 /* set up stderr for the child */
3846 * There is no type cast for the argv, because the type may be
3847 * different on different machines. This may cause a warning
3848 * message with strict compilers, don't worry about it.
3849 * Call _exit() instead of exit() to avoid closing the connection
3850 * to the X server (esp. with GTK, which uses atexit()).
3852 execvp(argv
[0], argv
);
3853 _exit(EXEC_FAILED
); /* exec failed, return failure code */
3858 * While child is running, ignore terminating signals.
3859 * Do catch CTRL-C, so that "got_int" is set.
3861 catch_signals(SIG_IGN
, SIG_ERR
);
3865 * For the GUI we redirect stdin, stdout and stderr to our window.
3866 * This is also used to pipe stdin/stdout to/from the external
3869 if ((options
& (SHELL_READ
|SHELL_WRITE
))
3871 || (gui
.in_use
&& show_shell_mess
)
3875 # define BUFLEN 100 /* length for buffer, pseudo tty limit is 128 */
3876 char_u buffer
[BUFLEN
+ 1];
3878 int buffer_off
= 0; /* valid bytes in buffer[] */
3880 char_u ta_buf
[BUFLEN
+ 1]; /* TypeAHead */
3881 int ta_len
= 0; /* valid bytes in ta_buf[] */
3892 if (pty_master_fd
>= 0)
3894 close(pty_slave_fd
); /* close slave side of pty */
3895 fromshell_fd
= pty_master_fd
;
3896 toshell_fd
= dup(pty_master_fd
);
3901 close(fd_toshell
[0]);
3902 close(fd_fromshell
[1]);
3903 toshell_fd
= fd_toshell
[1];
3904 fromshell_fd
= fd_fromshell
[0];
3908 * Write to the child if there are typed characters.
3909 * Read from the child if there are characters available.
3910 * Repeat the reading a few times if more characters are
3911 * available. Need to check for typed keys now and then, but
3912 * not too often (delays when no chars are available).
3913 * This loop is quit if no characters can be read from the pty
3914 * (WaitForChar detected special condition), or there are no
3915 * characters available and the child has exited.
3916 * Only check if the child has exited when there is no more
3917 * output. The child may exit before all the output has
3920 * Currently this busy loops!
3921 * This can probably dead-lock when the write blocks!
3923 p_more_save
= p_more
;
3926 State
= EXTERNCMD
; /* don't redraw at window resize */
3928 if ((options
& SHELL_WRITE
) && toshell_fd
>= 0)
3930 /* Fork a process that will write the lines to the
3931 * external program. */
3932 if ((wpid
= fork()) == -1)
3934 MSG_PUTS(_("\nCannot fork\n"));
3938 linenr_T lnum
= curbuf
->b_op_start
.lnum
;
3940 char_u
*lp
= ml_get(lnum
);
3945 close(fromshell_fd
);
3948 l
= STRLEN(lp
+ written
);
3951 else if (lp
[written
] == NL
)
3952 /* NL -> NUL translation */
3953 len
= write(toshell_fd
, "", (size_t)1);
3956 s
= vim_strchr(lp
+ written
, NL
);
3957 len
= write(toshell_fd
, (char *)lp
+ written
,
3958 s
== NULL
? l
: s
- (lp
+ written
));
3962 /* Finished a line, add a NL, unless this line
3963 * should not have one. */
3964 if (lnum
!= curbuf
->b_op_end
.lnum
3966 || (lnum
!= write_no_eol_lnum
3968 curbuf
->b_ml
.ml_line_count
3969 || curbuf
->b_p_eol
)))
3970 write(toshell_fd
, "\n", (size_t)1);
3972 if (lnum
> curbuf
->b_op_end
.lnum
)
3974 /* finished all the lines, close pipe */
3994 if (options
& SHELL_READ
)
3995 ga_init2(&ga
, 1, BUFLEN
);
4002 * Check if keys have been typed, write them to the child
4004 * Don't do this if we are expanding wild cards (would eat
4006 * Don't do this when filtering and terminal is in cooked
4007 * mode, the shell command will handle the I/O. Avoids
4008 * that a typed password is echoed for ssh or gpg command.
4009 * Don't get characters when the child has already
4010 * finished (wait_pid == 0).
4011 * Don't get extra characters when we already have one.
4012 * Don't read characters unless we didn't get output for a
4013 * while, avoids that ":r !ls" eats typeahead.
4016 if (!(options
& SHELL_EXPAND
)
4018 (SHELL_READ
|SHELL_WRITE
|SHELL_COOKED
))
4019 != (SHELL_READ
|SHELL_WRITE
|SHELL_COOKED
)
4027 && (len
= ui_inchar(ta_buf
,
4028 BUFLEN
, 10L, 0)) > 0)))
4032 * Check for CTRL-C: send interrupt signal to child.
4033 * Check for CTRL-D: EOF, close pipe to child.
4035 if (len
== 1 && (pty_master_fd
< 0 || cmd
!= NULL
))
4039 * Send SIGINT to the child's group or all
4040 * processes in our group.
4042 if (ta_buf
[ta_len
] == Ctrl_C
4043 || ta_buf
[ta_len
] == intr_char
)
4054 if (pty_master_fd
< 0 && toshell_fd
>= 0
4055 && ta_buf
[ta_len
] == Ctrl_D
)
4062 /* replace K_BS by <BS> and K_DEL by <DEL> */
4063 for (i
= ta_len
; i
< ta_len
+ len
; ++i
)
4065 if (ta_buf
[i
] == CSI
&& len
- i
> 2)
4067 c
= TERMCAP2KEY(ta_buf
[i
+ 1], ta_buf
[i
+ 2]);
4068 if (c
== K_DEL
|| c
== K_KDEL
|| c
== K_BS
)
4070 mch_memmove(ta_buf
+ i
+ 1, ta_buf
+ i
+ 3,
4071 (size_t)(len
- i
- 2));
4072 if (c
== K_DEL
|| c
== K_KDEL
)
4079 else if (ta_buf
[i
] == '\r')
4083 i
+= (*mb_ptr2len
)(ta_buf
+ i
) - 1;
4088 * For pipes: echo the typed characters.
4089 * For a pty this does not seem to work.
4091 if (pty_master_fd
< 0)
4093 for (i
= ta_len
; i
< ta_len
+ len
; ++i
)
4095 if (ta_buf
[i
] == '\n' || ta_buf
[i
] == '\b')
4096 msg_putchar(ta_buf
[i
]);
4100 int l
= (*mb_ptr2len
)(ta_buf
+ i
);
4102 msg_outtrans_len(ta_buf
+ i
, l
);
4107 msg_outtrans_len(ta_buf
+ i
, 1);
4109 windgoto(msg_row
, msg_col
);
4116 * Write the characters to the child, unless EOF has
4117 * been typed for pipes. Write one character at a
4118 * time, to avoid loosing too much typeahead.
4119 * When writing buffer lines, drop the typed
4120 * characters (only check for CTRL-C).
4122 if (options
& SHELL_WRITE
)
4124 else if (toshell_fd
>= 0)
4126 len
= write(toshell_fd
, (char *)ta_buf
, (size_t)1);
4130 mch_memmove(ta_buf
, ta_buf
+ len
, ta_len
);
4138 /* CTRL-C sends a signal to the child, we ignore it
4151 * Check if the child has any characters to be printed.
4152 * Read them and write them to our window. Repeat this as
4153 * long as there is something to do, avoid the 10ms wait
4154 * for mch_inchar(), or sending typeahead characters to
4155 * the external process.
4156 * TODO: This should handle escape sequences, compatible
4157 * to some terminal (vt52?).
4160 while (RealWaitForChar(fromshell_fd
, 10L, NULL
))
4162 len
= read(fromshell_fd
, (char *)buffer
4164 + buffer_off
, (size_t)(BUFLEN
- buffer_off
)
4169 if (len
<= 0) /* end of file or error */
4173 if (options
& SHELL_READ
)
4175 /* Do NUL -> NL translation, append NL separated
4176 * lines to the current buffer. */
4177 for (i
= 0; i
< len
; ++i
)
4179 if (buffer
[i
] == NL
)
4180 append_ga_line(&ga
);
4181 else if (buffer
[i
] == NUL
)
4184 ga_append(&ga
, buffer
[i
]);
4195 /* Check if the last character in buffer[] is
4196 * incomplete, keep these bytes for the next
4198 for (p
= buffer
; p
< buffer
+ len
; p
+= l
)
4202 l
= 1; /* NUL byte? */
4203 else if (MB_BYTE2LEN(*p
) != l
)
4206 if (p
== buffer
) /* no complete character */
4208 /* avoid getting stuck at an illegal byte */
4220 if (p
< buffer
+ len
)
4223 buffer_off
= (buffer
+ len
) - p
;
4224 mch_memmove(buffer
, p
, buffer_off
);
4229 # endif /* FEAT_MBYTE */
4236 windgoto(msg_row
, msg_col
);
4243 /* If we already detected the child has finished break the
4245 if (wait_pid
== pid
)
4249 * Check if the child still exists, before checking for
4250 * typed characters (otherwise we would loose typeahead).
4253 wait_pid
= wait4(pid
, &status
, WNOHANG
, (struct rusage
*) 0);
4255 wait_pid
= waitpid(pid
, &status
, WNOHANG
);
4257 if ((wait_pid
== (pid_t
)-1 && errno
== ECHILD
)
4258 || (wait_pid
== pid
&& WIFEXITED(status
)))
4260 /* Don't break the loop yet, try reading more
4261 * characters from "fromshell_fd" first. When using
4262 * pipes there might still be something to read and
4263 * then we'll break the loop at the "break" above. */
4270 p_more
= p_more_save
;
4271 if (options
& SHELL_READ
)
4275 append_ga_line(&ga
);
4276 /* remember that the NL was missing */
4277 write_no_eol_lnum
= curwin
->w_cursor
.lnum
;
4280 write_no_eol_lnum
= 0;
4285 * Give all typeahead that wasn't used back to ui_inchar().
4288 ui_inchar_undo(ta_buf
, ta_len
);
4290 if (toshell_fd
>= 0)
4292 close(fromshell_fd
);
4296 * Wait until our child has exited.
4297 * Ignore wait() returning pids of other children and returning
4298 * because of some signal like SIGWINCH.
4299 * Don't wait if wait_pid was already set above, indicating the
4300 * child already exited.
4302 while (wait_pid
!= pid
)
4304 # ifdef _THREAD_SAFE
4305 /* Ugly hack: when compiled with Python threads are probably
4306 * used, in which case wait() sometimes hangs for no obvious
4307 * reason. Use waitpid() instead and loop (like the GUI). */
4309 wait_pid
= wait4(pid
, &status
, WNOHANG
, (struct rusage
*)0);
4311 wait_pid
= waitpid(pid
, &status
, WNOHANG
);
4315 /* Wait for 1/100 sec before trying again. */
4316 mch_delay(10L, TRUE
);
4320 wait_pid
= wait(&status
);
4330 /* Make sure the child that writes to the external program is
4333 kill(wpid
, SIGKILL
);
4336 * Set to raw mode right now, otherwise a CTRL-C after
4337 * catch_signals() will kill Vim.
4339 if (tmode
== TMODE_RAW
)
4340 settmode(TMODE_RAW
);
4341 did_settmode
= TRUE
;
4344 if (WIFEXITED(status
))
4346 /* LINTED avoid "bitwise operation on signed value" */
4347 retval
= WEXITSTATUS(status
);
4348 if (retval
&& !emsg_silent
)
4350 if (retval
== EXEC_FAILED
)
4352 MSG_PUTS(_("\nCannot execute shell "));
4356 else if (!(options
& SHELL_SILENT
))
4358 MSG_PUTS(_("\nshell returned "));
4359 msg_outnum((long)retval
);
4365 MSG_PUTS(_("\nCommand terminated\n"));
4372 if (tmode
== TMODE_RAW
)
4373 settmode(TMODE_RAW
); /* set to raw mode */
4381 #endif /* USE_SYSTEM */
4385 * Check for CTRL-C typed by reading all available characters.
4386 * In cooked mode we should get SIGINT, no need to check.
4391 if (curr_tmode
== TMODE_RAW
&& RealWaitForChar(read_cmd_fd
, 0L, NULL
))
4392 fill_input_buf(FALSE
);
4396 * Wait "msec" msec until a character is available from the keyboard or from
4397 * inbuf[]. msec == -1 will block forever.
4398 * When a GUI is being used, this will never get called -- webb
4404 #ifdef FEAT_MOUSE_GPM
4405 int gpm_process_wanted
;
4407 #ifdef FEAT_XCLIPBOARD
4412 if (input_available()) /* something in inbuf[] */
4415 #if defined(FEAT_MOUSE_DEC)
4416 /* May need to query the mouse position. */
4419 WantQueryMouse
= FALSE
;
4420 mch_write((char_u
*)IF_EB("\033[1'|", ESC_STR
"[1'|"), 5);
4425 * For FEAT_MOUSE_GPM and FEAT_XCLIPBOARD we loop here to process mouse
4426 * events. This is a bit complicated, because they might both be defined.
4428 #if defined(FEAT_MOUSE_GPM) || defined(FEAT_XCLIPBOARD)
4429 # ifdef FEAT_XCLIPBOARD
4431 if (do_xterm_trace())
4436 # ifdef FEAT_XCLIPBOARD
4439 msec
= XT_TRACE_DELAY
;
4440 if (rest
>= 0 && rest
< XT_TRACE_DELAY
)
4446 # ifdef FEAT_MOUSE_GPM
4447 gpm_process_wanted
= 0;
4448 avail
= RealWaitForChar(read_cmd_fd
, msec
, &gpm_process_wanted
);
4450 avail
= RealWaitForChar(read_cmd_fd
, msec
, NULL
);
4454 if (input_available())
4456 # ifdef FEAT_XCLIPBOARD
4457 if (rest
== 0 || !do_xterm_trace())
4463 # ifdef FEAT_MOUSE_GPM
4464 || (gpm_process_wanted
&& mch_gpm_process() == 0)
4466 # ifdef FEAT_XCLIPBOARD
4467 || (!avail
&& rest
!= 0)
4472 avail
= RealWaitForChar(read_cmd_fd
, msec
, NULL
);
4478 * Wait "msec" msec until a character is available from file descriptor "fd".
4479 * Time == -1 will block forever.
4480 * When a GUI is being used, this will not be used for input -- webb
4481 * Returns also, when a request from Sniff is waiting -- toni.
4482 * Or when a Linux GPM mouse event is waiting.
4485 #if defined(__BEOS__)
4490 RealWaitForChar(fd
, msec
, check_for_gpm
)
4496 #if defined(FEAT_XCLIPBOARD) || defined(USE_XSMP) || defined(FEAT_MZSCHEME)
4497 static int busy
= FALSE
;
4499 /* May retry getting characters after an event was handled. */
4502 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
4503 /* Remember at what time we started, so that we know how much longer we
4504 * should wait after being interrupted. */
4505 # define USE_START_TV
4506 struct timeval start_tv
;
4509 # ifdef FEAT_XCLIPBOARD
4510 xterm_Shell
!= (Widget
)0
4511 # if defined(USE_XSMP) || defined(FEAT_MZSCHEME)
4517 # ifdef FEAT_MZSCHEME
4521 # ifdef FEAT_MZSCHEME
4522 (mzthreads_allowed() && p_mzq
> 0)
4525 gettimeofday(&start_tv
, NULL
);
4528 /* Handle being called recursively. This may happen for the session
4529 * manager stuff, it may save the file, which does a breakcheck. */
4539 int finished
= TRUE
; /* default is to 'loop' just once */
4540 # ifdef FEAT_MZSCHEME
4541 int mzquantum_used
= FALSE
;
4545 struct pollfd fds
[5];
4547 # ifdef FEAT_XCLIPBOARD
4550 # ifdef FEAT_MOUSE_GPM
4556 int towait
= (int)msec
;
4558 # ifdef FEAT_MZSCHEME
4559 mzvim_check_threads();
4560 if (mzthreads_allowed() && p_mzq
> 0 && (msec
< 0 || msec
> p_mzq
))
4562 towait
= (int)p_mzq
; /* don't wait longer than 'mzquantum' */
4563 mzquantum_used
= TRUE
;
4567 fds
[0].events
= POLLIN
;
4571 # define SNIFF_IDX 1
4572 if (want_sniff_request
)
4574 fds
[SNIFF_IDX
].fd
= fd_from_sniff
;
4575 fds
[SNIFF_IDX
].events
= POLLIN
;
4579 # ifdef FEAT_XCLIPBOARD
4580 if (xterm_Shell
!= (Widget
)0)
4583 fds
[nfd
].fd
= ConnectionNumber(xterm_dpy
);
4584 fds
[nfd
].events
= POLLIN
;
4588 # ifdef FEAT_MOUSE_GPM
4589 if (check_for_gpm
!= NULL
&& gpm_flag
&& gpm_fd
>= 0)
4592 fds
[nfd
].fd
= gpm_fd
;
4593 fds
[nfd
].events
= POLLIN
;
4598 if (xsmp_icefd
!= -1)
4601 fds
[nfd
].fd
= xsmp_icefd
;
4602 fds
[nfd
].events
= POLLIN
;
4607 ret
= poll(fds
, nfd
, towait
);
4608 # ifdef FEAT_MZSCHEME
4609 if (ret
== 0 && mzquantum_used
)
4610 /* MzThreads scheduling is required and timeout occured */
4616 sniff_disconnect(1);
4617 else if (want_sniff_request
)
4619 if (fds
[SNIFF_IDX
].revents
& POLLHUP
)
4620 sniff_disconnect(1);
4621 if (fds
[SNIFF_IDX
].revents
& POLLIN
)
4622 sniff_request_waiting
= 1;
4625 # ifdef FEAT_XCLIPBOARD
4626 if (xterm_Shell
!= (Widget
)0 && (fds
[xterm_idx
].revents
& POLLIN
))
4628 xterm_update(); /* Maybe we should hand out clipboard */
4629 if (--ret
== 0 && !input_available())
4634 # ifdef FEAT_MOUSE_GPM
4635 if (gpm_idx
>= 0 && (fds
[gpm_idx
].revents
& POLLIN
))
4641 if (xsmp_idx
>= 0 && (fds
[xsmp_idx
].revents
& (POLLIN
| POLLHUP
)))
4643 if (fds
[xsmp_idx
].revents
& POLLIN
)
4646 xsmp_handle_requests();
4649 else if (fds
[xsmp_idx
].revents
& POLLHUP
)
4652 verb_msg((char_u
*)_("XSMP lost ICE connection"));
4656 finished
= FALSE
; /* Try again */
4661 #else /* HAVE_SELECT */
4664 struct timeval
*tvp
;
4669 # ifdef FEAT_MZSCHEME
4670 mzvim_check_threads();
4671 if (mzthreads_allowed() && p_mzq
> 0 && (msec
< 0 || msec
> p_mzq
))
4673 towait
= p_mzq
; /* don't wait longer than 'mzquantum' */
4674 mzquantum_used
= TRUE
;
4678 /* don't check for incoming chars if not in raw mode, because select()
4679 * always returns TRUE then (in some version of emx.dll) */
4680 if (curr_tmode
!= TMODE_RAW
)
4686 tv
.tv_sec
= towait
/ 1000;
4687 tv
.tv_usec
= (towait
% 1000) * (1000000/1000);
4694 * Select on ready for reading and exceptional condition (end of file).
4696 FD_ZERO(&rfds
); /* calls bzero() on a sun */
4699 # if !defined(__QNX__) && !defined(__CYGWIN32__)
4700 /* For QNX select() always returns 1 if this is set. Why? */
4706 if (want_sniff_request
)
4708 FD_SET(fd_from_sniff
, &rfds
);
4709 FD_SET(fd_from_sniff
, &efds
);
4710 if (maxfd
< fd_from_sniff
)
4711 maxfd
= fd_from_sniff
;
4714 # ifdef FEAT_XCLIPBOARD
4715 if (xterm_Shell
!= (Widget
)0)
4717 FD_SET(ConnectionNumber(xterm_dpy
), &rfds
);
4718 if (maxfd
< ConnectionNumber(xterm_dpy
))
4719 maxfd
= ConnectionNumber(xterm_dpy
);
4722 # ifdef FEAT_MOUSE_GPM
4723 if (check_for_gpm
!= NULL
&& gpm_flag
&& gpm_fd
>= 0)
4725 FD_SET(gpm_fd
, &rfds
);
4726 FD_SET(gpm_fd
, &efds
);
4732 if (xsmp_icefd
!= -1)
4734 FD_SET(xsmp_icefd
, &rfds
);
4735 FD_SET(xsmp_icefd
, &efds
);
4736 if (maxfd
< xsmp_icefd
)
4742 /* Old VMS as v6.2 and older have broken select(). It waits more than
4743 * required. Should not be used */
4746 ret
= select(maxfd
+ 1, &rfds
, NULL
, &efds
, tvp
);
4749 if (ret
== -1 && errno
== ENOTSUP
)
4756 # ifdef FEAT_MZSCHEME
4757 if (ret
== 0 && mzquantum_used
)
4758 /* loop if MzThreads must be scheduled and timeout occured */
4764 sniff_disconnect(1);
4765 else if (ret
> 0 && want_sniff_request
)
4767 if (FD_ISSET(fd_from_sniff
, &efds
))
4768 sniff_disconnect(1);
4769 if (FD_ISSET(fd_from_sniff
, &rfds
))
4770 sniff_request_waiting
= 1;
4773 # ifdef FEAT_XCLIPBOARD
4774 if (ret
> 0 && xterm_Shell
!= (Widget
)0
4775 && FD_ISSET(ConnectionNumber(xterm_dpy
), &rfds
))
4777 xterm_update(); /* Maybe we should hand out clipboard */
4778 /* continue looping when we only got the X event and the input
4779 * buffer is empty */
4780 if (--ret
== 0 && !input_available())
4787 # ifdef FEAT_MOUSE_GPM
4788 if (ret
> 0 && gpm_flag
&& check_for_gpm
!= NULL
&& gpm_fd
>= 0)
4790 if (FD_ISSET(gpm_fd
, &efds
))
4792 else if (FD_ISSET(gpm_fd
, &rfds
))
4797 if (ret
> 0 && xsmp_icefd
!= -1)
4799 if (FD_ISSET(xsmp_icefd
, &efds
))
4802 verb_msg((char_u
*)_("XSMP lost ICE connection"));
4805 finished
= FALSE
; /* keep going if event was only one */
4807 else if (FD_ISSET(xsmp_icefd
, &rfds
))
4810 xsmp_handle_requests();
4813 finished
= FALSE
; /* keep going if event was only one */
4818 #endif /* HAVE_SELECT */
4821 if (finished
|| msec
== 0)
4824 /* We're going to loop around again, find out for how long */
4827 # ifdef USE_START_TV
4830 /* Compute remaining wait time. */
4831 gettimeofday(&mtv
, NULL
);
4832 msec
-= (mtv
.tv_sec
- start_tv
.tv_sec
) * 1000L
4833 + (mtv
.tv_usec
- start_tv
.tv_usec
) / 1000L;
4835 /* Guess we got interrupted halfway. */
4839 break; /* waited long enough */
4849 #ifndef NO_EXPANDPATH
4851 * Expand a path into all matching files and/or directories. Handles "*",
4852 * "?", "[a-z]", "**", etc.
4853 * "path" has backslashes before chars that are not to be expanded.
4854 * Returns the number of matches found.
4857 mch_expandpath(gap
, path
, flags
)
4860 int flags
; /* EW_* flags */
4862 return unix_expandpath(gap
, path
, 0, flags
, FALSE
);
4867 * mch_expand_wildcards() - this code does wild-card pattern matching using
4870 * return OK for success, FAIL for error (you may lose some memory) and put
4871 * an error message in *file.
4873 * num_pat is number of input patterns
4874 * pat is array of pointers to input patterns
4875 * num_file is pointer to number of matched file names
4876 * file is pointer to array of pointers to matched file names
4886 #define SHELL_SPECIAL (char_u *)"\t \"&'$;<>()\\|"
4890 mch_expand_wildcards(num_pat
, pat
, num_file
, file
, flags
)
4895 int flags
; /* EW_* flags */
4902 # define EXPL_ALLOC_INC 16
4903 char_u
**expl_files
;
4904 size_t files_alloced
, files_free
;
4908 *num_file
= 0; /* default: no files found */
4909 files_alloced
= EXPL_ALLOC_INC
; /* how much space is allocated */
4910 files_free
= EXPL_ALLOC_INC
; /* how much space is not used */
4911 *file
= (char_u
**)alloc(sizeof(char_u
**) * files_alloced
);
4915 for (; num_pat
> 0; num_pat
--, pat
++)
4918 if (vim_strchr(*pat
, '$') || vim_strchr(*pat
, '~'))
4919 /* expand environment var or home dir */
4920 buf
= expand_env_save(*pat
);
4922 buf
= vim_strsave(*pat
);
4924 has_wildcard
= mch_has_exp_wildcard(buf
); /* (still) wildcards? */
4925 if (has_wildcard
) /* yes, so expand them */
4926 expl_files
= (char_u
**)_fnexplode(buf
);
4929 * return value of buf if no wildcards left,
4930 * OR if no match AND EW_NOTFOUND is set.
4932 if ((!has_wildcard
&& ((flags
& EW_NOTFOUND
) || mch_getperm(buf
) >= 0))
4933 || (expl_files
== NULL
&& (flags
& EW_NOTFOUND
)))
4934 { /* simply save the current contents of *buf */
4935 expl_files
= (char_u
**)alloc(sizeof(char_u
**) * 2);
4936 if (expl_files
!= NULL
)
4938 expl_files
[0] = vim_strsave(buf
);
4939 expl_files
[1] = NULL
;
4945 * Count number of names resulting from expansion,
4946 * At the same time add a backslash to the end of names that happen to
4947 * be directories, and replace slashes with backslashes.
4951 for (i
= 0; (p
= expl_files
[i
]) != NULL
; i
++)
4954 /* If we don't want dirs and this is one, skip it */
4955 if ((dir
&& !(flags
& EW_DIR
)) || (!dir
&& !(flags
& EW_FILE
)))
4958 /* Skip files that are not executable if we check for that. */
4959 if (!dir
&& (flags
& EW_EXEC
) && !mch_can_exe(p
))
4962 if (--files_free
== 0)
4964 /* need more room in table of pointers */
4965 files_alloced
+= EXPL_ALLOC_INC
;
4966 *file
= (char_u
**)vim_realloc(*file
,
4967 sizeof(char_u
**) * files_alloced
);
4970 EMSG(_(e_outofmem
));
4974 files_free
= EXPL_ALLOC_INC
;
4979 /* For a directory we add a '/', unless it's already
4982 if (((*file
)[*num_file
] = alloc(len
+ 2)) != NULL
)
4984 STRCPY((*file
)[*num_file
], p
);
4985 if (!after_pathsep((*file
)[*num_file
],
4986 (*file
)[*num_file
] + len
))
4988 (*file
)[*num_file
][len
] = psepc
;
4989 (*file
)[*num_file
][len
+ 1] = NUL
;
4995 (*file
)[*num_file
] = vim_strsave(p
);
4999 * Error message already given by either alloc or vim_strsave.
5000 * Should return FAIL, but returning OK works also.
5002 if ((*file
)[*num_file
] == NULL
)
5006 _fnexplodefree((char **)expl_files
);
5018 #define STYLE_ECHO 0 /* use "echo" to expand */
5019 #define STYLE_GLOB 1 /* use "glob" to expand, for csh */
5020 #define STYLE_PRINT 2 /* use "print -N" to expand, for zsh */
5021 #define STYLE_BT 3 /* `cmd` expansion, execute the pattern directly */
5022 int shell_style
= STYLE_ECHO
;
5024 static int did_find_nul
= FALSE
;
5025 int ampersent
= FALSE
;
5027 *num_file
= 0; /* default: no files found */
5031 * If there are no wildcards, just copy the names to allocated memory.
5032 * Saves a lot of time, because we don't have to start a new shell.
5034 if (!have_wildcard(num_pat
, pat
))
5035 return save_patterns(num_pat
, pat
, num_file
, file
);
5037 # ifdef HAVE_SANDBOX
5038 /* Don't allow any shell command in the sandbox. */
5039 if (sandbox
!= 0 && check_secure())
5044 * Don't allow the use of backticks in secure and restricted mode.
5046 if (secure
|| restricted
)
5047 for (i
= 0; i
< num_pat
; ++i
)
5048 if (vim_strchr(pat
[i
], '`') != NULL
5049 && (check_restricted() || check_secure()))
5053 * get a name for the temp file
5055 if ((tempname
= vim_tempname('o')) == NULL
)
5062 * Let the shell expand the patterns and write the result into the temp
5063 * file. if expanding `cmd` execute it directly.
5064 * If we use csh, glob will work better than echo.
5065 * If we use zsh, print -N will work better than glob.
5067 if (num_pat
== 1 && *pat
[0] == '`'
5068 && (len
= STRLEN(pat
[0])) > 2
5069 && *(pat
[0] + len
- 1) == '`')
5070 shell_style
= STYLE_BT
;
5071 else if ((len
= STRLEN(p_sh
)) >= 3)
5073 if (STRCMP(p_sh
+ len
- 3, "csh") == 0)
5074 shell_style
= STYLE_GLOB
;
5075 else if (STRCMP(p_sh
+ len
- 3, "zsh") == 0)
5076 shell_style
= STYLE_PRINT
;
5079 /* "unset nonomatch; print -N >" plus two is 29 */
5080 len
= STRLEN(tempname
) + 29;
5081 for (i
= 0; i
< num_pat
; ++i
)
5083 /* Count the length of the patterns in the same way as they are put in
5084 * "command" below. */
5086 len
+= STRLEN(pat
[i
]) + 3; /* add space and two quotes */
5088 ++len
; /* add space */
5089 for (j
= 0; pat
[i
][j
] != NUL
; ++j
)
5091 if (vim_strchr(SHELL_SPECIAL
, pat
[i
][j
]) != NULL
)
5092 ++len
; /* may add a backslash */
5097 command
= alloc(len
);
5098 if (command
== NULL
)
5106 * Build the shell command:
5107 * - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
5109 * - Add the shell command to print the expanded names.
5110 * - Add the temp file name.
5111 * - Add the file name patterns.
5113 if (shell_style
== STYLE_BT
)
5115 /* change `command; command& ` to (command; command ) */
5116 STRCPY(command
, "(");
5117 STRCAT(command
, pat
[0] + 1); /* exclude first backtick */
5118 p
= command
+ STRLEN(command
) - 1;
5119 *p
-- = ')'; /* remove last backtick */
5120 while (p
> command
&& vim_iswhite(*p
))
5122 if (*p
== '&') /* remove trailing '&' */
5127 STRCAT(command
, ">");
5131 if (flags
& EW_NOTFOUND
)
5132 STRCPY(command
, "set nonomatch; ");
5134 STRCPY(command
, "unset nonomatch; ");
5135 if (shell_style
== STYLE_GLOB
)
5136 STRCAT(command
, "glob >");
5137 else if (shell_style
== STYLE_PRINT
)
5138 STRCAT(command
, "print -N >");
5140 STRCAT(command
, "echo >");
5142 STRCAT(command
, tempname
);
5143 if (shell_style
!= STYLE_BT
)
5144 for (i
= 0; i
< num_pat
; ++i
)
5146 /* When using system() always add extra quotes, because the shell
5147 * is started twice. Otherwise put a backslash before special
5148 * characters, except insice ``. */
5150 STRCAT(command
, " \"");
5151 STRCAT(command
, pat
[i
]);
5152 STRCAT(command
, "\"");
5156 p
= command
+ STRLEN(command
);
5158 for (j
= 0; pat
[i
][j
] != NUL
; ++j
)
5160 if (pat
[i
][j
] == '`')
5162 else if (pat
[i
][j
] == '\\' && pat
[i
][j
+ 1] != NUL
)
5164 /* Remove a backslash, take char literally. But keep
5165 * backslash inside backticks, before a special character
5166 * and before a backtick. */
5168 || vim_strchr(SHELL_SPECIAL
, pat
[i
][j
+ 1]) != NULL
5169 || pat
[i
][j
+ 1] == '`')
5173 else if (!intick
&& vim_strchr(SHELL_SPECIAL
,
5175 /* Put a backslash before a special character, but not
5176 * when inside ``. */
5179 /* Copy one character. */
5185 if (flags
& EW_SILENT
)
5186 show_shell_mess
= FALSE
;
5188 STRCAT(command
, "&"); /* put the '&' back after the
5192 * Using zsh -G: If a pattern has no matches, it is just deleted from
5193 * the argument list, otherwise zsh gives an error message and doesn't
5194 * expand any other pattern.
5196 if (shell_style
== STYLE_PRINT
)
5197 extra_shell_arg
= (char_u
*)"-G"; /* Use zsh NULL_GLOB option */
5200 * If we use -f then shell variables set in .cshrc won't get expanded.
5201 * vi can do it, so we will too, but it is only necessary if there is a "$"
5202 * in one of the patterns, otherwise we can still use the fast option.
5204 else if (shell_style
== STYLE_GLOB
&& !have_dollars(num_pat
, pat
))
5205 extra_shell_arg
= (char_u
*)"-f"; /* Use csh fast option */
5208 * execute the shell command
5210 i
= call_shell(command
, SHELL_EXPAND
| SHELL_SILENT
);
5212 /* When running in the background, give it some time to create the temp
5213 * file, but don't wait for it to finish. */
5215 mch_delay(10L, TRUE
);
5217 extra_shell_arg
= NULL
; /* cleanup */
5218 show_shell_mess
= TRUE
;
5221 if (i
) /* mch_call_shell() failed */
5223 mch_remove(tempname
);
5226 * With interactive completion, the error message is not printed.
5227 * However with USE_SYSTEM, I don't know how to turn off error messages
5228 * from the shell, so screen may still get messed up -- webb.
5231 if (!(flags
& EW_SILENT
))
5234 redraw_later_clear(); /* probably messed up screen */
5235 msg_putchar('\n'); /* clear bottom line quickly */
5236 cmdline_row
= Rows
- 1; /* continue on last line */
5238 if (!(flags
& EW_SILENT
))
5241 MSG(_(e_wildexpand
));
5242 msg_start(); /* don't overwrite this message */
5245 /* If a `cmd` expansion failed, don't list `cmd` as a match, even when
5246 * EW_NOTFOUND is given */
5247 if (shell_style
== STYLE_BT
)
5253 * read the names from the file into memory
5255 fd
= fopen((char *)tempname
, READBIN
);
5258 /* Something went wrong, perhaps a file name with a special char. */
5259 if (!(flags
& EW_SILENT
))
5261 MSG(_(e_wildexpand
));
5262 msg_start(); /* don't overwrite this message */
5267 fseek(fd
, 0L, SEEK_END
);
5268 len
= ftell(fd
); /* get size of temp file */
5269 fseek(fd
, 0L, SEEK_SET
);
5270 buffer
= alloc(len
+ 1);
5274 mch_remove(tempname
);
5279 i
= fread((char *)buffer
, 1, len
, fd
);
5281 mch_remove(tempname
);
5284 /* unexpected read error */
5285 EMSG2(_(e_notread
), tempname
);
5292 #if defined(__CYGWIN__) || defined(__CYGWIN32__)
5293 /* Translate <CR><NL> into <NL>. Caution, buffer may contain NUL. */
5295 for (i
= 0; i
< len
; ++i
)
5296 if (!(buffer
[i
] == CAR
&& buffer
[i
+ 1] == NL
))
5302 /* file names are separated with Space */
5303 if (shell_style
== STYLE_ECHO
)
5305 buffer
[len
] = '\n'; /* make sure the buffer ends in NL */
5307 for (i
= 0; *p
!= '\n'; ++i
) /* count number of entries */
5309 while (*p
!= ' ' && *p
!= '\n')
5311 p
= skipwhite(p
); /* skip to next entry */
5314 /* file names are separated with NL */
5315 else if (shell_style
== STYLE_BT
)
5317 buffer
[len
] = NUL
; /* make sure the buffer ends in NUL */
5319 for (i
= 0; *p
!= NUL
; ++i
) /* count number of entries */
5321 while (*p
!= '\n' && *p
!= NUL
)
5325 p
= skipwhite(p
); /* skip leading white space */
5328 /* file names are separated with NUL */
5332 * Some versions of zsh use spaces instead of NULs to separate
5333 * results. Only do this when there is no NUL before the end of the
5334 * buffer, otherwise we would never be able to use file names with
5335 * embedded spaces when zsh does use NULs.
5336 * When we found a NUL once, we know zsh is OK, set did_find_nul and
5337 * don't check for spaces again.
5339 check_spaces
= FALSE
;
5340 if (shell_style
== STYLE_PRINT
&& !did_find_nul
)
5342 /* If there is a NUL, set did_find_nul, else set check_spaces */
5343 if (len
&& (int)STRLEN(buffer
) < len
- 1)
5344 did_find_nul
= TRUE
;
5346 check_spaces
= TRUE
;
5350 * Make sure the buffer ends with a NUL. For STYLE_PRINT there
5351 * already is one, for STYLE_GLOB it needs to be added.
5353 if (len
&& buffer
[len
- 1] == NUL
)
5358 for (p
= buffer
; p
< buffer
+ len
; ++p
)
5359 if (*p
== NUL
|| (*p
== ' ' && check_spaces
)) /* count entry */
5365 ++i
; /* count last entry */
5370 * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
5371 * /bin/sh will happily expand it to nothing rather than returning an
5372 * error; and hey, it's good to check anyway -- webb.
5378 *file
= (char_u
**)alloc(sizeof(char_u
*) * i
);
5387 * Isolate the individual file names.
5390 for (i
= 0; i
< *num_file
; ++i
)
5393 /* Space or NL separates */
5394 if (shell_style
== STYLE_ECHO
|| shell_style
== STYLE_BT
)
5396 while (!(shell_style
== STYLE_ECHO
&& *p
== ' ')
5397 && *p
!= '\n' && *p
!= NUL
)
5399 if (p
== buffer
+ len
) /* last entry */
5404 p
= skipwhite(p
); /* skip to next entry */
5407 else /* NUL separates */
5409 while (*p
&& p
< buffer
+ len
) /* skip entry */
5416 * Move the file names to allocated memory.
5418 for (j
= 0, i
= 0; i
< *num_file
; ++i
)
5420 /* Require the files to exist. Helps when using /bin/sh */
5421 if (!(flags
& EW_NOTFOUND
) && mch_getperm((*file
)[i
]) < 0)
5424 /* check if this entry should be included */
5425 dir
= (mch_isdir((*file
)[i
]));
5426 if ((dir
&& !(flags
& EW_DIR
)) || (!dir
&& !(flags
& EW_FILE
)))
5429 /* Skip files that are not executable if we check for that. */
5430 if (!dir
&& (flags
& EW_EXEC
) && !mch_can_exe((*file
)[i
]))
5433 p
= alloc((unsigned)(STRLEN((*file
)[i
]) + 1 + dir
));
5436 STRCPY(p
, (*file
)[i
]);
5438 STRCAT(p
, "/"); /* add '/' to a directory name */
5445 if (*num_file
== 0) /* rejected all entries */
5455 if (flags
& EW_NOTFOUND
)
5456 return save_patterns(num_pat
, pat
, num_file
, file
);
5459 #endif /* __EMX__ */
5466 save_patterns(num_pat
, pat
, num_file
, file
)
5475 *file
= (char_u
**)alloc(num_pat
* sizeof(char_u
*));
5478 for (i
= 0; i
< num_pat
; i
++)
5480 s
= vim_strsave(pat
[i
]);
5482 /* Be compatible with expand_filename(): halve the number of
5487 *num_file
= num_pat
;
5494 * Return TRUE if the string "p" contains a wildcard that mch_expandpath() can
5498 mch_has_exp_wildcard(p
)
5501 for ( ; *p
; mb_ptr_adv(p
))
5504 if (*p
== '\\' && p
[1] != NUL
)
5508 if (vim_strchr((char_u
*)
5525 * Return TRUE if the string "p" contains a wildcard.
5526 * Don't recognize '~' at the end as a wildcard.
5532 for ( ; *p
; mb_ptr_adv(p
))
5535 if (*p
== '\\' && p
[1] != NUL
)
5539 if (vim_strchr((char_u
*)
5544 # ifdef VIM_BACKTICK
5554 || (*p
== '~' && p
[1] != NUL
))
5562 have_wildcard(num
, file
)
5568 for (i
= 0; i
< num
; i
++)
5569 if (mch_has_wildcard(file
[i
]))
5575 have_dollars(num
, file
)
5581 for (i
= 0; i
< num
; i
++)
5582 if (vim_strchr(file
[i
], '$') != NULL
)
5586 #endif /* ifndef __EMX__ */
5590 * Scaled-down version of rename(), which is missing in Xenix.
5591 * This version can only move regular files and will fail if the
5592 * destination exists.
5595 mch_rename(src
, dest
)
5596 const char *src
, *dest
;
5600 if (stat(dest
, &st
) >= 0) /* fail if destination exists */
5602 if (link(src
, dest
) != 0) /* link file to new name */
5604 if (mch_remove(src
) == 0) /* delete link to old name */
5608 #endif /* !HAVE_RENAME */
5610 #ifdef FEAT_MOUSE_GPM
5612 * Initializes connection with gpm (if it isn't already opened)
5613 * Return 1 if succeeded (or connection already opened), 0 if failed
5618 static Gpm_Connect gpm_connect
; /* Must it be kept till closing ? */
5622 gpm_connect
.eventMask
= (GPM_UP
| GPM_DRAG
| GPM_DOWN
);
5623 gpm_connect
.defaultMask
= ~GPM_HARD
;
5624 /* Default handling for mouse move*/
5625 gpm_connect
.minMod
= 0; /* Handle any modifier keys */
5626 gpm_connect
.maxMod
= 0xffff;
5627 if (Gpm_Open(&gpm_connect
, 0) > 0)
5629 /* gpm library tries to handling TSTP causes
5630 * problems. Anyways, we close connection to Gpm whenever
5631 * we are going to suspend or starting an external process
5632 * so we should'nt have problem with this
5634 signal(SIGTSTP
, restricted
? SIG_IGN
: SIG_DFL
);
5635 return 1; /* succeed */
5638 Gpm_Close(); /* We don't want to talk to xterm via gpm */
5641 return 1; /* already open */
5645 * Closes connection to gpm
5646 * returns non-zero if connection succesfully closed
5651 if (gpm_flag
&& gpm_fd
>= 0) /* if Open */
5655 /* Reads gpm event and adds special keys to input buf. Returns length of
5656 * generated key sequence.
5657 * This function is made after gui_send_mouse_event
5663 static Gpm_Event gpm_event
;
5665 int_u vim_modifiers
;
5667 unsigned char buttons_mask
;
5668 unsigned char gpm_modifiers
;
5669 static unsigned char old_buttons
= 0;
5671 Gpm_GetEvent(&gpm_event
);
5674 /* Don't put events in the input queue now. */
5675 if (hold_gui_events
)
5679 row
= gpm_event
.y
- 1;
5680 col
= gpm_event
.x
- 1;
5682 string
[0] = ESC
; /* Our termcode */
5685 switch (GPM_BARE_EVENTS(gpm_event
.type
))
5688 string
[3] = MOUSE_DRAG
;
5691 buttons_mask
= gpm_event
.buttons
& ~old_buttons
;
5692 old_buttons
= gpm_event
.buttons
;
5693 switch (buttons_mask
)
5696 button
= MOUSE_LEFT
;
5699 button
= MOUSE_MIDDLE
;
5702 button
= MOUSE_RIGHT
;
5706 /*Don't know what to do. Can more than one button be
5707 * reported in one event? */
5709 string
[3] = (char_u
)(button
| 0x20);
5710 SET_NUM_MOUSE_CLICKS(string
[3], gpm_event
.clicks
+ 1);
5713 string
[3] = MOUSE_RELEASE
;
5714 old_buttons
&= ~gpm_event
.buttons
;
5719 /*This code is based on gui_x11_mouse_cb in gui_x11.c */
5720 gpm_modifiers
= gpm_event
.modifiers
;
5721 vim_modifiers
= 0x0;
5722 /* I ignore capslock stats. Aren't we all just hate capslock mixing with
5723 * Vim commands ? Besides, gpm_event.modifiers is unsigned char, and
5724 * K_CAPSSHIFT is defined 8, so it probably isn't even reported
5726 if (gpm_modifiers
& ((1 << KG_SHIFT
) | (1 << KG_SHIFTR
) | (1 << KG_SHIFTL
)))
5727 vim_modifiers
|= MOUSE_SHIFT
;
5729 if (gpm_modifiers
& ((1 << KG_CTRL
) | (1 << KG_CTRLR
) | (1 << KG_CTRLL
)))
5730 vim_modifiers
|= MOUSE_CTRL
;
5731 if (gpm_modifiers
& ((1 << KG_ALT
) | (1 << KG_ALTGR
)))
5732 vim_modifiers
|= MOUSE_ALT
;
5733 string
[3] |= vim_modifiers
;
5734 string
[4] = (char_u
)(col
+ ' ' + 1);
5735 string
[5] = (char_u
)(row
+ ' ' + 1);
5736 add_to_input_buf(string
, 6);
5739 #endif /* FEAT_MOUSE_GPM */
5741 #if defined(FEAT_LIBCALL) || defined(PROTO)
5742 typedef char_u
* (*STRPROCSTR
)__ARGS((char_u
*));
5743 typedef char_u
* (*INTPROCSTR
)__ARGS((int));
5744 typedef int (*STRPROCINT
)__ARGS((char_u
*));
5745 typedef int (*INTPROCINT
)__ARGS((int));
5748 * Call a DLL routine which takes either a string or int param
5749 * and returns an allocated string.
5752 mch_libcall(libname
, funcname
, argstring
, argint
, string_result
, number_result
)
5755 char_u
*argstring
; /* NULL when using a argint */
5757 char_u
**string_result
;/* NULL when using number_result */
5760 # if defined(USE_DLOPEN)
5767 INTPROCSTR ProcAddI
;
5768 char_u
*retval_str
= NULL
;
5770 int success
= FALSE
;
5773 * Get a handle to the DLL module.
5775 # if defined(USE_DLOPEN)
5776 /* First clear any error, it's not cleared by the dlopen() call. */
5779 hinstLib
= dlopen((char *)libname
, RTLD_LAZY
5784 if (hinstLib
== NULL
)
5786 /* "dlerr" must be used before dlclose() */
5787 dlerr
= (char *)dlerror();
5789 EMSG2(_("dlerror = \"%s\""), dlerr
);
5792 hinstLib
= shl_load((const char*)libname
, BIND_IMMEDIATE
|BIND_VERBOSE
, 0L);
5795 /* If the handle is valid, try to get the function address. */
5796 if (hinstLib
!= NULL
)
5798 # ifdef HAVE_SETJMP_H
5800 * Catch a crash when calling the library function. For example when
5801 * using a number where a string pointer is expected.
5804 if (SETJMP(lc_jump_env
) != 0)
5807 # if defined(USE_DLOPEN)
5818 if (argstring
!= NULL
)
5820 # if defined(USE_DLOPEN)
5821 ProcAdd
= (STRPROCSTR
)dlsym(hinstLib
, (const char *)funcname
);
5822 dlerr
= (char *)dlerror();
5824 if (shl_findsym(&hinstLib
, (const char *)funcname
,
5825 TYPE_PROCEDURE
, (void *)&ProcAdd
) < 0)
5828 if ((success
= (ProcAdd
!= NULL
5829 # if defined(USE_DLOPEN)
5834 if (string_result
== NULL
)
5835 retval_int
= ((STRPROCINT
)ProcAdd
)(argstring
);
5837 retval_str
= (ProcAdd
)(argstring
);
5842 # if defined(USE_DLOPEN)
5843 ProcAddI
= (INTPROCSTR
)dlsym(hinstLib
, (const char *)funcname
);
5844 dlerr
= (char *)dlerror();
5846 if (shl_findsym(&hinstLib
, (const char *)funcname
,
5847 TYPE_PROCEDURE
, (void *)&ProcAddI
) < 0)
5850 if ((success
= (ProcAddI
!= NULL
5851 # if defined(USE_DLOPEN)
5856 if (string_result
== NULL
)
5857 retval_int
= ((INTPROCINT
)ProcAddI
)(argint
);
5859 retval_str
= (ProcAddI
)(argint
);
5863 /* Save the string before we free the library. */
5864 /* Assume that a "1" or "-1" result is an illegal pointer. */
5865 if (string_result
== NULL
)
5866 *number_result
= retval_int
;
5867 else if (retval_str
!= NULL
5868 && retval_str
!= (char_u
*)1
5869 && retval_str
!= (char_u
*)-1)
5870 *string_result
= vim_strsave(retval_str
);
5873 # ifdef HAVE_SETJMP_H
5880 /* try to find the name of this signal */
5881 for (i
= 0; signal_info
[i
].sig
!= -1; i
++)
5882 if (lc_signal
== signal_info
[i
].sig
)
5884 EMSG2("E368: got SIG%s in libcall()", signal_info
[i
].name
);
5889 # if defined(USE_DLOPEN)
5890 /* "dlerr" must be used before dlclose() */
5892 EMSG2(_("dlerror = \"%s\""), dlerr
);
5894 /* Free the DLL module. */
5895 (void)dlclose(hinstLib
);
5897 (void)shl_unload(hinstLib
);
5903 EMSG2(_(e_libcall
), funcname
);
5911 #if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) || defined(PROTO)
5912 static int xterm_trace
= -1; /* default: disabled */
5913 static int xterm_button
;
5916 * Setup a dummy window for X selections in a terminal.
5925 if (!x_connect_to_server())
5929 if (app_context
!= NULL
&& xterm_Shell
== (Widget
)0)
5931 int (*oldhandler
)();
5932 #if defined(HAVE_SETJMP_H)
5933 int (*oldIOhandler
)();
5935 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
5936 struct timeval start_tv
;
5939 gettimeofday(&start_tv
, NULL
);
5942 /* Ignore X errors while opening the display */
5943 oldhandler
= XSetErrorHandler(x_error_check
);
5945 #if defined(HAVE_SETJMP_H)
5946 /* Ignore X IO errors while opening the display */
5947 oldIOhandler
= XSetIOErrorHandler(x_IOerror_check
);
5949 if (SETJMP(lc_jump_env
) != 0)
5957 xterm_dpy
= XtOpenDisplay(app_context
, xterm_display
,
5958 "vim_xterm", "Vim_xterm", NULL
, 0, &z
, &strp
);
5959 #if defined(HAVE_SETJMP_H)
5964 #if defined(HAVE_SETJMP_H)
5965 /* Now handle X IO errors normally. */
5966 (void)XSetIOErrorHandler(oldIOhandler
);
5968 /* Now handle X errors normally. */
5969 (void)XSetErrorHandler(oldhandler
);
5971 if (xterm_dpy
== NULL
)
5974 verb_msg((char_u
*)_("Opening the X display failed"));
5978 /* Catch terminating error of the X server connection. */
5979 (void)XSetIOErrorHandler(x_IOerror_handler
);
5981 # if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
5985 xopen_message(&start_tv
);
5990 /* Create a Shell to make converters work. */
5991 AppShell
= XtVaAppCreateShell("vim_xterm", "Vim_xterm",
5992 applicationShellWidgetClass
, xterm_dpy
,
5994 if (AppShell
== (Widget
)0)
5996 xterm_Shell
= XtVaCreatePopupShell("VIM",
5997 topLevelShellWidgetClass
, AppShell
,
5998 XtNmappedWhenManaged
, 0,
6002 if (xterm_Shell
== (Widget
)0)
6005 x11_setup_atoms(xterm_dpy
);
6006 if (x11_display
== NULL
)
6007 x11_display
= xterm_dpy
;
6009 XtRealizeWidget(xterm_Shell
);
6010 XSync(xterm_dpy
, False
);
6013 if (xterm_Shell
!= (Widget
)0)
6016 if (x11_window
== 0 && (strp
= getenv("WINDOWID")) != NULL
)
6017 x11_window
= (Window
)atol(strp
);
6018 /* Check if $WINDOWID is valid. */
6019 if (test_x11_window(xterm_dpy
) == FAIL
)
6021 if (x11_window
!= 0)
6027 start_xterm_trace(button
)
6030 if (x11_window
== 0 || xterm_trace
< 0 || xterm_Shell
== (Widget
)0)
6033 xterm_button
= button
;
6041 if (xterm_trace
< 0)
6047 * Query the xterm pointer and generate mouse termcodes if necessary
6048 * return TRUE if dragging is active, else FALSE
6061 static char_u
*mouse_code
;
6062 static char_u mouse_name
[2] = {KS_MOUSE
, KE_FILLER
};
6063 static int prev_row
= 0, prev_col
= 0;
6064 static XSizeHints xterm_hints
;
6066 if (xterm_trace
<= 0)
6069 if (xterm_trace
== 1)
6071 /* Get the hints just before tracking starts. The font size might
6072 * have changed recently */
6073 XGetWMNormalHints(xterm_dpy
, x11_window
, &xterm_hints
, &got_hints
);
6074 if (!(got_hints
& PResizeInc
)
6075 || xterm_hints
.width_inc
<= 1
6076 || xterm_hints
.height_inc
<= 1)
6078 xterm_trace
= -1; /* Not enough data -- disable tracing */
6082 /* Rely on the same mouse code for the duration of this */
6083 mouse_code
= find_termcode(mouse_name
);
6084 prev_row
= mouse_row
;
6085 prev_row
= mouse_col
;
6088 /* Find the offset of the chars, there might be a scrollbar on the
6089 * left of the window and/or a menu on the top (eterm etc.) */
6090 XQueryPointer(xterm_dpy
, x11_window
, &root
, &child
, &root_x
, &root_y
,
6091 &win_x
, &win_y
, &mask_return
);
6092 xterm_hints
.y
= win_y
- (xterm_hints
.height_inc
* mouse_row
)
6093 - (xterm_hints
.height_inc
/ 2);
6094 if (xterm_hints
.y
<= xterm_hints
.height_inc
/ 2)
6096 xterm_hints
.x
= win_x
- (xterm_hints
.width_inc
* mouse_col
)
6097 - (xterm_hints
.width_inc
/ 2);
6098 if (xterm_hints
.x
<= xterm_hints
.width_inc
/ 2)
6102 if (mouse_code
== NULL
)
6108 XQueryPointer(xterm_dpy
, x11_window
, &root
, &child
, &root_x
, &root_y
,
6109 &win_x
, &win_y
, &mask_return
);
6111 row
= check_row((win_y
- xterm_hints
.y
) / xterm_hints
.height_inc
);
6112 col
= check_col((win_x
- xterm_hints
.x
) / xterm_hints
.width_inc
);
6113 if (row
== prev_row
&& col
== prev_col
)
6116 STRCPY(buf
, mouse_code
);
6117 strp
= buf
+ STRLEN(buf
);
6118 *strp
++ = (xterm_button
| MOUSE_DRAG
) & ~0x20;
6119 *strp
++ = (char_u
)(col
+ ' ' + 1);
6120 *strp
++ = (char_u
)(row
+ ' ' + 1);
6122 add_to_input_buf(buf
, STRLEN(buf
));
6129 # if defined(FEAT_GUI) || defined(PROTO)
6131 * Destroy the display, window and app_context. Required for GTK.
6136 if (xterm_Shell
!= (Widget
)0)
6138 XtDestroyWidget(xterm_Shell
);
6139 xterm_Shell
= (Widget
)0;
6141 if (xterm_dpy
!= NULL
)
6144 /* Lesstif and Solaris crash here, lose some memory */
6145 XtCloseDisplay(xterm_dpy
);
6147 if (x11_display
== xterm_dpy
)
6152 if (app_context
!= (XtAppContext
)NULL
)
6154 /* Lesstif and Solaris crash here, lose some memory */
6155 XtDestroyApplicationContext(app_context
);
6156 app_context
= (XtAppContext
)NULL
;
6163 * Catch up with any queued X events. This may put keyboard input into the
6164 * input buffer, call resize call-backs, trigger timers etc. If there is
6165 * nothing in the X event queue (& no timers pending), then we return
6173 while (XtAppPending(app_context
) && !vim_is_input_buf_full())
6175 XtAppNextEvent(app_context
, &event
);
6176 #ifdef FEAT_CLIENTSERVER
6178 XPropertyEvent
*e
= (XPropertyEvent
*)&event
;
6180 if (e
->type
== PropertyNotify
&& e
->window
== commWindow
6181 && e
->atom
== commProperty
&& e
->state
== PropertyNewValue
)
6182 serverEventProc(xterm_dpy
, &event
);
6185 XtDispatchEvent(&event
);
6190 clip_xterm_own_selection(cbd
)
6193 if (xterm_Shell
!= (Widget
)0)
6194 return clip_x11_own_selection(xterm_Shell
, cbd
);
6199 clip_xterm_lose_selection(cbd
)
6202 if (xterm_Shell
!= (Widget
)0)
6203 clip_x11_lose_selection(xterm_Shell
, cbd
);
6207 clip_xterm_request_selection(cbd
)
6210 if (xterm_Shell
!= (Widget
)0)
6211 clip_x11_request_selection(xterm_Shell
, xterm_dpy
, cbd
);
6215 clip_xterm_set_selection(cbd
)
6218 clip_x11_set_selection(cbd
);
6223 #if defined(USE_XSMP) || defined(PROTO)
6225 * Code for X Session Management Protocol.
6227 static void xsmp_handle_save_yourself
__ARGS((SmcConn smc_conn
, SmPointer client_data
, int save_type
, Bool shutdown
, int interact_style
, Bool fast
));
6228 static void xsmp_die
__ARGS((SmcConn smc_conn
, SmPointer client_data
));
6229 static void xsmp_save_complete
__ARGS((SmcConn smc_conn
, SmPointer client_data
));
6230 static void xsmp_shutdown_cancelled
__ARGS((SmcConn smc_conn
, SmPointer client_data
));
6231 static void xsmp_ice_connection
__ARGS((IceConn iceConn
, IcePointer clientData
, Bool opening
, IcePointer
*watchData
));
6234 # if defined(FEAT_GUI) && defined(USE_XSMP_INTERACT)
6235 static void xsmp_handle_interaction
__ARGS((SmcConn smc_conn
, SmPointer client_data
));
6238 * This is our chance to ask the user if they want to save,
6239 * or abort the logout
6243 xsmp_handle_interaction(smc_conn
, client_data
)
6245 SmPointer client_data
;
6247 cmdmod_T save_cmdmod
;
6248 int cancel_shutdown
= False
;
6250 save_cmdmod
= cmdmod
;
6251 cmdmod
.confirm
= TRUE
;
6252 if (check_changed_any(FALSE
))
6253 /* Mustn't logout */
6254 cancel_shutdown
= True
;
6255 cmdmod
= save_cmdmod
;
6256 setcursor(); /* position cursor */
6259 /* Done interaction */
6260 SmcInteractDone(smc_conn
, cancel_shutdown
);
6263 * Only end save-yourself here if we're not cancelling shutdown;
6264 * we'll get a cancelled callback later in which we'll end it.
6265 * Hopefully get around glitchy SMs (like GNOME-1)
6267 if (!cancel_shutdown
)
6269 xsmp
.save_yourself
= False
;
6270 SmcSaveYourselfDone(smc_conn
, True
);
6276 * Callback that starts save-yourself.
6280 xsmp_handle_save_yourself(smc_conn
, client_data
, save_type
,
6281 shutdown
, interact_style
, fast
)
6283 SmPointer client_data
;
6289 /* Handle already being in saveyourself */
6290 if (xsmp
.save_yourself
)
6291 SmcSaveYourselfDone(smc_conn
, True
);
6292 xsmp
.save_yourself
= True
;
6293 xsmp
.shutdown
= shutdown
;
6295 /* First up, preserve all files */
6297 ml_sync_all(FALSE
, FALSE
); /* preserve all swap files */
6300 verb_msg((char_u
*)_("XSMP handling save-yourself request"));
6302 # if defined(FEAT_GUI) && defined(USE_XSMP_INTERACT)
6303 /* Now see if we can ask about unsaved files */
6304 if (shutdown
&& !fast
&& gui
.in_use
)
6305 /* Need to interact with user, but need SM's permission */
6306 SmcInteractRequest(smc_conn
, SmDialogError
,
6307 xsmp_handle_interaction
, client_data
);
6311 /* Can stop the cycle here */
6312 SmcSaveYourselfDone(smc_conn
, True
);
6313 xsmp
.save_yourself
= False
;
6319 * Callback to warn us of imminent death.
6323 xsmp_die(smc_conn
, client_data
)
6325 SmPointer client_data
;
6329 /* quit quickly leaving swapfiles for modified buffers behind */
6330 getout_preserve_modified(0);
6335 * Callback to tell us that save-yourself has completed.
6339 xsmp_save_complete(smc_conn
, client_data
)
6341 SmPointer client_data
;
6343 xsmp
.save_yourself
= False
;
6348 * Callback to tell us that an instigated shutdown was cancelled
6349 * (maybe even by us)
6353 xsmp_shutdown_cancelled(smc_conn
, client_data
)
6355 SmPointer client_data
;
6357 if (xsmp
.save_yourself
)
6358 SmcSaveYourselfDone(smc_conn
, True
);
6359 xsmp
.save_yourself
= False
;
6360 xsmp
.shutdown
= False
;
6365 * Callback to tell us that a new ICE connection has been established.
6369 xsmp_ice_connection(iceConn
, clientData
, opening
, watchData
)
6371 IcePointer clientData
;
6373 IcePointer
*watchData
;
6375 /* Intercept creation of ICE connection fd */
6378 xsmp_icefd
= IceConnectionNumber(iceConn
);
6379 IceRemoveConnectionWatch(xsmp_ice_connection
, NULL
);
6384 /* Handle any ICE processing that's required; return FAIL if SM lost */
6386 xsmp_handle_requests()
6390 if (IceProcessMessages(xsmp
.iceconn
, NULL
, &rep
)
6391 == IceProcessMessagesIOError
)
6395 verb_msg((char_u
*)_("XSMP lost ICE connection"));
6405 /* Set up X Session Management Protocol */
6409 char errorstring
[80];
6411 SmcCallbacks smcallbacks
;
6419 verb_msg((char_u
*)_("XSMP opening connection"));
6421 xsmp
.save_yourself
= xsmp
.shutdown
= False
;
6423 /* Set up SM callbacks - must have all, even if they're not used */
6424 smcallbacks
.save_yourself
.callback
= xsmp_handle_save_yourself
;
6425 smcallbacks
.save_yourself
.client_data
= NULL
;
6426 smcallbacks
.die
.callback
= xsmp_die
;
6427 smcallbacks
.die
.client_data
= NULL
;
6428 smcallbacks
.save_complete
.callback
= xsmp_save_complete
;
6429 smcallbacks
.save_complete
.client_data
= NULL
;
6430 smcallbacks
.shutdown_cancelled
.callback
= xsmp_shutdown_cancelled
;
6431 smcallbacks
.shutdown_cancelled
.client_data
= NULL
;
6433 /* Set up a watch on ICE connection creations. The "dummy" argument is
6434 * apparently required for FreeBSD (we get a BUS error when using NULL). */
6435 if (IceAddConnectionWatch(xsmp_ice_connection
, &dummy
) == 0)
6438 verb_msg((char_u
*)_("XSMP ICE connection watch failed"));
6442 /* Create an SM connection */
6443 xsmp
.smcconn
= SmcOpenConnection(
6448 SmcSaveYourselfProcMask
| SmcDieProcMask
6449 | SmcSaveCompleteProcMask
| SmcShutdownCancelledProcMask
,
6453 sizeof(errorstring
),
6455 if (xsmp
.smcconn
== NULL
)
6457 char errorreport
[132];
6461 vim_snprintf(errorreport
, sizeof(errorreport
),
6462 _("XSMP SmcOpenConnection failed: %s"), errorstring
);
6463 verb_msg((char_u
*)errorreport
);
6467 xsmp
.iceconn
= SmcGetIceConnection(xsmp
.smcconn
);
6471 smname
.value
= "vim";
6473 smnameprop
.name
= "SmProgram";
6474 smnameprop
.type
= "SmARRAY8";
6475 smnameprop
.num_vals
= 1;
6476 smnameprop
.vals
= &smname
;
6478 smprops
[0] = &smnameprop
;
6479 SmcSetProperties(xsmp
.smcconn
, 1, smprops
);
6484 /* Shut down XSMP comms. */
6488 if (xsmp_icefd
!= -1)
6490 SmcCloseConnection(xsmp
.smcconn
, 0, NULL
);
6494 #endif /* USE_XSMP */
6498 /* Translate character to its CTRL- value */
6502 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6503 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6504 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6505 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6506 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6507 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6511 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6514 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6525 0, 0, 0, 0, 0, 0, 0,
6536 0, 0, 0, 0, 0, 0, 0, 0,
6549 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6551 /* BE - C0 */ 0, 0, 0,
6561 /* CA - D0 */ 0, 0, 0, 0, 0, 0, 0,
6571 /* DA - DF */ 0, 0, 0, 0, 0, 0,
6582 /* EA - FF*/ 0, 0, 0, 0, 0, 0,
6583 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6586 char MetaCharTable
[]=
6587 {/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
6588 0, 0, 0, 0,'\\', 0,'F', 0,'W','M','N', 0, 0, 0, 0, 0,
6589 0, 0, 0, 0,']', 0, 0,'G', 0, 0,'R','O', 0, 0, 0, 0,
6590 '@','A','B','C','D','E', 0, 0,'H','I','J','K','L', 0, 0, 0,
6591 'P','Q', 0,'S','T','U','V', 0,'X','Y','Z','[', 0, 0,'^', 0
6595 /* TODO: Use characters NOT numbers!!! */
6596 char CtrlCharTable
[]=
6597 {/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
6598 124,193,194,195, 0,201, 0, 0, 0, 0, 0,210,211,212,213,214,
6599 215,216,217,226, 0,209,200, 0,231,232, 0, 0,224,189, 95,109,
6600 0, 0, 0, 0, 0, 0,230,173, 0, 0, 0, 0, 0,197,198,199,
6601 0, 0,229, 0, 0, 0, 0,196, 0, 0, 0, 0,227,228, 0,233,