Some changes to migrate towards C++ and a multithreaded model

This commit is contained in:
ridiculousfish
2011-12-26 19:18:46 -08:00
parent 3f16ace678
commit 8d2f107d61
90 changed files with 7368 additions and 5981 deletions

218
path.cpp
View File

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