aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c1664
1 files changed, 0 insertions, 1664 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
deleted file mode 100644
index 93cd0272a8..0000000000
--- a/src/os_unix.c
+++ /dev/null
@@ -1,1664 +0,0 @@
-/*
- * VIM - Vi IMproved by Bram Moolenaar
- * OS/2 port by Paul Slootman
- * VMS merge by Zoltan Arpadffy
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
-
-/*
- * os_unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
- * Also for BeOS and Atari MiNT.
- *
- * A lot of this file was originally written by Juergen Weigert and later
- * changed beyond recognition.
- */
-
-/*
- * Some systems have a prototype for select() that has (int *) instead of
- * (fd_set *), which is wrong. This define removes that prototype. We define
- * our own prototype below.
- * Don't use it for the Mac, it causes a warning for precompiled headers.
- * TODO: use a configure check for precompiled headers?
- */
-# define select select_declared_wrong
-
-#include <string.h>
-
-#include "vim.h"
-#include "os_unix.h"
-#include "buffer.h"
-#include "charset.h"
-#include "eval.h"
-#include "ex_cmds.h"
-#include "fileio.h"
-#include "getchar.h"
-#include "main.h"
-#include "mbyte.h"
-#include "memline.h"
-#include "memory.h"
-#include "message.h"
-#include "misc1.h"
-#include "misc2.h"
-#include "garray.h"
-#include "path.h"
-#include "screen.h"
-#include "syntax.h"
-#include "term.h"
-#include "ui.h"
-#include "os/os.h"
-#include "os/time.h"
-#include "os/event.h"
-#include "os/input.h"
-#include "os/shell.h"
-#include "os/signal.h"
-#include "os/job.h"
-
-#if defined(HAVE_SYS_IOCTL_H)
-# include <sys/ioctl.h>
-#endif
-
-#ifdef HAVE_STROPTS_H
-# include <stropts.h>
-#endif
-
-#if defined(HAVE_TERMIOS_H)
-# include <termios.h>
-#endif
-
-/* shared library access */
-#if defined(HAVE_DLFCN_H) && defined(USE_DLOPEN)
-# include <dlfcn.h>
-#endif
-
-#ifdef HAVE_SELINUX
-# include <selinux/selinux.h>
-static int selinux_enabled = -1;
-#endif
-
-static int get_x11_title(int);
-static int get_x11_icon(int);
-
-static char_u *oldtitle = NULL;
-static int did_set_title = FALSE;
-static char_u *oldicon = NULL;
-static int did_set_icon = FALSE;
-
-static int have_wildcard(int, char_u **);
-static int have_dollars(int, char_u **);
-
-static void save_patterns(int num_pat, char_u **pat, int *num_file,
- char_u ***file);
-
-/*
- * Write s[len] to the screen.
- */
-void mch_write(char_u *s, int len)
-{
- ignored = (int)write(1, (char *)s, len);
- if (p_wd) /* Unix is too fast, slow down a bit more */
- os_microdelay(p_wd, false);
-}
-
-/*
- * A simplistic version of setjmp() that only allows one level of using.
- * Don't call twice before calling mch_endjmp()!.
- * Usage:
- * mch_startjmp();
- * if (SETJMP(lc_jump_env) != 0)
- * {
- * mch_didjmp();
- * EMSG("crash!");
- * }
- * else
- * {
- * do_the_work;
- * mch_endjmp();
- * }
- * Note: Can't move SETJMP() here, because a function calling setjmp() must
- * not return before the saved environment is used.
- * Returns OK for normal return, FAIL when the protected code caused a
- * problem and LONGJMP() was used.
- */
-void mch_startjmp()
-{
- lc_active = TRUE;
-}
-
-void mch_endjmp()
-{
- lc_active = FALSE;
-}
-
-/*
- * If the machine has job control, use it to suspend the program,
- * otherwise fake it by starting a new shell.
- */
-void mch_suspend()
-{
- /* BeOS does have SIGTSTP, but it doesn't work. */
-#if defined(SIGTSTP) && !defined(__BEOS__)
- out_flush(); /* needed to make cursor visible on some systems */
- settmode(TMODE_COOK);
- out_flush(); /* needed to disable mouse on some systems */
-
-
-# if defined(_REENTRANT) && defined(SIGCONT)
- sigcont_received = FALSE;
-# endif
- kill(0, SIGTSTP); /* send ourselves a STOP signal */
-# if defined(_REENTRANT) && defined(SIGCONT)
- /*
- * Wait for the SIGCONT signal to be handled. It generally happens
- * immediately, but somehow not all the time. Do not call pause()
- * because there would be race condition which would hang Vim if
- * signal happened in between the test of sigcont_received and the
- * call to pause(). If signal is not yet received, call sleep(0)
- * to just yield CPU. Signal should then be received. If somehow
- * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
- * further if signal is not received after 1+2+3+4 ms (not expected
- * to happen).
- */
- {
- long wait_time;
- for (wait_time = 0; !sigcont_received && wait_time <= 3L; wait_time++)
- /* Loop is not entered most of the time */
- os_delay(wait_time, FALSE);
- }
-# endif
-
- /*
- * Set oldtitle to NULL, so the current title is obtained again.
- */
- free(oldtitle);
- oldtitle = NULL;
- settmode(TMODE_RAW);
- need_check_timestamps = TRUE;
- did_check_timestamps = FALSE;
-#endif
-}
-
-void mch_init()
-{
- Columns = 80;
- Rows = 24;
-
- out_flush();
-
-#ifdef MACOS_CONVERT
- mac_conv_init();
-#endif
-
- event_init();
-}
-
-static int get_x11_title(int test_only)
-{
- return FALSE;
-}
-
-static int get_x11_icon(int test_only)
-{
- if (!test_only) {
- if (STRNCMP(T_NAME, "builtin_", 8) == 0)
- oldicon = vim_strsave(T_NAME + 8);
- else
- oldicon = vim_strsave(T_NAME);
- }
- return FALSE;
-}
-
-
-int mch_can_restore_title()
-{
- return get_x11_title(TRUE);
-}
-
-int mch_can_restore_icon()
-{
- return get_x11_icon(TRUE);
-}
-
-/*
- * Set the window title and icon.
- */
-void mch_settitle(char_u *title, char_u *icon)
-{
- int type = 0;
- static int recursive = 0;
-
- if (T_NAME == NULL) /* no terminal name (yet) */
- return;
- if (title == NULL && icon == NULL) /* nothing to do */
- return;
-
- /* When one of the X11 functions causes a deadly signal, we get here again
- * recursively. Avoid hanging then (something is probably locked). */
- if (recursive)
- return;
- ++recursive;
-
- /*
- * if the window ID and the display is known, we may use X11 calls
- */
-
- /*
- * Note: if "t_ts" is set, title is set with escape sequence rather
- * than x11 calls, because the x11 calls don't always work
- */
- if ((type || *T_TS != NUL) && title != NULL) {
- if (oldtitle == NULL
- ) /* first call but not in GUI, save title */
- (void)get_x11_title(FALSE);
-
- if (*T_TS != NUL) /* it's OK if t_fs is empty */
- term_settitle(title);
- did_set_title = TRUE;
- }
-
- if ((type || *T_CIS != NUL) && icon != NULL) {
- if (oldicon == NULL
- ) /* first call, save icon */
- get_x11_icon(FALSE);
-
- if (*T_CIS != NUL) {
- out_str(T_CIS); /* set icon start */
- out_str_nf(icon);
- out_str(T_CIE); /* set icon end */
- out_flush();
- }
- did_set_icon = TRUE;
- }
- --recursive;
-}
-
-/*
- * Restore the window/icon title.
- * "which" is one of:
- * 1 only restore title
- * 2 only restore icon
- * 3 restore title and icon
- */
-void mch_restore_title(int which)
-{
- /* only restore the title or icon when it has been set */
- mch_settitle(((which & 1) && did_set_title) ?
- (oldtitle ? oldtitle : p_titleold) : NULL,
- ((which & 2) && did_set_icon) ? oldicon : NULL);
-}
-
-
-/*
- * Return TRUE if "name" looks like some xterm name.
- * Seiichi Sato mentioned that "mlterm" works like xterm.
- */
-int vim_is_xterm(char_u *name)
-{
- if (name == NULL)
- return FALSE;
- return STRNICMP(name, "xterm", 5) == 0
- || STRNICMP(name, "nxterm", 6) == 0
- || STRNICMP(name, "kterm", 5) == 0
- || STRNICMP(name, "mlterm", 6) == 0
- || STRNICMP(name, "rxvt", 4) == 0
- || STRCMP(name, "builtin_xterm") == 0;
-}
-
-/*
- * Return TRUE if "name" appears to be that of a terminal
- * known to support the xterm-style mouse protocol.
- * Relies on term_is_xterm having been set to its correct value.
- */
-int use_xterm_like_mouse(char_u *name)
-{
- return name != NULL
- && (term_is_xterm || STRNICMP(name, "screen", 6) == 0);
-}
-
-/*
- * Return non-zero when using an xterm mouse, according to 'ttymouse'.
- * Return 1 for "xterm".
- * Return 2 for "xterm2".
- * Return 3 for "urxvt".
- * Return 4 for "sgr".
- */
-int use_xterm_mouse()
-{
- if (ttym_flags == TTYM_SGR)
- return 4;
- if (ttym_flags == TTYM_URXVT)
- return 3;
- if (ttym_flags == TTYM_XTERM2)
- return 2;
- if (ttym_flags == TTYM_XTERM)
- return 1;
- return 0;
-}
-
-int vim_is_iris(char_u *name)
-{
- if (name == NULL)
- return FALSE;
- return STRNICMP(name, "iris-ansi", 9) == 0
- || STRCMP(name, "builtin_iris-ansi") == 0;
-}
-
-int vim_is_vt300(char_u *name)
-{
- if (name == NULL)
- return FALSE; /* actually all ANSI comp. terminals should be here */
- /* catch VT100 - VT5xx */
- return (STRNICMP(name, "vt", 2) == 0
- && vim_strchr((char_u *)"12345", name[2]) != NULL)
- || STRCMP(name, "builtin_vt320") == 0;
-}
-
-/*
- * Return TRUE if "name" is a terminal for which 'ttyfast' should be set.
- * This should include all windowed terminal emulators.
- */
-int vim_is_fastterm(char_u *name)
-{
- if (name == NULL)
- return FALSE;
- if (vim_is_xterm(name) || vim_is_vt300(name) || vim_is_iris(name))
- return TRUE;
- return STRNICMP(name, "hpterm", 6) == 0
- || STRNICMP(name, "sun-cmd", 7) == 0
- || STRNICMP(name, "screen", 6) == 0
- || STRNICMP(name, "dtterm", 6) == 0;
-}
-
-#if defined(USE_FNAME_CASE) || defined(PROTO)
-/*
- * Set the case of the file name, if it already exists. This will cause the
- * file name to remain exactly the same.
- * Only required for file systems where case is ignored and preserved.
- */
-void fname_case(
-char_u *name,
-int len; /* buffer size, only used when name gets longer */
-)
-{
- struct stat st;
- char_u *slash, *tail;
- DIR *dirp;
- struct dirent *dp;
-
- if (lstat((char *)name, &st) >= 0) {
- /* Open the directory where the file is located. */
- slash = vim_strrchr(name, '/');
- if (slash == NULL) {
- dirp = opendir(".");
- tail = name;
- } else {
- *slash = NUL;
- dirp = opendir((char *)name);
- *slash = '/';
- tail = slash + 1;
- }
-
- if (dirp != NULL) {
- while ((dp = readdir(dirp)) != NULL) {
- /* Only accept names that differ in case and are the same byte
- * length. TODO: accept different length name. */
- if (STRICMP(tail, dp->d_name) == 0
- && STRLEN(tail) == STRLEN(dp->d_name)) {
- char_u newname[MAXPATHL + 1];
- struct stat st2;
-
- /* Verify the inode is equal. */
- vim_strncpy(newname, name, MAXPATHL);
- vim_strncpy(newname + (tail - name), (char_u *)dp->d_name,
- MAXPATHL - (tail - name));
- if (lstat((char *)newname, &st2) >= 0
- && st.st_ino == st2.st_ino
- && st.st_dev == st2.st_dev) {
- STRCPY(tail, dp->d_name);
- break;
- }
- }
- }
-
- closedir(dirp);
- }
- }
-}
-#endif
-
-#if defined(HAVE_ACL) || defined(PROTO)
-# ifdef HAVE_SYS_ACL_H
-# include <sys/acl.h>
-# endif
-# ifdef HAVE_SYS_ACCESS_H
-# include <sys/access.h>
-# endif
-
-
-#if defined(HAVE_SELINUX) || defined(PROTO)
-/*
- * Copy security info from "from_file" to "to_file".
- */
-void mch_copy_sec(char_u *from_file, char_u *to_file)
-{
- if (from_file == NULL)
- return;
-
- if (selinux_enabled == -1)
- selinux_enabled = is_selinux_enabled();
-
- if (selinux_enabled > 0) {
- security_context_t from_context = NULL;
- security_context_t to_context = NULL;
-
- if (getfilecon((char *)from_file, &from_context) < 0) {
- /* If the filesystem doesn't support extended attributes,
- the original had no special security context and the
- target cannot have one either. */
- if (errno == EOPNOTSUPP)
- return;
-
- MSG_PUTS(_("\nCould not get security context for "));
- msg_outtrans(from_file);
- msg_putchar('\n');
- return;
- }
- if (getfilecon((char *)to_file, &to_context) < 0) {
- MSG_PUTS(_("\nCould not get security context for "));
- msg_outtrans(to_file);
- msg_putchar('\n');
- freecon (from_context);
- return;
- }
- if (strcmp(from_context, to_context) != 0) {
- if (setfilecon((char *)to_file, from_context) < 0) {
- MSG_PUTS(_("\nCould not set security context for "));
- msg_outtrans(to_file);
- msg_putchar('\n');
- }
- }
- freecon(to_context);
- freecon(from_context);
- }
-}
-#endif /* HAVE_SELINUX */
-
-/*
- * Return a pointer to the ACL of file "fname" in allocated memory.
- * Return NULL if the ACL is not available for whatever reason.
- */
-vim_acl_T mch_get_acl(char_u *fname)
-{
- vim_acl_T ret = NULL;
- return ret;
-}
-
-/*
- * Set the ACL of file "fname" to "acl" (unless it's NULL).
- */
-void mch_set_acl(char_u *fname, vim_acl_T aclent)
-{
- if (aclent == NULL)
- return;
-}
-
-void mch_free_acl(vim_acl_T aclent)
-{
- if (aclent == NULL)
- return;
-}
-#endif
-
-/*
- * Set hidden flag for "name".
- */
-void mch_hide(char_u *name)
-{
- /* can't hide a file */
-}
-
-/*
- * Check what "name" is:
- * NODE_NORMAL: file or directory (or doesn't exist)
- * NODE_WRITABLE: writable device, socket, fifo, etc.
- * NODE_OTHER: non-writable things
- */
-int mch_nodetype(char_u *name)
-{
- struct stat st;
-
- if (stat((char *)name, &st))
- return NODE_NORMAL;
- if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
- return NODE_NORMAL;
- if (S_ISBLK(st.st_mode)) /* block device isn't writable */
- return NODE_OTHER;
- /* Everything else is writable? */
- return NODE_WRITABLE;
-}
-
-void mch_early_init()
-{
- time_init();
-}
-
-#if defined(EXITFREE) || defined(PROTO)
-void mch_free_mem() {
- free(oldtitle);
- free(oldicon);
-}
-
-#endif
-
-static void exit_scroll(void);
-
-/*
- * Output a newline when exiting.
- * Make sure the newline goes to the same stream as the text.
- */
-static void exit_scroll()
-{
- if (silent_mode)
- return;
- if (newline_on_exit || msg_didout) {
- if (msg_use_printf()) {
- if (info_message)
- mch_msg("\n");
- else
- mch_errmsg("\r\n");
- } else
- out_char('\n');
- } else {
- restore_cterm_colors(); /* get original colors back */
- msg_clr_eos_force(); /* clear the rest of the display */
- windgoto((int)Rows - 1, 0); /* may have moved the cursor */
- }
-}
-
-void mch_exit(int r)
-{
- exiting = TRUE;
-
- event_teardown();
-
- {
- settmode(TMODE_COOK);
- mch_restore_title(3); /* restore xterm title and icon name */
- /*
- * When t_ti is not empty but it doesn't cause swapping terminal
- * pages, need to output a newline when msg_didout is set. But when
- * t_ti does swap pages it should not go to the shell page. Do this
- * before stoptermcap().
- */
- if (swapping_screen() && !newline_on_exit)
- exit_scroll();
-
- /* Stop termcap: May need to check for T_CRV response, which
- * requires RAW mode. */
- stoptermcap();
-
- /*
- * A newline is only required after a message in the alternate screen.
- * This is set to TRUE by wait_return().
- */
- if (!swapping_screen() || newline_on_exit)
- exit_scroll();
-
- /* Cursor may have been switched off without calling starttermcap()
- * when doing "vim -u vimrc" and vimrc contains ":q". */
- if (full_screen)
- cursor_on();
- }
- out_flush();
- ml_close_all(TRUE); /* remove all memfiles */
-
-#ifdef MACOS_CONVERT
- mac_conv_cleanup();
-#endif
-
-
-
-#ifdef EXITFREE
- free_all_mem();
-#endif
-
- exit(r);
-}
-
-void mch_settmode(int tmode)
-{
- static int first = TRUE;
-
- /* Why is NeXT excluded here (and not in os_unixx.h)? */
-#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
- defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
- /*
- * for "new" tty systems
- */
-# ifdef HAVE_TERMIOS_H
- static struct termios told;
- struct termios tnew;
-# else
- static struct termio told;
- struct termio tnew;
-# endif
-
- if (first) {
- first = FALSE;
-# if defined(HAVE_TERMIOS_H)
- tcgetattr(read_cmd_fd, &told);
-# else
- ioctl(read_cmd_fd, TCGETA, &told);
-# endif
- }
-
- tnew = told;
- if (tmode == TMODE_RAW) {
- /*
- * ~ICRNL enables typing ^V^M
- */
- tnew.c_iflag &= ~ICRNL;
- tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE
-# if defined(IEXTEN) && !defined(__MINT__)
- | IEXTEN /* IEXTEN enables typing ^V on SOLARIS */
- /* but it breaks function keys on MINT */
-# endif
- );
-# ifdef ONLCR /* don't map NL -> CR NL, we do it ourselves */
- tnew.c_oflag &= ~ONLCR;
-# endif
- tnew.c_cc[VMIN] = 1; /* return after 1 char */
- tnew.c_cc[VTIME] = 0; /* don't wait */
- } else if (tmode == TMODE_SLEEP)
- tnew.c_lflag &= ~(ECHO);
-
-# if defined(HAVE_TERMIOS_H)
- {
- int n = 10;
-
- /* A signal may cause tcsetattr() to fail (e.g., SIGCONT). Retry a
- * few times. */
- while (tcsetattr(read_cmd_fd, TCSANOW, &tnew) == -1
- && errno == EINTR && n > 0)
- --n;
- }
-# else
- ioctl(read_cmd_fd, TCSETA, &tnew);
-# endif
-
-#else
-
- /*
- * for "old" tty systems
- */
-# ifndef TIOCSETN
-# define TIOCSETN TIOCSETP /* for hpux 9.0 */
-# endif
- static struct sgttyb ttybold;
- struct sgttyb ttybnew;
-
- if (first) {
- first = FALSE;
- ioctl(read_cmd_fd, TIOCGETP, &ttybold);
- }
-
- ttybnew = ttybold;
- if (tmode == TMODE_RAW) {
- ttybnew.sg_flags &= ~(CRMOD | ECHO);
- ttybnew.sg_flags |= RAW;
- } else if (tmode == TMODE_SLEEP)
- ttybnew.sg_flags &= ~(ECHO);
- ioctl(read_cmd_fd, TIOCSETN, &ttybnew);
-#endif
- curr_tmode = tmode;
-}
-
-/*
- * Try to get the code for "t_kb" from the stty setting
- *
- * Even if termcap claims a backspace key, the user's setting *should*
- * prevail. stty knows more about reality than termcap does, and if
- * somebody's usual erase key is DEL (which, for most BSD users, it will
- * be), they're going to get really annoyed if their erase key starts
- * doing forward deletes for no reason. (Eric Fischer)
- */
-void get_stty()
-{
- char_u buf[2];
- char_u *p;
-
- /* Why is NeXT excluded here (and not in os_unixx.h)? */
-#if defined(ECHOE) && defined(ICANON) && (defined(HAVE_TERMIO_H) || \
- defined(HAVE_TERMIOS_H)) && !defined(__NeXT__)
- /* for "new" tty systems */
-# ifdef HAVE_TERMIOS_H
- struct termios keys;
-# else
- struct termio keys;
-# endif
-
-# if defined(HAVE_TERMIOS_H)
- if (tcgetattr(read_cmd_fd, &keys) != -1)
-# else
- if (ioctl(read_cmd_fd, TCGETA, &keys) != -1)
-# endif
- {
- buf[0] = keys.c_cc[VERASE];
- intr_char = keys.c_cc[VINTR];
-#else
- /* for "old" tty systems */
- struct sgttyb keys;
-
- if (ioctl(read_cmd_fd, TIOCGETP, &keys) != -1) {
- buf[0] = keys.sg_erase;
- intr_char = keys.sg_kill;
-#endif
- buf[1] = NUL;
- add_termcode((char_u *)"kb", buf, FALSE);
-
- /*
- * If <BS> and <DEL> are now the same, redefine <DEL>.
- */
- p = find_termcode((char_u *)"kD");
- if (p != NULL && p[0] == buf[0] && p[1] == buf[1])
- do_fixdel(NULL);
- }
-}
-
-/*
- * Set mouse clicks on or off.
- */
-void mch_setmouse(on)
-int on;
-{
- static int ison = FALSE;
- int xterm_mouse_vers;
-
- if (on == ison) /* return quickly if nothing to do */
- return;
-
- xterm_mouse_vers = use_xterm_mouse();
-
- if (ttym_flags == TTYM_URXVT) {
- out_str_nf((char_u *)
- (on
- ? IF_EB("\033[?1015h", ESC_STR "[?1015h")
- : IF_EB("\033[?1015l", ESC_STR "[?1015l")));
- ison = on;
- }
-
- if (ttym_flags == TTYM_SGR) {
- out_str_nf((char_u *)
- (on
- ? IF_EB("\033[?1006h", ESC_STR "[?1006h")
- : IF_EB("\033[?1006l", ESC_STR "[?1006l")));
- ison = on;
- }
-
- if (xterm_mouse_vers > 0) {
- if (on) /* enable mouse events, use mouse tracking if available */
- out_str_nf((char_u *)
- (xterm_mouse_vers > 1
- ? IF_EB("\033[?1002h", ESC_STR "[?1002h")
- : IF_EB("\033[?1000h", ESC_STR "[?1000h")));
- else /* disable mouse events, could probably always send the same */
- out_str_nf((char_u *)
- (xterm_mouse_vers > 1
- ? IF_EB("\033[?1002l", ESC_STR "[?1002l")
- : IF_EB("\033[?1000l", ESC_STR "[?1000l")));
- ison = on;
- } else if (ttym_flags == TTYM_DEC) {
- if (on) /* enable mouse events */
- out_str_nf((char_u *)"\033[1;2'z\033[1;3'{");
- else /* disable mouse events */
- out_str_nf((char_u *)"\033['z");
- ison = on;
- }
-
-}
-
-/*
- * Set the mouse termcode, depending on the 'term' and 'ttymouse' options.
- */
-void check_mouse_termcode()
-{
- if (use_xterm_mouse()
- && use_xterm_mouse() != 3
- ) {
- set_mouse_termcode(KS_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? IF_EB("\233M", CSI_STR "M")
- : IF_EB("\033[M", ESC_STR "[M")));
- if (*p_mouse != NUL) {
- /* force mouse off and maybe on to send possibly new mouse
- * activation sequence to the xterm, with(out) drag tracing. */
- mch_setmouse(FALSE);
- setmouse();
- }
- } else
- del_mouse_termcode(KS_MOUSE);
-
-
- /* There is no conflict, but one may type "ESC }" from Insert mode. Don't
- * define it in the GUI or when using an xterm. */
- if (!use_xterm_mouse()
- )
- set_mouse_termcode(KS_NETTERM_MOUSE,
- (char_u *)IF_EB("\033}", ESC_STR "}"));
- else
- del_mouse_termcode(KS_NETTERM_MOUSE);
-
- /* conflicts with xterm mouse: "\033[" and "\033[M" */
- if (!use_xterm_mouse()
- )
- set_mouse_termcode(KS_DEC_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? IF_EB("\233",
- CSI_STR) : IF_EB("\033[",
- ESC_STR "[")));
- else
- del_mouse_termcode(KS_DEC_MOUSE);
- /* same as the dec mouse */
- if (use_xterm_mouse() == 3
- ) {
- set_mouse_termcode(KS_URXVT_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? IF_EB("\233", CSI_STR)
- : IF_EB("\033[", ESC_STR "[")));
-
- if (*p_mouse != NUL) {
- mch_setmouse(FALSE);
- setmouse();
- }
- } else
- del_mouse_termcode(KS_URXVT_MOUSE);
- /* same as the dec mouse */
- if (use_xterm_mouse() == 4
- ) {
- set_mouse_termcode(KS_SGR_MOUSE, (char_u *)(term_is_8bit(T_NAME)
- ? IF_EB("\233<", CSI_STR "<")
- : IF_EB("\033[<", ESC_STR "[<")));
-
- if (*p_mouse != NUL) {
- mch_setmouse(FALSE);
- setmouse();
- }
- } else
- del_mouse_termcode(KS_SGR_MOUSE);
-}
-
-/*
- * Try to get the current window size:
- * 1. with an ioctl(), most accurate method
- * 2. from the environment variables LINES and COLUMNS
- * 3. from the termcap
- * 4. keep using the old values
- * Return OK when size could be determined, FAIL otherwise.
- */
-int mch_get_shellsize()
-{
- long rows = 0;
- long columns = 0;
- char_u *p;
-
- /*
- * 1. try using an ioctl. It is the most accurate method.
- *
- * Try using TIOCGWINSZ first, some systems that have it also define
- * TIOCGSIZE but don't have a struct ttysize.
- */
-# ifdef TIOCGWINSZ
- {
- struct winsize ws;
- int fd = 1;
-
- /* When stdout is not a tty, use stdin for the ioctl(). */
- if (!isatty(fd) && isatty(read_cmd_fd))
- fd = read_cmd_fd;
- if (ioctl(fd, TIOCGWINSZ, &ws) == 0) {
- columns = ws.ws_col;
- rows = ws.ws_row;
- }
- }
-# else /* TIOCGWINSZ */
-# ifdef TIOCGSIZE
- {
- struct ttysize ts;
- int fd = 1;
-
- /* When stdout is not a tty, use stdin for the ioctl(). */
- if (!isatty(fd) && isatty(read_cmd_fd))
- fd = read_cmd_fd;
- if (ioctl(fd, TIOCGSIZE, &ts) == 0) {
- columns = ts.ts_cols;
- rows = ts.ts_lines;
- }
- }
-# endif /* TIOCGSIZE */
-# endif /* TIOCGWINSZ */
-
- /*
- * 2. get size from environment
- * When being POSIX compliant ('|' flag in 'cpoptions') this overrules
- * the ioctl() values!
- */
- if (columns == 0 || rows == 0 || vim_strchr(p_cpo, CPO_TSIZE) != NULL) {
- if ((p = (char_u *)os_getenv("LINES")))
- rows = atoi((char *)p);
- if ((p = (char_u *)os_getenv("COLUMNS")))
- columns = atoi((char *)p);
- }
-
-#ifdef HAVE_TGETENT
- /*
- * 3. try reading "co" and "li" entries from termcap
- */
- if (columns == 0 || rows == 0)
- getlinecol(&columns, &rows);
-#endif
-
- /*
- * 4. If everything fails, use the old values
- */
- if (columns <= 0 || rows <= 0)
- return FAIL;
-
- Rows = rows;
- Columns = columns;
- limit_screen_size();
- return OK;
-}
-
-/*
- * Try to set the window size to Rows and Columns.
- */
-void mch_set_shellsize()
-{
- if (*T_CWS) {
- /*
- * NOTE: if you get an error here that term_set_winsize() is
- * undefined, check the output of configure. It could probably not
- * find a ncurses, termcap or termlib library.
- */
- term_set_winsize((int)Rows, (int)Columns);
- out_flush();
- screen_start(); /* don't know where cursor is now */
- }
-}
-
-/*
- * mch_expand_wildcards() - this code does wild-card pattern matching using
- * the shell
- *
- * return OK for success, FAIL for error (you may lose some memory) and put
- * an error message in *file.
- *
- * num_pat is number of input patterns
- * pat is array of pointers to input patterns
- * num_file is pointer to number of matched file names
- * file is pointer to array of pointers to matched file names
- */
-
-#ifndef SEEK_SET
-# define SEEK_SET 0
-#endif
-#ifndef SEEK_END
-# define SEEK_END 2
-#endif
-
-#define SHELL_SPECIAL (char_u *)"\t \"&'$;<>()\\|"
-
-int mch_expand_wildcards(num_pat, pat, num_file, file, flags)
-int num_pat;
-char_u **pat;
-int *num_file;
-char_u ***file;
-int flags; /* EW_* flags */
-{
- int i;
- size_t len;
- char_u *p;
- bool dir;
- char_u *extra_shell_arg = NULL;
- ShellOpts shellopts = kShellOptExpand | kShellOptSilent;
- int j;
- char_u *tempname;
- char_u *command;
- FILE *fd;
- char_u *buffer;
-#define STYLE_ECHO 0 /* use "echo", the default */
-#define STYLE_GLOB 1 /* use "glob", for csh */
-#define STYLE_VIMGLOB 2 /* use "vimglob", for Posix sh */
-#define STYLE_PRINT 3 /* use "print -N", for zsh */
-#define STYLE_BT 4 /* `cmd` expansion, execute the pattern
- * directly */
- int shell_style = STYLE_ECHO;
- int check_spaces;
- static int did_find_nul = FALSE;
- int ampersent = FALSE;
- /* vimglob() function to define for Posix shell */
- static char *sh_vimglob_func =
- "vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
-
- *num_file = 0; /* default: no files found */
- *file = NULL;
-
- /*
- * If there are no wildcards, just copy the names to allocated memory.
- * Saves a lot of time, because we don't have to start a new shell.
- */
- if (!have_wildcard(num_pat, pat)) {
- save_patterns(num_pat, pat, num_file, file);
- return OK;
- }
-
-# ifdef HAVE_SANDBOX
- /* Don't allow any shell command in the sandbox. */
- if (sandbox != 0 && check_secure())
- return FAIL;
-# endif
-
- /*
- * Don't allow the use of backticks in secure and restricted mode.
- */
- if (secure || restricted)
- for (i = 0; i < num_pat; ++i)
- if (vim_strchr(pat[i], '`') != NULL
- && (check_restricted() || check_secure()))
- return FAIL;
-
- /*
- * get a name for the temp file
- */
- if ((tempname = vim_tempname('o')) == NULL) {
- EMSG(_(e_notmp));
- return FAIL;
- }
-
- /*
- * Let the shell expand the patterns and write the result into the temp
- * file.
- * STYLE_BT: NL separated
- * If expanding `cmd` execute it directly.
- * STYLE_GLOB: NUL separated
- * If we use *csh, "glob" will work better than "echo".
- * STYLE_PRINT: NL or NUL separated
- * If we use *zsh, "print -N" will work better than "glob".
- * STYLE_VIMGLOB: NL separated
- * If we use *sh*, we define "vimglob()".
- * STYLE_ECHO: space separated.
- * A shell we don't know, stay safe and use "echo".
- */
- if (num_pat == 1 && *pat[0] == '`'
- && (len = STRLEN(pat[0])) > 2
- && *(pat[0] + len - 1) == '`')
- shell_style = STYLE_BT;
- else if ((len = STRLEN(p_sh)) >= 3) {
- if (STRCMP(p_sh + len - 3, "csh") == 0)
- shell_style = STYLE_GLOB;
- else if (STRCMP(p_sh + len - 3, "zsh") == 0)
- shell_style = STYLE_PRINT;
- }
- if (shell_style == STYLE_ECHO && strstr((char *)path_tail(p_sh),
- "sh") != NULL)
- shell_style = STYLE_VIMGLOB;
-
- /* Compute the length of the command. We need 2 extra bytes: for the
- * optional '&' and for the NUL.
- * Worst case: "unset nonomatch; print -N >" plus two is 29 */
- len = STRLEN(tempname) + 29;
- if (shell_style == STYLE_VIMGLOB)
- len += STRLEN(sh_vimglob_func);
-
- for (i = 0; i < num_pat; ++i) {
- /* Count the length of the patterns in the same way as they are put in
- * "command" below. */
- ++len; /* add space */
- for (j = 0; pat[i][j] != NUL; ++j) {
- if (vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
- ++len; /* may add a backslash */
- ++len;
- }
- }
- command = alloc(len);
-
- /*
- * Build the shell command:
- * - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
- * recognizes this).
- * - Add the shell command to print the expanded names.
- * - Add the temp file name.
- * - Add the file name patterns.
- */
- if (shell_style == STYLE_BT) {
- /* change `command; command& ` to (command; command ) */
- STRCPY(command, "(");
- STRCAT(command, pat[0] + 1); /* exclude first backtick */
- p = command + STRLEN(command) - 1;
- *p-- = ')'; /* remove last backtick */
- while (p > command && vim_iswhite(*p))
- --p;
- if (*p == '&') { /* remove trailing '&' */
- ampersent = TRUE;
- *p = ' ';
- }
- STRCAT(command, ">");
- } else {
- if (flags & EW_NOTFOUND)
- STRCPY(command, "set nonomatch; ");
- else
- STRCPY(command, "unset nonomatch; ");
- if (shell_style == STYLE_GLOB)
- STRCAT(command, "glob >");
- else if (shell_style == STYLE_PRINT)
- STRCAT(command, "print -N >");
- else if (shell_style == STYLE_VIMGLOB)
- STRCAT(command, sh_vimglob_func);
- else
- STRCAT(command, "echo >");
- }
-
- STRCAT(command, tempname);
-
- if (shell_style != STYLE_BT)
- for (i = 0; i < num_pat; ++i) {
- /* Put a backslash before special
- * characters, except inside ``. */
- int intick = FALSE;
-
- p = command + STRLEN(command);
- *p++ = ' ';
- for (j = 0; pat[i][j] != NUL; ++j) {
- if (pat[i][j] == '`')
- intick = !intick;
- else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL) {
- /* Remove a backslash, take char literally. But keep
- * backslash inside backticks, before a special character
- * and before a backtick. */
- if (intick
- || vim_strchr(SHELL_SPECIAL, pat[i][j + 1]) != NULL
- || pat[i][j + 1] == '`')
- *p++ = '\\';
- ++j;
- } else if (!intick && vim_strchr(SHELL_SPECIAL,
- pat[i][j]) != NULL)
- /* Put a backslash before a special character, but not
- * when inside ``. */
- *p++ = '\\';
-
- /* Copy one character. */
- *p++ = pat[i][j];
- }
- *p = NUL;
- }
-
- if (flags & EW_SILENT) {
- shellopts |= kShellOptHideMess;
- }
-
- if (ampersent)
- STRCAT(command, "&"); /* put the '&' after the redirection */
-
- /*
- * Using zsh -G: If a pattern has no matches, it is just deleted from
- * the argument list, otherwise zsh gives an error message and doesn't
- * expand any other pattern.
- */
- if (shell_style == STYLE_PRINT)
- extra_shell_arg = (char_u *)"-G"; /* Use zsh NULL_GLOB option */
-
- /*
- * If we use -f then shell variables set in .cshrc won't get expanded.
- * vi can do it, so we will too, but it is only necessary if there is a "$"
- * in one of the patterns, otherwise we can still use the fast option.
- */
- else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat))
- extra_shell_arg = (char_u *)"-f"; /* Use csh fast option */
-
- /*
- * execute the shell command
- */
- i = call_shell(
- command,
- shellopts,
- extra_shell_arg
- );
-
- /* When running in the background, give it some time to create the temp
- * file, but don't wait for it to finish. */
- if (ampersent)
- os_delay(10L, TRUE);
-
- free(command);
-
- if (i != 0) { /* mch_call_shell() failed */
- os_remove((char *)tempname);
- free(tempname);
- /*
- * With interactive completion, the error message is not printed.
- */
- if (!(flags & EW_SILENT))
- {
- redraw_later_clear(); /* probably messed up screen */
- msg_putchar('\n'); /* clear bottom line quickly */
- cmdline_row = Rows - 1; /* continue on last line */
- MSG(_(e_wildexpand));
- msg_start(); /* don't overwrite this message */
- }
-
- /* If a `cmd` expansion failed, don't list `cmd` as a match, even when
- * EW_NOTFOUND is given */
- if (shell_style == STYLE_BT)
- return FAIL;
- goto notfound;
- }
-
- /*
- * read the names from the file into memory
- */
- fd = fopen((char *)tempname, READBIN);
- if (fd == NULL) {
- /* Something went wrong, perhaps a file name with a special char. */
- if (!(flags & EW_SILENT)) {
- MSG(_(e_wildexpand));
- msg_start(); /* don't overwrite this message */
- }
- free(tempname);
- goto notfound;
- }
- fseek(fd, 0L, SEEK_END);
- len = ftell(fd); /* get size of temp file */
- fseek(fd, 0L, SEEK_SET);
- buffer = alloc(len + 1);
- i = fread((char *)buffer, 1, len, fd);
- fclose(fd);
- os_remove((char *)tempname);
- if (i != (int)len) {
- /* unexpected read error */
- EMSG2(_(e_notread), tempname);
- free(tempname);
- free(buffer);
- return FAIL;
- }
- free(tempname);
-
-
-
- /* file names are separated with Space */
- if (shell_style == STYLE_ECHO) {
- buffer[len] = '\n'; /* make sure the buffer ends in NL */
- p = buffer;
- for (i = 0; *p != '\n'; ++i) { /* count number of entries */
- while (*p != ' ' && *p != '\n')
- ++p;
- p = skipwhite(p); /* skip to next entry */
- }
- }
- /* file names are separated with NL */
- else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
- buffer[len] = NUL; /* make sure the buffer ends in NUL */
- p = buffer;
- for (i = 0; *p != NUL; ++i) { /* count number of entries */
- while (*p != '\n' && *p != NUL)
- ++p;
- if (*p != NUL)
- ++p;
- p = skipwhite(p); /* skip leading white space */
- }
- }
- /* file names are separated with NUL */
- else {
- /*
- * Some versions of zsh use spaces instead of NULs to separate
- * results. Only do this when there is no NUL before the end of the
- * buffer, otherwise we would never be able to use file names with
- * embedded spaces when zsh does use NULs.
- * When we found a NUL once, we know zsh is OK, set did_find_nul and
- * don't check for spaces again.
- */
- check_spaces = FALSE;
- if (shell_style == STYLE_PRINT && !did_find_nul) {
- /* If there is a NUL, set did_find_nul, else set check_spaces */
- buffer[len] = NUL;
- if (len && (int)STRLEN(buffer) < (int)len)
- did_find_nul = TRUE;
- else
- check_spaces = TRUE;
- }
-
- /*
- * Make sure the buffer ends with a NUL. For STYLE_PRINT there
- * already is one, for STYLE_GLOB it needs to be added.
- */
- if (len && buffer[len - 1] == NUL)
- --len;
- else
- buffer[len] = NUL;
- i = 0;
- for (p = buffer; p < buffer + len; ++p)
- if (*p == NUL || (*p == ' ' && check_spaces)) { /* count entry */
- ++i;
- *p = NUL;
- }
- if (len)
- ++i; /* count last entry */
- }
- if (i == 0) {
- /*
- * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
- * /bin/sh will happily expand it to nothing rather than returning an
- * error; and hey, it's good to check anyway -- webb.
- */
- free(buffer);
- goto notfound;
- }
- *num_file = i;
- *file = (char_u **)alloc(sizeof(char_u *) * i);
-
- /*
- * Isolate the individual file names.
- */
- p = buffer;
- for (i = 0; i < *num_file; ++i) {
- (*file)[i] = p;
- /* Space or NL separates */
- if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
- || shell_style == STYLE_VIMGLOB) {
- while (!(shell_style == STYLE_ECHO && *p == ' ')
- && *p != '\n' && *p != NUL)
- ++p;
- if (p == buffer + len) /* last entry */
- *p = NUL;
- else {
- *p++ = NUL;
- p = skipwhite(p); /* skip to next entry */
- }
- } else { /* NUL separates */
- while (*p && p < buffer + len) /* skip entry */
- ++p;
- ++p; /* skip NUL */
- }
- }
-
- /*
- * Move the file names to allocated memory.
- */
- for (j = 0, i = 0; i < *num_file; ++i) {
- /* Require the files to exist. Helps when using /bin/sh */
- if (!(flags & EW_NOTFOUND) && !os_file_exists((*file)[i]))
- continue;
-
- /* check if this entry should be included */
- dir = (os_isdir((*file)[i]));
- if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
- continue;
-
- /* Skip files that are not executable if we check for that. */
- if (!dir && (flags & EW_EXEC) && !os_can_exe((*file)[i]))
- continue;
-
- p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
- STRCPY(p, (*file)[i]);
- if (dir)
- add_pathsep(p); /* add '/' to a directory name */
- (*file)[j++] = p;
- }
- free(buffer);
- *num_file = j;
-
- if (*num_file == 0) { /* rejected all entries */
- free(*file);
- *file = NULL;
- goto notfound;
- }
-
- return OK;
-
-notfound:
- if (flags & EW_NOTFOUND) {
- save_patterns(num_pat, pat, num_file, file);
- return OK;
- }
- return FAIL;
-
-}
-
-
-static void save_patterns(num_pat, pat, num_file, file)
-int num_pat;
-char_u **pat;
-int *num_file;
-char_u ***file;
-{
- int i;
- char_u *s;
-
- *file = xmalloc((size_t)num_pat * sizeof(char_u *));
-
- for (i = 0; i < num_pat; i++) {
- s = vim_strsave(pat[i]);
- if (s != NULL)
- /* Be compatible with expand_filename(): halve the number of
- * backslashes. */
- backslash_halve(s);
- (*file)[i] = s;
- }
- *num_file = num_pat;
-}
-
-/*
- * Return TRUE if the string "p" contains a wildcard that mch_expandpath() can
- * expand.
- */
-int mch_has_exp_wildcard(p)
-char_u *p;
-{
- for (; *p; mb_ptr_adv(p)) {
- if (*p == '\\' && p[1] != NUL)
- ++p;
- else if (vim_strchr((char_u *)
- "*?[{'"
- , *p) != NULL)
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * Return TRUE if the string "p" contains a wildcard.
- * Don't recognize '~' at the end as a wildcard.
- */
-int mch_has_wildcard(p)
-char_u *p;
-{
- for (; *p; mb_ptr_adv(p)) {
- if (*p == '\\' && p[1] != NUL)
- ++p;
- else if (vim_strchr((char_u *)
- "*?[{`'$"
- , *p) != NULL
- || (*p == '~' && p[1] != NUL))
- return TRUE;
- }
- return FALSE;
-}
-
-static int have_wildcard(num, file)
-int num;
-char_u **file;
-{
- int i;
-
- for (i = 0; i < num; i++)
- if (mch_has_wildcard(file[i]))
- return 1;
- return 0;
-}
-
-static int have_dollars(num, file)
-int num;
-char_u **file;
-{
- int i;
-
- for (i = 0; i < num; i++)
- if (vim_strchr(file[i], '$') != NULL)
- return TRUE;
- return FALSE;
-}
-
-#if defined(FEAT_LIBCALL) || defined(PROTO)
-typedef char_u * (*STRPROCSTR)(char_u *);
-typedef char_u * (*INTPROCSTR)(int);
-typedef int (*STRPROCINT)(char_u *);
-typedef int (*INTPROCINT)(int);
-
-/*
- * Call a DLL routine which takes either a string or int param
- * and returns an allocated string.
- */
-int mch_libcall(libname, funcname, argstring, argint, string_result,
- number_result)
-char_u *libname;
-char_u *funcname;
-char_u *argstring; /* NULL when using a argint */
-int argint;
-char_u **string_result; /* NULL when using number_result */
-int *number_result;
-{
-# if defined(USE_DLOPEN)
- void *hinstLib;
- char *dlerr = NULL;
-# else
- shl_t hinstLib;
-# endif
- STRPROCSTR ProcAdd;
- INTPROCSTR ProcAddI;
- char_u *retval_str = NULL;
- int retval_int = 0;
- int success = FALSE;
-
- /*
- * Get a handle to the DLL module.
- */
-# if defined(USE_DLOPEN)
- /* First clear any error, it's not cleared by the dlopen() call. */
- (void)dlerror();
-
- hinstLib = dlopen((char *)libname, RTLD_LAZY
-# ifdef RTLD_LOCAL
- | RTLD_LOCAL
-# endif
- );
- if (hinstLib == NULL) {
- /* "dlerr" must be used before dlclose() */
- dlerr = (char *)dlerror();
- if (dlerr != NULL)
- EMSG2(_("dlerror = \"%s\""), dlerr);
- }
-# else
- hinstLib = shl_load((const char*)libname, BIND_IMMEDIATE|BIND_VERBOSE, 0L);
-# endif
-
- /* If the handle is valid, try to get the function address. */
- if (hinstLib != NULL) {
- /*
- * Catch a crash when calling the library function. For example when
- * using a number where a string pointer is expected.
- */
- mch_startjmp();
- if (SETJMP(lc_jump_env) != 0) {
- success = FALSE;
-# if defined(USE_DLOPEN)
- dlerr = NULL;
-# endif
- } else
- {
- retval_str = NULL;
- retval_int = 0;
-
- if (argstring != NULL) {
-# if defined(USE_DLOPEN)
- ProcAdd = (STRPROCSTR)dlsym(hinstLib, (const char *)funcname);
- dlerr = (char *)dlerror();
-# else
- if (shl_findsym(&hinstLib, (const char *)funcname,
- TYPE_PROCEDURE, (void *)&ProcAdd) < 0)
- ProcAdd = NULL;
-# endif
- if ((success = (ProcAdd != NULL
-# if defined(USE_DLOPEN)
- && dlerr == NULL
-# endif
- ))) {
- if (string_result == NULL)
- retval_int = ((STRPROCINT)ProcAdd)(argstring);
- else
- retval_str = (ProcAdd)(argstring);
- }
- } else {
-# if defined(USE_DLOPEN)
- ProcAddI = (INTPROCSTR)dlsym(hinstLib, (const char *)funcname);
- dlerr = (char *)dlerror();
-# else
- if (shl_findsym(&hinstLib, (const char *)funcname,
- TYPE_PROCEDURE, (void *)&ProcAddI) < 0)
- ProcAddI = NULL;
-# endif
- if ((success = (ProcAddI != NULL
-# if defined(USE_DLOPEN)
- && dlerr == NULL
-# endif
- ))) {
- if (string_result == NULL)
- retval_int = ((INTPROCINT)ProcAddI)(argint);
- else
- retval_str = (ProcAddI)(argint);
- }
- }
-
- /* Save the string before we free the library. */
- /* Assume that a "1" or "-1" result is an illegal pointer. */
- if (string_result == NULL)
- *number_result = retval_int;
- else if (retval_str != NULL
- && retval_str != (char_u *)1
- && retval_str != (char_u *)-1)
- *string_result = vim_strsave(retval_str);
- }
-
- mch_endjmp();
-# ifdef SIGHASARG
- if (lc_signal != 0) {
- int i;
-
- /* try to find the name of this signal */
- for (i = 0; signal_info[i].sig != -1; i++)
- if (lc_signal == signal_info[i].sig)
- break;
- EMSG2("E368: got SIG%s in libcall()", signal_info[i].name);
- }
-# endif
-
-# if defined(USE_DLOPEN)
- /* "dlerr" must be used before dlclose() */
- if (dlerr != NULL)
- EMSG2(_("dlerror = \"%s\""), dlerr);
-
- /* Free the DLL module. */
- (void)dlclose(hinstLib);
-# else
- (void)shl_unload(hinstLib);
-# endif
- }
-
- if (!success) {
- EMSG2(_(e_libcall), funcname);
- return FAIL;
- }
-
- return OK;
-}
-#endif
-
-
-