os_unix: Port mch_FullName and mch_isFullName to libuv.

Basically just delete conditional use of fchdir, since the other called
mch_* functions are already ported to libuv.
This commit is contained in:
Thomas Wienecke 2014-02-25 20:50:23 +01:00 committed by Thiago de Arruda
parent 60280ffa10
commit 8437a4c972
7 changed files with 93 additions and 123 deletions

View File

@ -12,6 +12,7 @@
*/
#include "vim.h"
#include "os/os.h"
/*
* Variables shared between getcmdline(), redrawcmdline() and others.

View File

@ -43,6 +43,7 @@
*/
#include "vim.h"
#include "os/os.h"
#ifndef UNIX /* it's in os_unix.h for Unix */
# include <time.h>

View File

@ -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 == '~';
}

View File

@ -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

View File

@ -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

View File

@ -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));

View File

@ -12,6 +12,7 @@
*/
#include "vim.h"
#include "os/os.h"
/*
* Structure that stores information about a highlight group.