diff options
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 527 |
1 files changed, 119 insertions, 408 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 344be7b0df..856191ea95 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -28,11 +28,27 @@ # define select select_declared_wrong #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 "message.h" +#include "misc1.h" +#include "misc2.h" +#include "screen.h" +#include "syntax.h" +#include "term.h" +#include "ui.h" +#include "os/os.h" #include "os_unixx.h" /* unix includes for os_unix.c only */ - #ifdef HAVE_SELINUX # include <selinux/selinux.h> static int selinux_enabled = -1; @@ -221,23 +237,10 @@ static struct signalinfo { {-1, "Unknown!", FALSE} }; -int mch_chdir(path) -char *path; -{ - if (p_verbose >= 5) { - verbose_enter(); - smsg((char_u *)"chdir(%s)", path); - verbose_leave(); - } - return chdir(path); -} - /* * Write s[len] to the screen. */ -void mch_write(s, len) -char_u *s; -int len; +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 */ @@ -252,74 +255,75 @@ int len; * If wtime == n wait a short time for characters. * If wtime == -1 wait forever for characters. */ -int mch_inchar(buf, maxlen, wtime, tb_change_cnt) -char_u *buf; -int maxlen; -long wtime; /* don't use "time", MIPS cannot handle it */ -int tb_change_cnt; +int mch_inchar( + char_u *buf, + int maxlen, + long wtime, /* don't use "time", MIPS cannot handle it */ + int tb_change_cnt + ) { - int len; + int len; - /* Check if window changed size while we were busy, perhaps the ":set - * columns=99" command was used. */ - while (do_resize) - handle_resize(); + /* Check if window changed size while we were busy, perhaps the ":set + * columns=99" command was used. */ + while (do_resize) + handle_resize(); - if (wtime >= 0) { - while (WaitForChar(wtime) == 0) { /* no character available */ - if (!do_resize) /* return if not interrupted by resize */ - return 0; - handle_resize(); - } - } else { /* wtime == -1 */ - /* - * If there is no character available within 'updatetime' seconds - * flush all the swap files to disk. - * Also done when interrupted by SIGWINCH. - */ - if (WaitForChar(p_ut) == 0) { - if (trigger_cursorhold() && maxlen >= 3 - && !typebuf_changed(tb_change_cnt)) { - buf[0] = K_SPECIAL; - buf[1] = KS_EXTRA; - buf[2] = (int)KE_CURSORHOLD; - return 3; - } - before_blocking(); + if (wtime >= 0) { + while (WaitForChar(wtime) == 0) { /* no character available */ + if (!do_resize) /* return if not interrupted by resize */ + return 0; + handle_resize(); + } + } else { /* wtime == -1 */ + /* + * If there is no character available within 'updatetime' seconds + * flush all the swap files to disk. + * Also done when interrupted by SIGWINCH. + */ + if (WaitForChar(p_ut) == 0) { + if (trigger_cursorhold() && maxlen >= 3 + && !typebuf_changed(tb_change_cnt)) { + buf[0] = K_SPECIAL; + buf[1] = KS_EXTRA; + buf[2] = (int)KE_CURSORHOLD; + return 3; + } + before_blocking(); + } } - } - for (;; ) { /* repeat until we got a character */ - while (do_resize) /* window changed size */ - handle_resize(); + for (;; ) { /* repeat until we got a character */ + while (do_resize) /* window changed size */ + handle_resize(); - /* - * We want to be interrupted by the winch signal - * or by an event on the monitored file descriptors. - */ - if (WaitForChar(-1L) == 0) { - if (do_resize) /* interrupted by SIGWINCH signal */ - handle_resize(); - return 0; - } + /* + * We want to be interrupted by the winch signal + * or by an event on the monitored file descriptors. + */ + if (WaitForChar(-1L) == 0) { + if (do_resize) /* interrupted by SIGWINCH signal */ + handle_resize(); + return 0; + } - /* If input was put directly in typeahead buffer bail out here. */ - if (typebuf_changed(tb_change_cnt)) - return 0; + /* If input was put directly in typeahead buffer bail out here. */ + if (typebuf_changed(tb_change_cnt)) + return 0; - /* - * For some terminals we only get one character at a time. - * We want the get all available characters, so we could keep on - * trying until none is available - * For some other terminals this is quite slow, that's why we don't do - * it. - */ - len = read_from_input_buf(buf, (long)maxlen); - if (len > 0) { - return len; + /* + * For some terminals we only get one character at a time. + * We want the get all available characters, so we could keep on + * trying until none is available + * For some other terminals this is quite slow, that's why we don't do + * it. + */ + len = read_from_input_buf(buf, (long)maxlen); + if (len > 0) { + return len; + } } - } } static void handle_resize() { @@ -334,105 +338,7 @@ int mch_char_avail() { return WaitForChar(0L); } -#if defined(HAVE_TOTAL_MEM) || defined(PROTO) -# ifdef HAVE_SYS_RESOURCE_H -# include <sys/resource.h> -# endif -# if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTL) -# include <sys/sysctl.h> -# endif -# if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO) -# include <sys/sysinfo.h> -# endif - -/* - * Return total amount of memory available in Kbyte. - * Doesn't change when memory has been allocated. - */ -long_u mch_total_mem(special) -int special UNUSED; -{ - long_u mem = 0; - long_u shiftright = 10; /* how much to shift "mem" right for Kbyte */ - -# ifdef HAVE_SYSCTL - int mib[2], physmem; - size_t len; - - /* BSD way of getting the amount of RAM available. */ - mib[0] = CTL_HW; - mib[1] = HW_USERMEM; - len = sizeof(physmem); - if (sysctl(mib, 2, &physmem, &len, NULL, 0) == 0) - mem = (long_u)physmem; -# endif - -# if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO) - if (mem == 0) { - struct sysinfo sinfo; - - /* Linux way of getting amount of RAM available */ - if (sysinfo(&sinfo) == 0) { -# ifdef HAVE_SYSINFO_MEM_UNIT - /* avoid overflow as much as possible */ - while (shiftright > 0 && (sinfo.mem_unit & 1) == 0) { - sinfo.mem_unit = sinfo.mem_unit >> 1; - --shiftright; - } - mem = sinfo.totalram * sinfo.mem_unit; -# else - mem = sinfo.totalram; -# endif - } - } -# endif - -# ifdef HAVE_SYSCONF - if (mem == 0) { - long pagesize, pagecount; - - /* Solaris way of getting amount of RAM available */ - pagesize = sysconf(_SC_PAGESIZE); - pagecount = sysconf(_SC_PHYS_PAGES); - if (pagesize > 0 && pagecount > 0) { - /* avoid overflow as much as possible */ - while (shiftright > 0 && (pagesize & 1) == 0) { - pagesize = (long_u)pagesize >> 1; - --shiftright; - } - mem = (long_u)pagesize * pagecount; - } - } -# endif - - /* Return the minimum of the physical memory and the user limit, because - * using more than the user limit may cause Vim to be terminated. */ -# if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT) - { - struct rlimit rlp; - - if (getrlimit(RLIMIT_DATA, &rlp) == 0 - && rlp.rlim_cur < ((rlim_t)1 << (sizeof(long_u) * 8 - 1)) -# ifdef RLIM_INFINITY - && rlp.rlim_cur != RLIM_INFINITY -# endif - && ((long_u)rlp.rlim_cur >> 10) < (mem >> shiftright) - ) { - mem = (long_u)rlp.rlim_cur; - shiftright = 10; - } - } -# endif - - if (mem > 0) - return mem >> shiftright; - return (long_u)0x1fffff; -} -#endif - -void mch_delay(msec, ignoreinput) -long msec; -int ignoreinput; +void mch_delay(long msec, int ignoreinput) { int old_tmode; @@ -508,8 +414,7 @@ static int stack_grows_downwards; * Find out if the stack grows upwards or downwards. * "p" points to a variable on the stack of the caller. */ -static void check_stack_growth(p) -char *p; +static void check_stack_growth(char *p) { int i; @@ -577,8 +482,7 @@ static void get_stack_limit() { * Return FAIL when running out of stack space. * "p" must point to any variable local to the caller that's on the stack. */ -int mch_stackcheck(p) -char *p; +int mch_stackcheck(char *p) { if (stack_limit != NULL) { if (stack_grows_downwards) { @@ -1005,9 +909,10 @@ void reset_signals() { #endif } -static void catch_signals(func_deadly, func_other) -RETSIGTYPE (*func_deadly)(); -RETSIGTYPE (*func_other)(); +static void catch_signals( + RETSIGTYPE (*func_deadly)(), + RETSIGTYPE (*func_other)() + ) { int i; @@ -1056,8 +961,7 @@ RETSIGTYPE (*func_other)(); * signal * Returns TRUE when Vim should exit. */ -int vim_handle_signal(sig) -int sig; +int vim_handle_signal(int sig) { static int got_signal = 0; static int blocked = TRUE; @@ -1088,9 +992,7 @@ int sig; /* * Check_win checks whether we have an interactive stdout. */ -int mch_check_win(argc, argv) -int argc UNUSED; -char **argv UNUSED; +int mch_check_win(int argc, char **argv) { if (isatty(1)) return OK; @@ -1106,14 +1008,12 @@ int mch_input_isatty() { return FALSE; } -static int get_x11_title(test_only) -int test_only UNUSED; +static int get_x11_title(int test_only) { return FALSE; } -static int get_x11_icon(test_only) -int test_only; +static int get_x11_icon(int test_only) { if (!test_only) { if (STRNCMP(T_NAME, "builtin_", 8) == 0) @@ -1136,9 +1036,7 @@ int mch_can_restore_icon() { /* * Set the window title and icon. */ -void mch_settitle(title, icon) -char_u *title; -char_u *icon; +void mch_settitle(char_u *title, char_u *icon) { int type = 0; static int recursive = 0; @@ -1195,8 +1093,7 @@ char_u *icon; * 2 only restore icon * 3 restore title and icon */ -void mch_restore_title(which) -int which; +void mch_restore_title(int which) { /* only restore the title or icon when it has been set */ mch_settitle(((which & 1) && did_set_title) ? @@ -1209,8 +1106,7 @@ int which; * Return TRUE if "name" looks like some xterm name. * Seiichi Sato mentioned that "mlterm" works like xterm. */ -int vim_is_xterm(name) -char_u *name; +int vim_is_xterm(char_u *name) { if (name == NULL) return FALSE; @@ -1227,8 +1123,7 @@ char_u *name; * 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(name) -char_u *name; +int use_xterm_like_mouse(char_u *name) { return name != NULL && (term_is_xterm || STRNICMP(name, "screen", 6) == 0); @@ -1253,8 +1148,7 @@ int use_xterm_mouse() { return 0; } -int vim_is_iris(name) -char_u *name; +int vim_is_iris(char_u *name) { if (name == NULL) return FALSE; @@ -1262,8 +1156,7 @@ char_u *name; || STRCMP(name, "builtin_iris-ansi") == 0; } -int vim_is_vt300(name) -char_u *name; +int vim_is_vt300(char_u *name) { if (name == NULL) return FALSE; /* actually all ANSI comp. terminals should be here */ @@ -1277,8 +1170,7 @@ char_u *name; * Return TRUE if "name" is a terminal for which 'ttyfast' should be set. * This should include all windowed terminal emulators. */ -int vim_is_fastterm(name) -char_u *name; +int vim_is_fastterm(char_u *name) { if (name == NULL) return FALSE; @@ -1294,9 +1186,7 @@ char_u *name; * Insert user name in s[len]. * Return OK if a name found. */ -int mch_get_user_name(s, len) -char_u *s; -int len; +int mch_get_user_name(char_u *s, int len) { return mch_get_uname(getuid(), s, len); } @@ -1305,10 +1195,7 @@ int len; * Insert user name for "uid" in s[len]. * Return OK if a name found. */ -int mch_get_uname(uid, s, len) -uid_t uid; -char_u *s; -int len; +int mch_get_uname(uid_t uid, char_u *s, int len) { #if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID) struct passwd *pw; @@ -1328,9 +1215,7 @@ int len; */ #ifdef HAVE_SYS_UTSNAME_H -void mch_get_host_name(s, len) -char_u *s; -int len; +void mch_get_host_name(char_u *s, int len) { struct utsname vutsname; @@ -1345,9 +1230,7 @@ int len; # define gethostname(nam, len) sysinfo(SI_HOSTNAME, nam, len) # endif -void mch_get_host_name(s, len) -char_u *s; -int len; +void mch_get_host_name(char_u *s, int len) { gethostname((char *)s, len); s[len - 1] = NUL; /* make sure it's terminated */ @@ -1361,172 +1244,16 @@ long mch_get_pid() { return (long)getpid(); } -#if !defined(HAVE_STRERROR) && defined(USE_GETCWD) -static char *strerror __ARGS((int)); - -static char * strerror(err) -int err; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - static char er[20]; - - if (err > 0 && err < sys_nerr) - return sys_errlist[err]; - sprintf(er, "Error %d", err); - return er; -} -#endif - -/* - * Get name of current directory into buffer 'buf' of length 'len' bytes. - * Return OK for success, FAIL for failure. - */ -int mch_dirname(buf, len) -char_u *buf; -int len; -{ -#if defined(USE_GETCWD) - if (getcwd((char *)buf, len) == NULL) { - STRCPY(buf, strerror(errno)); - return FAIL; - } - return OK; -#else - return getwd((char *)buf) != NULL ? OK : FAIL; -#endif -} - - -/* - * Get absolute file name into "buf[len]". - * - * return FAIL for failure, OK for success - */ -int mch_FullName(fname, buf, len, force) -char_u *fname, *buf; -int len; -int force; /* also expand when already absolute path */ -{ - int l; -#ifdef HAVE_FCHDIR - int fd = -1; - static int dont_fchdir = FALSE; /* TRUE when fchdir() doesn't work */ -#endif - char_u olddir[MAXPATHL]; - char_u *p; - int retval = OK; - - - - /* expand it if forced or not an absolute path */ - if (force || !mch_isFullName(fname)) { - /* - * If the file name has a path, change to that directory for a moment, - * and then do the getwd() (and get back to where we were). - * This will get the correct path name with "../" things. - */ - if ((p = vim_strrchr(fname, '/')) != NULL) { -#ifdef HAVE_FCHDIR - /* - * Use fchdir() if possible, it's said to be faster and more - * reliable. But on SunOS 4 it might not work. Check this by - * doing a fchdir() right now. - */ - if (!dont_fchdir) { - fd = open(".", O_RDONLY | O_EXTRA, 0); - if (fd >= 0 && fchdir(fd) < 0) { - close(fd); - fd = -1; - dont_fchdir = TRUE; /* don't try again */ - } - } -#endif - - /* Only change directory when we are sure we can return to where - * we are now. After doing "su" chdir(".") might not work. */ - if ( -#ifdef HAVE_FCHDIR - fd < 0 && -#endif - (mch_dirname(olddir, MAXPATHL) == FAIL - || mch_chdir((char *)olddir) != 0)) { - p = NULL; /* can't get current dir: don't chdir */ - retval = FAIL; - } else { - /* The directory is copied into buf[], to be able to remove - * the file name without changing it (could be a string in - * read-only memory) */ - if (p - fname >= len) - retval = FAIL; - else { - vim_strncpy(buf, fname, p - fname); - if (mch_chdir((char *)buf)) - retval = FAIL; - else - fname = p + 1; - *buf = NUL; - } - } - } - if (mch_dirname(buf, len) == FAIL) { - retval = FAIL; - *buf = NUL; - } - if (p != NULL) { -#ifdef HAVE_FCHDIR - if (fd >= 0) { - if (p_verbose >= 5) { - verbose_enter(); - MSG("fchdir() to previous dir"); - verbose_leave(); - } - l = fchdir(fd); - close(fd); - } else -#endif - l = mch_chdir((char *)olddir); - if (l != 0) - EMSG(_(e_prev_dir)); - } - - l = STRLEN(buf); - if (l >= len - 1) - retval = FAIL; /* no space for trailing "/" */ - else if (l > 0 && buf[l - 1] != '/' && *fname != NUL - && STRCMP(fname, ".") != 0) - STRCAT(buf, "/"); - } - - /* Catch file names which are too long. */ - if (retval == FAIL || (int)(STRLEN(buf) + STRLEN(fname)) >= len) - return FAIL; - - /* Do not append ".", "/dir/." is equal to "/dir". */ - if (STRCMP(fname, ".") != 0) - STRCAT(buf, fname); - - return OK; -} - -/* - * Return TRUE if "fname" does not depend on the current directory. - */ -int mch_isFullName(fname) -char_u *fname; -{ - return *fname == '/' || *fname == '~'; -} - #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(name, len) -char_u *name; -int len UNUSED; /* buffer size, only used when name gets longer */ +void fname_case( +char_u *name, +int len; /* buffer size, only used when name gets longer */ +) { struct stat st; char_u *slash, *tail; @@ -1578,8 +1305,7 @@ int len UNUSED; /* buffer size, only used when name gets longer */ * Get file permissions for 'name'. * Returns -1 when it doesn't exist. */ -long mch_getperm(name) -char_u *name; +long mch_getperm(char_u *name) { struct stat statb; @@ -1600,9 +1326,7 @@ char_u *name; * * return FAIL for failure, OK otherwise */ -int mch_setperm(name, perm) -char_u *name; -long perm; +int mch_setperm(char_u *name, long perm) { return chmod((char *) name, @@ -1622,9 +1346,7 @@ long perm; /* * Copy security info from "from_file" to "to_file". */ -void mch_copy_sec(from_file, to_file) -char_u *from_file; -char_u *to_file; +void mch_copy_sec(char_u *from_file, char_u *to_file) { if (from_file == NULL) return; @@ -1672,8 +1394,7 @@ char_u *to_file; * 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(fname) -char_u *fname UNUSED; +vim_acl_T mch_get_acl(char_u *fname) { vim_acl_T ret = NULL; return ret; @@ -1682,16 +1403,13 @@ char_u *fname UNUSED; /* * Set the ACL of file "fname" to "acl" (unless it's NULL). */ -void mch_set_acl(fname, aclent) -char_u *fname UNUSED; -vim_acl_T aclent; +void mch_set_acl(char_u *fname, vim_acl_T aclent) { if (aclent == NULL) return; } -void mch_free_acl(aclent) -vim_acl_T aclent; +void mch_free_acl(vim_acl_T aclent) { if (aclent == NULL) return; @@ -1701,8 +1419,7 @@ vim_acl_T aclent; /* * Set hidden flag for "name". */ -void mch_hide(name) -char_u *name UNUSED; +void mch_hide(char_u *name) { /* can't hide a file */ } @@ -1712,8 +1429,7 @@ char_u *name UNUSED; * return FALSE if "name" is not a directory * return FALSE for error */ -int mch_isdir(name) -char_u *name; +int mch_isdir(char_u *name) { struct stat statb; @@ -1733,8 +1449,7 @@ static int executable_file __ARGS((char_u *name)); /* * Return 1 if "name" is an executable file, 0 if not or it doesn't exist. */ -static int executable_file(name) -char_u *name; +static int executable_file(char_u *name) { struct stat st; @@ -1747,8 +1462,7 @@ char_u *name; * Return 1 if "name" can be found in $PATH and executed, 0 if not. * Return -1 if unknown. */ -int mch_can_exe(name) -char_u *name; +int mch_can_exe(char_u *name) { char_u *buf; char_u *p, *e; @@ -1801,8 +1515,7 @@ char_u *name; * NODE_WRITABLE: writable device, socket, fifo, etc. * NODE_OTHER: non-writable things */ -int mch_nodetype(name) -char_u *name; +int mch_nodetype(char_u *name) { struct stat st; @@ -1876,8 +1589,7 @@ static void exit_scroll() { } } -void mch_exit(r) -int r; +void mch_exit(int r) { exiting = TRUE; @@ -1934,8 +1646,7 @@ static void may_core_dump() { } } -void mch_settmode(tmode) -int tmode; +void mch_settmode(int tmode) { static int first = TRUE; @@ -2196,7 +1907,7 @@ void check_mouse_termcode() { * set screen mode, always fails. */ int mch_screenmode(arg) -char_u *arg UNUSED; +char_u *arg; { EMSG(_(e_screenmode)); return FAIL; @@ -3153,7 +2864,7 @@ long msec; static int RealWaitForChar(fd, msec, check_for_gpm) int fd; long msec; -int *check_for_gpm UNUSED; +int *check_for_gpm; { int ret; |