Windows: teach getenv to do a case-sensitive search
getenv() on Windows looks up environment variables in a case-insensitive manner. Even though all documentations claim that the environment is case-insensitive, it is possible for applications to pass an environment to child processes that has variables that differ only in case. Bash on Windows does this, for example, and sh-i18n--envsubst depends on this behavior. With this patch environment variables are first looked up in a case-sensitive manner; only if this finds nothing, the system's getenv() is used as a fallback. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Sixt committed
Jun 6, 2011 at 09:08 UTC
df599e9612788b728ce43a03159b85f1fe624d6a
1 file changed
+20
-3
compat/mingw.c
+20
-3
@@ -1116,14 +1116,31 @@ char **make_augmented_environ(const char *const *vars)
1116
}
1117
1118
#undef getenv
1119
+
1120
+/*
1121
+ * The system's getenv looks up the name in a case-insensitive manner.
1122
+ * This version tries a case-sensitive lookup and falls back to
1123
+ * case-insensitive if nothing was found. This is necessary because,
1124
+ * as a prominent example, CMD sets 'Path', but not 'PATH'.
1125
+ * Warning: not thread-safe.
1126
+ */
1127
+static char *getenv_cs(const char *name)
1128
+{
1129
+ size_t len = strlen(name);
1130
+ int i = lookup_env(environ, name, len);
1131
+ if (i >= 0)
1132
+ return environ[i] + len + 1; /* skip past name and '=' */
1133
+ return getenv(name);
1134
+}
1135
+
1136
char *mingw_getenv(const char *name)
1137
{
1121
- char *result = getenv(name);
1138
+ char *result = getenv_cs(name);
1139
if (!result && !strcmp(name, "TMPDIR")) {
1140
/* on Windows it is TMP and TEMP */
1124
- result = getenv("TMP");
1141
+ result = getenv_cs("TMP");
1142
if (!result)
1126
- result = getenv("TEMP");
1143
+ result = getenv_cs("TEMP");
1144
}
1145
return result;
1146
}