diff --git a/env.c b/env.c index 5534ca308..008521ad5 100644 --- a/env.c +++ b/env.c @@ -52,6 +52,9 @@ #include "env_universal.h" #include "input_common.h" #include "event.h" +#include "path.h" +#include "halloc.h" +#include "halloc_util.h" #include "complete.h" @@ -710,6 +713,19 @@ int env_set( const wchar_t *key, CHECK( key, ENV_INVALID ); + if( val && CONTAINS( key, L"PWD", L"HOME" ) ) + { + void *context = halloc( 0, 0 ); + const wchar_t *val_canonical = path_make_canonical( context, val ); + if( wcscmp( val_canonical, val ) ) + { + int res = env_set( key, val_canonical, var_mode ); + halloc_free( context ); + return res; + } + halloc_free( context ); + } + if( (var_mode & ENV_USER ) && hash_get( &env_read_only, key ) ) { diff --git a/fish_tests.c b/fish_tests.c index 31ea2b049..e7c180183 100644 --- a/fish_tests.c +++ b/fish_tests.c @@ -44,6 +44,8 @@ #include "output.h" #include "exec.h" #include "event.h" +#include "path.h" +#include "halloc.h" #include "halloc_util.h" /** @@ -600,6 +602,26 @@ static void test_expand() } +static void test_path() +{ + say( L"Testing path functions" ); + + void *context = halloc( 0, 0 ); + + + wchar_t *can = path_make_canonical( context, L"//foo//////bar/" ); + + if( wcscmp( can, L"/foo/bar" ) ) + { + err( L"Bug in canonical PATH code" ); + } + + halloc_free( context ); + +} + + + /** Test speed of completion calculations */ @@ -673,6 +695,9 @@ void perf_complete() } + + + /** Main test */ @@ -697,6 +722,7 @@ int main( int argc, char **argv ) test_tok(); test_parser(); test_expand(); + test_path(); say( L"Encountered %d errors in low-level tests", err_count ); diff --git a/path.c b/path.c index 469c702c0..7cb3e0a5a 100644 --- a/path.c +++ b/path.c @@ -266,3 +266,38 @@ wchar_t *path_get_config( void *context) } +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'/' ) + { + while( *(in+1) == L'/' ) + { + in++; + } + } + *out = *in; + + out++; + in++; + } + + while( 1 ) + { + if( out == res ) + break; + if( *(out-1) != L'/' ) + break; + out--; + } + *out = 0; + + return res; +} + diff --git a/path.h b/path.h index c825160b6..51213b5d3 100644 --- a/path.h +++ b/path.h @@ -40,4 +40,8 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd ); */ wchar_t *path_get_cdpath( void *context, wchar_t *in ); + +wchar_t *path_make_canonical( void *context, const wchar_t *path ); + + #endif