Skip to content

Commit

Permalink
environ.cc: New facility/environment variable MSYS2_ENV_CONV_EXCL
Browse files Browse the repository at this point in the history
Works very much like MSYS2_ARG_CONV_EXCL. In fact it uses the same
function, arg_heuristic_with_exclusions (). Also refactors parsing
the env. variables to use new function, string_split_delimited ().

The env. that is searched through is the merged (POSIX + Windows)
one. It remains to be seen if this should be made an option or not.

This feature was prompted because the R language (Windows exe) calls
bash to run configure.win, which then calls back into R to read its
config variables (LOCAL_SOFT) and when this happens, msys2-runtime
converts R_ARCH from "/x64" to an absolute Windows path and appends
it to another absolute path, R_HOME, forming an invalid path.
  • Loading branch information
mingwandroid authored and dscho committed Feb 11, 2024
1 parent d8cb51c commit 79cd04c
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 21 deletions.
34 changes: 24 additions & 10 deletions winsup/cygwin/environ.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1172,6 +1172,10 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,

int tl = 0;
char **pass_dstp;
#ifdef __MSYS__
char *msys2_env_conv_excl_env = NULL;
size_t msys2_env_conv_excl_count = 0;
#endif
char **pass_env = (char **) alloca (sizeof (char *)
* (n + winnum + SPENVS_SIZE + 1));
/* Iterate over input list, generating a new environment list and refreshing
Expand All @@ -1180,16 +1184,25 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
{
bool calc_tl = !no_envblock;
#ifdef __MSYS__
/* Don't pass timezone environment to non-msys applications */
if (!keep_posix && ascii_strncasematch(*srcp, "TZ=", 3))
if (!keep_posix)
{
const char *v = *srcp + 3;
if (*v == ':')
goto next1;
for (; *v; v++)
if (!isalpha(*v) && !isdigit(*v) &&
*v != '-' && *v != '+' && *v != ':')
goto next1;
/* Don't pass timezone environment to non-msys applications */
if (ascii_strncasematch(*srcp, "TZ=", 3))
{
const char *v = *srcp + 3;
if (*v == ':')
goto next1;
for (; *v; v++)
if (!isalpha(*v) && !isdigit(*v) &&
*v != '-' && *v != '+' && *v != ':')
goto next1;
}
else if (ascii_strncasematch(*srcp, "MSYS2_ENV_CONV_EXCL=", 20))
{
msys2_env_conv_excl_env = (char*)alloca (strlen(&(*srcp)[20])+1);
strcpy (msys2_env_conv_excl_env, &(*srcp)[20]);
msys2_env_conv_excl_count = string_split_delimited (msys2_env_conv_excl_env, ';');
}
}
#endif
/* Look for entries that require special attention */
Expand Down Expand Up @@ -1314,7 +1327,8 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
}
#ifdef __MSYS__
else if (!keep_posix) {
char *win_arg = arg_heuristic(*srcp);
char *win_arg = arg_heuristic_with_exclusions
(*srcp, msys2_env_conv_excl_env, msys2_env_conv_excl_count);
debug_printf("WIN32_PATH is %s", win_arg);
p = cstrdup1(win_arg);
if (win_arg != *srcp)
Expand Down
2 changes: 2 additions & 0 deletions winsup/cygwin/local_includes/miscfuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ void backslashify (const char *, char *, bool);
void slashify (const char *, char *, bool);
#define isslash(c) ((c) == '/')

size_t string_split_delimited (char * string, char delimiter);

extern void transform_chars (PWCHAR, PWCHAR);
extern inline void
transform_chars (PUNICODE_STRING upath, USHORT start_idx)
Expand Down
20 changes: 20 additions & 0 deletions winsup/cygwin/miscfuncs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,26 @@ NT_readline::gets ()
}
}

/* Searches through string for delimiter replacing each instance with '\0'
and returning the number of such delimited substrings. This function
Will return 0 for the NULL string and at least 1 otherwise. */

size_t
string_split_delimited (char * string, char delimiter)
{
if ( string == NULL )
return 0;
size_t count = 1;
string = strchr ( string, delimiter );
while (string)
{
*string = '\0';
++count;
string = strchr ( string + 1, delimiter );
}
return count;
}

/* Signal the thread name to any attached debugger
(See "How to: Set a Thread Name in Native Code"
Expand Down
1 change: 0 additions & 1 deletion winsup/cygwin/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4044,7 +4044,6 @@ arg_heuristic_with_exclusions (char const * const arg, char const * exclusions,
return arg_result;
}

debug_printf("Input value: (%s)", arg);
for (size_t excl = 0; excl < exclusions_count; ++excl)
{
/* Since we've got regex linked we should maybe switch to that, but
Expand Down
12 changes: 2 additions & 10 deletions winsup/cygwin/spawn.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
int res = -1;

/* Environment variable MSYS2_ARG_CONV_EXCL contains a list
of ';' separated argument prefixes to pass un-modified..
It isn't applied to env. variables; only spawn arguments.
of ';' separated argument prefixes to pass un-modified.
A value of * means don't convert any arguments. */
char* msys2_arg_conv_excl_env = getenv("MSYS2_ARG_CONV_EXCL");
char* msys2_arg_conv_excl = NULL;
Expand All @@ -303,14 +302,7 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
{
msys2_arg_conv_excl = (char*)alloca (strlen(msys2_arg_conv_excl_env)+1);
strcpy (msys2_arg_conv_excl, msys2_arg_conv_excl_env);
msys2_arg_conv_excl_count = 1;
msys2_arg_conv_excl_env = strchr ( msys2_arg_conv_excl, ';' );
while (msys2_arg_conv_excl_env)
{
*msys2_arg_conv_excl_env = '\0';
++msys2_arg_conv_excl_count;
msys2_arg_conv_excl_env = strchr ( msys2_arg_conv_excl_env + 1, ';' );
}
msys2_arg_conv_excl_count = string_split_delimited (msys2_arg_conv_excl, ';');
}

/* Check if we have been called from exec{lv}p or spawn{lv}p and mask
Expand Down

0 comments on commit 79cd04c

Please sign in to comment.