Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
don't cache environment variables, fix non-ASCII environment variables
Browse files Browse the repository at this point in the history
GitCheetah caches environment variables when spawning the first child
process. Thus, updates to the hosting explorer process's environment are
not reflected in subsequently spawned child processes.

Note: if and when explorer updates its environment variables from the
registry seems to depend on the Windows version.

Additionally, non-ASCII environment variables are mangled in child
processes, as GetEnvironmentStringsA returns OEM-encoded strings, but
CreateProcessA expects ANSI.

Remove the copying / caching of the entire environment. When spawning
child processes, just tweak the PATH variable temporarily.

Reading a single environment variable (GetEnvironmentVariableA) instead of
the entire environment (GetEnvironmentStringsA) implicitly fixes non-ASCII
variables.

Signed-off-by: Karsten Blees <blees@dcon.de>
  • Loading branch information
kblees committed Feb 22, 2013
1 parent 9c63447 commit c679410
Showing 1 changed file with 26 additions and 60 deletions.
86 changes: 26 additions & 60 deletions explorer/systeminfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,71 +101,37 @@ int is_directory(const char *path)
return (FILE_ATTRIBUTE_DIRECTORY & GetFileAttributes(path));
}

/*
* builds an array of environment variables,
* as expected by mingw_spawnvpe
*/
static char **env_for_git()
pid_t fork_process(const char *cmd, const char **args, const char *wd)
{
static char **environment;

/*
* if we can't find path to msys in the registry, return NULL and
* the CreateProcess will copy the environment for us
*/
if (!environment && git_path()) {
char *old = GetEnvironmentStrings();
size_t space = 0, path_index = -1, name_len = 0;
int total = 0, i;

while (old[space]) {
/* if it's PATH variable (could be Path= too!) */
if (!strnicmp(old + space, "PATH=", 5)) {
path_index = space;
name_len = 5;
}

while (old[space])
space++;
space++; /* skip var-terminating NULL */

total++;
}

if (path_index == -1)
path_index = space;

environment = malloc(sizeof(*environment) * (total + 1));
space = 0;
for (i = 0; i < total; i++) {
if (path_index == space) {
char *path = old + space + name_len;
size_t len;
environment[i] = malloc(strlen(path) + 1 +
2 * strlen(git_path()) + 32);
len = sprintf(environment[i],
"PATH=%s%s%s", git_path(),
*path ? ";" : "", path);
} else
environment[i] = strdup(old + space);

while (old[space])
space++;
space++; /* skip var-terminating NULL */
pid_t result;
char *oldpath = NULL;
const char *gitpath = git_path();

/* if gitpath is set, temporarily set PATH=<gitpath>;%PATH% */
if (gitpath) {
int len;
struct strbuf path = STRBUF_INIT;
strbuf_addstr(&path, gitpath);
len = GetEnvironmentVariable("PATH", NULL, 0);
if (len) {
oldpath = malloc(len);
GetEnvironmentVariable("PATH", oldpath, len);
strbuf_addch(&path, ';');
strbuf_addstr(&path, oldpath);
}

/* mark the end of the array */
environment[i] = 0;

FreeEnvironmentStrings(old);
SetEnvironmentVariable("PATH", path.buf);
strbuf_release(&path);
}

return environment;
}
/* spawn child process */
result = mingw_spawnvpe_cwd(cmd, args, NULL, wd);

pid_t fork_process(const char *cmd, const char **args, const char *wd)
{
return mingw_spawnvpe_cwd(cmd, args, env_for_git(), wd);
/* reset PATH to previous value */
if (gitpath) {
SetEnvironmentVariable("PATH", oldpath);
free(oldpath);
}
return result;
}

int wait_for_process(pid_t pid, int max_time, int *errcode)
Expand Down

0 comments on commit c679410

Please sign in to comment.