PLACES putenv fix

svn: r17011
This commit is contained in:
Kevin Tew 2009-11-23 19:58:27 +00:00
parent 15e3644a85
commit ce693bdb82

View File

@ -383,6 +383,8 @@ scheme_init_string (Scheme_Env *env)
platform_3m_path = scheme_make_path(SCHEME_PLATFORM_LIBRARY_SUBPATH MZ3M_SUBDIR);
REGISTER_SO(putenv_str_table);
putenv_str_table = scheme_make_hash_table(SCHEME_hash_string);
REGISTER_SO(embedding_banner);
REGISTER_SO(current_locale_name);
@ -1978,33 +1980,67 @@ int scheme_any_string_has_null(Scheme_Object *o)
}
}
#ifdef DOS_FILE_SYSTEM
# include <windows.h>
static char *mzGETENV(char *s)
{
int sz, got;
char *res;
sz = GetEnvironmentVariable(s, NULL, 0);
if (!sz)
return NULL;
res = scheme_malloc_atomic(sz);
got = GetEnvironmentVariable(s, res, sz);
if (got < sz)
res[got] = 0;
return res;
#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)
static char* clone_str_with_gc(char* buffer) {
int length;
char *newbuffer;
length = strlen(buffer);
newbuffer = scheme_malloc_atomic(length+1);
memcpy(newbuffer, buffer, length+1);
return newbuffer;
}
static int mzPUTENV(char *var, char *val, char *together)
{
return !SetEnvironmentVariable(var, val);
}
#else
# define mzGETENV getenv
# define mzPUTENV(var, val, s) MSC_IZE(putenv)(s)
#endif
#ifndef DOS_FILE_SYSTEM
static void putenv_str_table_put_name(Scheme_Object *name, Scheme_Object *value) {
#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)
void *original_gc;
Scheme_Object *name_copy;
original_gc = GC_switch_to_master_gc();
name_copy = clone_str_with_gc(name);
scheme_hash_set(putenv_str_table, name_copy, value);
GC_switch_back_from_master(original_gc);
#else
scheme_hash_set(putenv_str_table, name, value);
#endif
}
#endif
#ifndef GETENV_FUNCTION
static void putenv_str_table_put_name_value(Scheme_Object *name, Scheme_Object *value) {
#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)
void *original_gc;
Scheme_Object *name_copy;
Scheme_Object *value_copy;
original_gc = GC_switch_to_master_gc();
name_copy = clone_str_with_gc(name);
value_copy = clone_str_with_gc(value);
scheme_hash_set(putenv_str_table, name_copy, value_copy);
GC_switch_back_from_master(original_gc);
#else
scheme_hash_set(putenv_str_table, name, value);
#endif
}
#endif
#if !defined(GETENV_FUNCTION) || defined(MZ_PRECISE_GC)
static Scheme_Object *putenv_str_table_get(Scheme_Object *name) {
#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)
void *original_gc;
Scheme_Object *value;
original_gc = GC_switch_to_master_gc();
value = scheme_hash_get(putenv_str_table, name);
GC_switch_back_from_master(original_gc);
return value;
#else
return scheme_hash_get(putenv_str_table, name);
#endif
}
#endif
static Scheme_Object *sch_bool_getenv(const char* name);
void
scheme_init_getenv(void)
{
@ -2017,124 +2053,158 @@ scheme_init_getenv(void)
scheme_current_thread->error_buf = &newbuf;
if (!scheme_setjmp(newbuf)) {
while (1) {
Scheme_Object *v = scheme_read(p);
if (SCHEME_EOFP(v))
break;
Scheme_Object *v = scheme_read(p);
if (SCHEME_EOFP(v))
break;
if (SCHEME_PAIRP(v) && SCHEME_PAIRP(SCHEME_CDR(v))
&& SCHEME_NULLP(SCHEME_CDR(SCHEME_CDR(v)))) {
Scheme_Object *key = SCHEME_CAR(v);
Scheme_Object *val = SCHEME_CADR(v);
if (SCHEME_STRINGP(key) && SCHEME_STRINGP(val)) {
Scheme_Object *a[2];
a[0] = key;
a[1] = val;
sch_putenv(2, a);
v = NULL;
}
}
if (SCHEME_PAIRP(v) && SCHEME_PAIRP(SCHEME_CDR(v))
&& SCHEME_NULLP(SCHEME_CDR(SCHEME_CDR(v)))) {
Scheme_Object *key = SCHEME_CAR(v);
Scheme_Object *val = SCHEME_CADR(v);
if (SCHEME_STRINGP(key) && SCHEME_STRINGP(val)) {
Scheme_Object *a[2];
a[0] = key;
a[1] = val;
sch_putenv(2, a);
v = NULL;
}
}
if (v)
scheme_signal_error("bad environment specification: %V", v);
if (v)
scheme_signal_error("bad environment specification: %V", v);
}
}
scheme_current_thread->error_buf = savebuf;
scheme_close_input_port(p);
if (scheme_hash_get(putenv_str_table, (Scheme_Object *)"PLTNOMZJIT")) {
scheme_set_startup_use_jit(0);
}
}
#else
if (mzGETENV("PLTNOMZJIT")) {
scheme_set_startup_use_jit(0);
}
#endif
if (sch_bool_getenv("PLTNOMZJIT")) {
scheme_set_startup_use_jit(0);
}
}
#ifdef DOS_FILE_SYSTEM
# include <windows.h>
static char *dos_win_getenv(const char *name) {
int value_size;
value_size = GetEnvironmentVariable(s, NULL, 0);
if (value_size) {
char *value;
int got;
value = scheme_malloc_atomic(value_size);
got = GetEnvironmentVariable(name, value, value_size);
if (got < value_size)
value[got] = 0;
return value;
}
return name;
}
#endif
static Scheme_Object *sch_bool_getenv(const char* name) {
Scheme_Object *rc;
rc = scheme_false;
#ifdef GETENV_FUNCTION
# ifdef DOS_FILE_SYSTEM
if (GetEnvironmentVariable(s, NULL, 0)) rc = scheme_true;
# else
if (getenv(name)) rc = scheme_true;
# endif
#else
if (putenv_str_table_get(name)) rc = scheme_true;
#endif
return rc;
}
static Scheme_Object *sch_getenv(int argc, Scheme_Object *argv[])
{
char *s;
char *name;
char *value;
Scheme_Object *bs;
if (!SCHEME_CHAR_STRINGP(argv[0])
|| scheme_any_string_has_null(argv[0]))
if (!SCHEME_CHAR_STRINGP(argv[0]) || scheme_any_string_has_null(argv[0]))
scheme_wrong_type("getenv", CHAR_STRING_W_NO_NULLS, 0, argc, argv);
bs = scheme_char_string_to_byte_string_locale(argv[0]);
name = SCHEME_BYTE_STR_VAL(bs);
#ifdef GETENV_FUNCTION
s = mzGETENV(SCHEME_BYTE_STR_VAL(bs));
# ifdef DOS_FILE_SYSTEM
value = dos_win_getenv(name);
# else
value = getenv(name);
# endif
#else
if (putenv_str_table) {
s = (char *)scheme_hash_get(putenv_str_table, (Scheme_Object *)SCHEME_BYTE_STR_VAL(argv[0]));
/* If found, skip over the `=' in the table: */
if (s)
s += SCHEME_BYTE_STRTAG_VAL(bs) + 1;
} else
s = NULL;
#endif
if (s)
return scheme_make_locale_string(s);
return scheme_false;
}
static Scheme_Object *sch_putenv(int argc, Scheme_Object *argv[])
{
char *s, *var, *val;
long varlen, vallen;
Scheme_Object *bs;
if (!SCHEME_CHAR_STRINGP(argv[0])
|| scheme_any_string_has_null(argv[0]))
scheme_wrong_type("putenv", CHAR_STRING_W_NO_NULLS, 0, argc, argv);
if (!SCHEME_CHAR_STRINGP(argv[1])
|| scheme_any_string_has_null(argv[1]))
scheme_wrong_type("putenv", CHAR_STRING_W_NO_NULLS, 1, argc, argv);
bs = scheme_char_string_to_byte_string_locale(argv[0]);
var = SCHEME_BYTE_STR_VAL(bs);
bs = scheme_char_string_to_byte_string_locale(argv[1]);
val = SCHEME_BYTE_STR_VAL(bs);
varlen = strlen(var);
vallen = strlen(val);
s = (char *)scheme_malloc_atomic(varlen + vallen + 2);
memcpy(s, var, varlen);
memcpy(s + varlen + 1, val, vallen + 1);
s[varlen] = '=';
#ifdef MZ_PRECISE_GC
{
/* Can't put moveable string into array. */
char *ss;
ss = s;
s = malloc(varlen + vallen + 2);
memcpy(s, ss, varlen + vallen + 2);
/* Free old, if in table: */
if (putenv_str_table) {
ss = (char *)scheme_hash_get(putenv_str_table, (Scheme_Object *)var);
if (ss)
free(ss);
}
Scheme_Object *hash_value;
hash_value = putenv_str_table_get(name);
return hash_value ? hash_value : scheme_false;
}
#endif
if (!putenv_str_table)
putenv_str_table = scheme_make_hash_table(SCHEME_hash_string);
return value ? scheme_make_locale_string(value) : scheme_false;
}
scheme_hash_set(putenv_str_table, (Scheme_Object *)var, (Scheme_Object *)s);
static int sch_unix_putenv(const char *var, const char *val, const long varlen, const long vallen) {
char *buffer;
long total_length;
total_length = varlen + vallen + 2;
#ifdef MZ_PRECISE_GC
/* Can't put moveable string into array. */
buffer = malloc(total_length);
#else
buffer = (char *)scheme_malloc_atomic(total_length);
#endif
memcpy(buffer, var, varlen);
buffer[varlen] = '=';
memcpy(buffer + varlen + 1, val, vallen + 1);
#ifdef MZ_PRECISE_GC
{
/* Free old, if in table: */
char *oldbuffer;
oldbuffer = (char *)putenv_str_table_get((Scheme_Object *)var);
if (oldbuffer)
free(oldbuffer);
}
#endif
/* if precise the buffer needs to be remembered so it can be freed */
/* if not precise the buffer needs to be rooted so it doesn't get collected prematurely */
putenv_str_table_put_name((Scheme_Object *)var, (Scheme_Object *)buffer);
return putenv(buffer);
}
static Scheme_Object *sch_putenv(int argc, Scheme_Object *argv[])
{
Scheme_Object *varbs;
Scheme_Object *valbs;
char *var;
char *val;
int rc = 0;
if (!SCHEME_CHAR_STRINGP(argv[0]) || scheme_any_string_has_null(argv[0]))
scheme_wrong_type("putenv", CHAR_STRING_W_NO_NULLS, 0, argc, argv);
if (!SCHEME_CHAR_STRINGP(argv[1]) || scheme_any_string_has_null(argv[1]))
scheme_wrong_type("putenv", CHAR_STRING_W_NO_NULLS, 1, argc, argv);
varbs = scheme_char_string_to_byte_string_locale(argv[0]);
var = SCHEME_BYTE_STR_VAL(varbs);
valbs = scheme_char_string_to_byte_string_locale(argv[1]);
val = SCHEME_BYTE_STR_VAL(valbs);
#ifdef GETENV_FUNCTION
return mzPUTENV(var, val, s) ? scheme_false : scheme_true;
# ifdef DOS_FILE_SYSTEM
rc = !SetEnvironmentVariable(var, val);
# else
rc = sch_unix_putenv(var, val, SCHEME_BYTE_STRLEN_VAL(varbs), SCHEME_BYTE_STRLEN_VAL(valbs));
# endif
#else
return scheme_true;
putenv_str_table_put_name_value(argv[0], argv[1]);
#endif
return rc ? scheme_false : scheme_true;
}
static void machine_details(char *s);