diff options
-rw-r--r-- | src/ex_getln.c | 1 | ||||
-rw-r--r-- | src/memline.c | 1 | ||||
-rw-r--r-- | src/os/fs.c | 88 | ||||
-rw-r--r-- | src/os/os.h | 2 | ||||
-rw-r--r-- | src/os_unix.c | 121 | ||||
-rw-r--r-- | src/proto/os_unix.pro | 2 | ||||
-rw-r--r-- | src/syntax.c | 1 |
7 files changed, 93 insertions, 123 deletions
diff --git a/src/ex_getln.c b/src/ex_getln.c index 9637b64f2d..83a0fd3dcc 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -12,6 +12,7 @@ */ #include "vim.h" +#include "os/os.h" /* * Variables shared between getcmdline(), redrawcmdline() and others. diff --git a/src/memline.c b/src/memline.c index 2f8fd69669..09818a5115 100644 --- a/src/memline.c +++ b/src/memline.c @@ -43,6 +43,7 @@ */ #include "vim.h" +#include "os/os.h" #ifndef UNIX /* it's in os_unix.h for Unix */ # include <time.h> diff --git a/src/os/fs.c b/src/os/fs.c index e9a76c6b79..e9fe651b6b 100644 --- a/src/os/fs.c +++ b/src/os/fs.c @@ -37,3 +37,91 @@ int mch_dirname(char_u *buf, int len) } return OK; } + +/* + * Get absolute file name into "buf[len]". + * + * return FAIL for failure, OK for success + */ +int mch_FullName( + char_u *fname, + char_u *buf, + int len, + int force /* also expand when already absolute path */ + ) +{ + int l; + 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) { + + /* Only change directory when we are sure we can return to where + * we are now. After doing "su" chdir(".") might not work. */ + if ((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) { + 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(char_u *fname) +{ + return *fname == '/' || *fname == '~'; +} + diff --git a/src/os/os.h b/src/os/os.h index 099f53312f..9cf2116091 100644 --- a/src/os/os.h +++ b/src/os/os.h @@ -6,5 +6,7 @@ long_u mch_total_mem(int special); int mch_chdir(char *path); int mch_dirname(char_u *buf, int len); +int mch_FullName (char_u *fname, char_u *buf, int len, int force); +int mch_isFullName (char_u *fname); #endif diff --git a/src/os_unix.c b/src/os_unix.c index 2bfddafc6c..4bc4024abb 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1244,127 +1244,6 @@ static char * strerror(int err) } #endif -/* - * Get absolute file name into "buf[len]". - * - * return FAIL for failure, OK for success - */ -int mch_FullName( - char_u *fname, - char_u *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(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 diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro index 64be80500c..3d03df1eaf 100644 --- a/src/proto/os_unix.pro +++ b/src/proto/os_unix.pro @@ -28,8 +28,6 @@ int mch_get_uname __ARGS((uid_t uid, char_u *s, int len)); void mch_get_host_name __ARGS((char_u *s, int len)); long mch_get_pid __ARGS((void)); void slash_adjust __ARGS((char_u *p)); -int mch_FullName __ARGS((char_u *fname, char_u *buf, int len, int force)); -int mch_isFullName __ARGS((char_u *fname)); void fname_case __ARGS((char_u *name, int len)); long mch_getperm __ARGS((char_u *name)); int mch_setperm __ARGS((char_u *name, long perm)); diff --git a/src/syntax.c b/src/syntax.c index c600b2f2a1..e576185b7d 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -12,6 +12,7 @@ */ #include "vim.h" +#include "os/os.h" /* * Structure that stores information about a highlight group. |