aboutsummaryrefslogtreecommitdiffhomepage
path: root/path.cpp
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2011-12-26 19:18:46 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2011-12-26 19:18:46 -0800
commit8d2f107d61a8b0e099ab9a59b8a32c236da5a5fc (patch)
tree89f718ab74f8400332534aee237c6f925348f05c /path.cpp
parent3f16ace6784caab54fb054836ee93902e9701913 (diff)
Some changes to migrate towards C++ and a multithreaded model
Diffstat (limited to 'path.cpp')
-rw-r--r--path.cpp218
1 files changed, 197 insertions, 21 deletions
diff --git a/path.cpp b/path.cpp
index 50288d2a..00f747c2 100644
--- a/path.cpp
+++ b/path.cpp
@@ -25,14 +25,115 @@
*/
#define MISSING_COMMAND_ERR_MSG _( L"Error while searching for command '%ls'" )
+bool path_get_path_string(const wcstring &cmd_str, wcstring &output, const env_vars &vars)
+{
+ const wchar_t * const cmd = cmd_str.c_str();
+ int err = ENOENT;
+ debug( 3, L"path_get_path_string( '%ls' )", cmd );
+
+ if(wcschr( cmd, L'/' ) != 0 )
+ {
+ if( waccess( cmd, X_OK )==0 )
+ {
+ struct stat buff;
+ if(wstat( cmd, &buff ))
+ {
+ return false;
+ }
+
+ if (S_ISREG(buff.st_mode))
+ {
+ output = cmd_str;
+ return true;
+ }
+ else
+ {
+ errno = EACCES;
+ return false;
+ }
+ }
+ else
+ {
+ //struct stat buff;
+ //wstat( cmd, &buff );
+ return false;
+ }
+
+ }
+ else
+ {
+ const wchar_t *path = vars.get(L"PATH");
+ if( path == 0 )
+ {
+ if( contains( PREFIX L"/bin", L"/bin", L"/usr/bin" ) )
+ {
+ path = L"/bin" ARRAY_SEP_STR L"/usr/bin";
+ }
+ else
+ {
+ path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
+ }
+ }
+
+ wcstokenizer tokenizer(path, ARRAY_SEP_STR);
+ wcstring new_cmd;
+ while (tokenizer.next(new_cmd))
+ {
+ size_t path_len = new_cmd.size();
+ if (path_len == 0) continue;
+
+ append_path_component(new_cmd, cmd_str);
+ if( waccess( new_cmd.c_str(), X_OK )==0 )
+ {
+ struct stat buff;
+ if( wstat( new_cmd.c_str(), &buff )==-1 )
+ {
+ if( errno != EACCES )
+ {
+ wperror( L"stat" );
+ }
+ continue;
+ }
+ if( S_ISREG(buff.st_mode) )
+ {
+ output = new_cmd;
+ return true;
+ }
+ err = EACCES;
+
+ }
+ else
+ {
+ switch( errno )
+ {
+ case ENOENT:
+ case ENAMETOOLONG:
+ case EACCES:
+ case ENOTDIR:
+ break;
+ default:
+ {
+ debug( 1,
+ MISSING_COMMAND_ERR_MSG,
+ new_cmd.c_str() );
+ wperror( L"access" );
+ }
+ }
+ }
+ }
+ }
+
+ errno = err;
+ return false;
+}
wchar_t *path_get_path( void *context, const wchar_t *cmd )
{
wchar_t *path;
int err = ENOENT;
-
+
CHECK( cmd, 0 );
debug( 3, L"path_get_path( '%ls' )", cmd );
@@ -46,7 +147,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
{
return 0;
}
-
+
if( S_ISREG(buff.st_mode) )
return halloc_wcsdup( context, cmd );
else
@@ -61,7 +162,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
wstat( cmd, &buff );
return 0;
}
-
+
}
else
{
@@ -77,12 +178,12 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
path = L"/bin" ARRAY_SEP_STR L"/usr/bin" ARRAY_SEP_STR PREFIX L"/bin";
}
}
-
+
/*
Allocate string long enough to hold the whole command
*/
- wchar_t *new_cmd = halloc( context, sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
-
+ wchar_t *new_cmd = (wchar_t *)halloc( context, sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
+
/*
We tokenize a copy of the path, since strtok modifies
its arguments
@@ -90,7 +191,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
wchar_t *path_cpy = wcsdup( path );
wchar_t *nxt_path = path;
wchar_t *state;
-
+
if( (new_cmd==0) || (path_cpy==0) )
{
DIE_MEM();
@@ -124,7 +225,7 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
return new_cmd;
}
err = EACCES;
-
+
}
else
{
@@ -154,7 +255,82 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
}
-wchar_t *path_get_cdpath( void *context, wchar_t *dir )
+bool path_get_cdpath_string(const wcstring &dir_str, wcstring &result, const env_vars &vars)
+{
+ wchar_t *res = 0;
+ int err = ENOENT;
+ bool success = false;
+
+ const wchar_t *const dir = dir_str.c_str();
+ if( dir[0] == L'/'|| (wcsncmp( dir, L"./", 2 )==0) )
+ {
+ struct stat buf;
+ if( wstat( dir, &buf ) == 0 )
+ {
+ if( S_ISDIR(buf.st_mode) )
+ {
+ result = dir_str;
+ success = true;
+ }
+ else
+ {
+ err = ENOTDIR;
+ }
+
+ }
+ }
+ else
+ {
+ const wchar_t *path = vars.get(L"CDPATH");
+ if( !path || !wcslen(path) )
+ {
+ path = L".";
+ }
+
+ wcstokenizer tokenizer(path, ARRAY_SEP_STR);
+ wcstring next_path;
+ while (tokenizer.next(next_path))
+ {
+ expand_tilde(next_path);
+ if (next_path.size() == 0) continue;
+
+ wcstring whole_path = next_path;
+ append_path_component(whole_path, dir);
+
+ struct stat buf;
+ if( wstat( whole_path.c_str(), &buf ) == 0 )
+ {
+ if( S_ISDIR(buf.st_mode) )
+ {
+ result = whole_path;
+ success = true;
+ break;
+ }
+ else
+ {
+ err = ENOTDIR;
+ }
+ }
+ else
+ {
+ if( lwstat( whole_path.c_str(), &buf ) == 0 )
+ {
+ err = EROTTEN;
+ }
+ }
+ }
+ }
+
+
+ if( !success )
+ {
+ errno = err;
+ }
+
+ return res;
+}
+
+wchar_t *path_get_cdpath( void *context, const wchar_t *dir )
{
wchar_t *res = 0;
int err = ENOENT;
@@ -205,7 +381,7 @@ wchar_t *path_get_cdpath( void *context, wchar_t *dir )
nxt_path != 0;
nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) )
{
- wchar_t *expanded_path = expand_tilde( wcsdup(nxt_path) );
+ wchar_t *expanded_path = expand_tilde_compat( wcsdup(nxt_path) );
// debug( 2, L"woot %ls\n", expanded_path );
@@ -229,7 +405,7 @@ wchar_t *path_get_cdpath( void *context, wchar_t *dir )
if( S_ISDIR(buf.st_mode) )
{
res = whole_path;
- halloc_register( context, whole_path );
+ halloc_register( context, whole_path );
break;
}
else
@@ -244,7 +420,7 @@ wchar_t *path_get_cdpath( void *context, wchar_t *dir )
err = EROTTEN;
}
}
-
+
free( whole_path );
}
free( path_cpy );
@@ -264,7 +440,7 @@ wchar_t *path_get_config( void *context)
wchar_t *xdg_dir, *home;
int done = 0;
wchar_t *res = 0;
-
+
xdg_dir = env_get( L"XDG_CONFIG_HOME" );
if( xdg_dir )
{
@@ -277,10 +453,10 @@ wchar_t *path_get_config( void *context)
{
free( res );
}
-
+
}
else
- {
+ {
home = env_get( L"HOME" );
if( home )
{
@@ -295,7 +471,7 @@ wchar_t *path_get_config( void *context)
}
}
}
-
+
if( done )
{
halloc_register_function( context, &free, res );
@@ -306,16 +482,16 @@ wchar_t *path_get_config( void *context)
debug( 0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." ));
return 0;
}
-
+
}
wchar_t *path_make_canonical( void *context, const wchar_t *path )
{
wchar_t *res = halloc_wcsdup( context, path );
wchar_t *in, *out;
-
+
in = out = res;
-
+
while( *in )
{
if( *in == L'/' )
@@ -326,7 +502,7 @@ wchar_t *path_make_canonical( void *context, const wchar_t *path )
}
}
*out = *in;
-
+
out++;
in++;
}
@@ -340,7 +516,7 @@ wchar_t *path_make_canonical( void *context, const wchar_t *path )
out--;
}
*out = 0;
-
+
return res;
}