diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index f2f42c7b4..f9b288c06 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2006-08-02 Christopher Faylor + + * environ.cc (env_win32_to_posix_path_list): Declare. + (conv_envvars): Use env_win32_to_posix_path_list rather than + cygwin_win32_to_posix_path_list. + (posify): Translate back to win32 path if errno is EIDRM. + * environ.h: Update copyright. Define ENV_CVT. + * path.cc (conv_path_list): If converting for the environment and + removed an element set errno to ENV_CVT. + (env_win32_to_posix_path_list): New function. + 2006-08-01 Christopher Faylor * environ.cc (dos_file_warning): Declare. diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 2e8acddcb..c11a657d2 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -43,6 +43,8 @@ extern bool allow_server; static char **lastenviron; +extern "C" int env_win32_to_posix_path_list (const char *, char *posix); + #define ENVMALLOC \ (CYGWIN_VERSION_DLL_MAKE_COMBINED (user_data->api_major, user_data->api_minor) \ <= CYGWIN_VERSION_DLL_MALLOC_ENV) @@ -57,7 +59,7 @@ static char **lastenviron; static int return_MAX_PATH (const char *) {return CYG_MAX_PATH;} static win_env conv_envvars[] = { - {NL ("PATH="), NULL, NULL, cygwin_win32_to_posix_path_list, + {NL ("PATH="), NULL, NULL, env_win32_to_posix_path_list, cygwin_posix_to_win32_path_list, cygwin_win32_to_posix_path_list_buf_size, cygwin_posix_to_win32_path_list_buf_size, true}, @@ -181,8 +183,17 @@ posify (char **here, const char *value) char *outenv = (char *) malloc (1 + len + conv->posix_len (value)); memcpy (outenv, src, len); - conv->toposix (value, outenv + len); - conv->add_cache (outenv + len, *value != '/' ? value : NULL); + char *newvalue = outenv + len; + if (!conv->toposix (value, newvalue) || _impure_ptr->_errno != EIDRM) + conv->add_cache (newvalue, *value != '/' ? value : NULL); + else + { + /* The conversion routine removed elements from a path list so we have + to recalculate the windows path to remove elements there, too. */ + char cleanvalue[strlen (value) + 1]; + conv->towin32 (newvalue, cleanvalue); + conv->add_cache (newvalue, cleanvalue); + } debug_printf ("env var converted to %s", outenv); *here = outenv; diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h index b953148b4..84c88a3c9 100644 --- a/winsup/cygwin/environ.h +++ b/winsup/cygwin/environ.h @@ -1,6 +1,6 @@ /* environ.h: Declarations for environ manipulation - Copyright 2000, 2001, 2002 Red Hat, Inc. + Copyright 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc. This file is part of Cygwin. @@ -48,3 +48,5 @@ extern "C" char __stdcall **cur_environ (); char ** __stdcall build_env (const char * const *envp, char *&envblock, int &envc, bool need_envblock) __attribute__ ((regparm (3))); + +#define ENV_CVT -1 diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 9a91aceb9..f7dccc01f 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -75,6 +75,7 @@ details. */ #include "shared_info.h" #include "registry.h" #include "cygtls.h" +#include "environ.h" #include bool dos_file_warning = true; @@ -1329,6 +1330,7 @@ conv_path_list (const char *src, char *dst, int to_posix) int err = 0; char *d = dst - 1; + bool saw_empty = false; do { char *s = strccpy (srcbuf, &src, src_delim); @@ -1343,7 +1345,11 @@ conv_path_list (const char *src, char *dst, int to_posix) else if (!to_posix) err = conv_fn (".", ++d); else - continue; + { + if (to_posix == ENV_CVT) + saw_empty = true; + continue; + } if (err) break; d = strchr (d, '\0'); @@ -1351,6 +1357,9 @@ conv_path_list (const char *src, char *dst, int to_posix) } while (*src++); + if (saw_empty) + err = EIDRM; + if (d < dst) d++; *d = '\0'; @@ -3885,6 +3894,12 @@ cygwin_posix_to_win32_path_list_buf_size (const char *path_list) return conv_path_list_buf_size (path_list, false); } +extern "C" int +env_win32_to_posix_path_list (const char *win32, char *posix) +{ + return_with_errno (conv_path_list (win32, posix, ENV_CVT)); +} + extern "C" int cygwin_win32_to_posix_path_list (const char *win32, char *posix) {