This is known, and is caused by the fact that if we synchronize more exactly there's a much larger performance penalty for all accesses to environment variables from Tcl, and that's a much more common use case than the one you have where you are changing the environment variable from C code. (The putenv()
system call doesn't give us anything we can efficiently hook to detect the changes, so we end up having to reassemble the whole env
array from scratch; this was found to be a significant bottleneck.)
The simplest workaround is for you to create a little extra command in Tcl (but written in C) that wraps the getenv()
call directly so that you can use that with environment variables that you suspect may have been changed behind Tcl's back.
int WrapGetEnv(ClientData ignored, Tcl_Interp *interp, int argc, char *argv[]) {
if (argc != 2) {
// Probably ought to be a better error here
return TCL_ERROR;
}
char *var = argv[1];
char *val = getenv(var);
if (val != NULL) {
Tcl_SetResult(interp, val, TCL_DYNAMIC);
}
return TCL_OK;
}
// ... in the right place do this ...
Tcl_CreateCommand(interp, "getenv", WrapGetEnv, NULL, NULL);