diff --git a/racket/src/racket/src/Makefile.in b/racket/src/racket/src/Makefile.in index bfe89ee8df..76528c1549 100644 --- a/racket/src/racket/src/Makefile.in +++ b/racket/src/racket/src/Makefile.in @@ -422,7 +422,7 @@ setjmpup.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/stypes.h $(srcdir)/schmach.h sfs.@LTO@: $(COMMON_HEADERS) \ $(srcdir)/stypes.h $(srcdir)/mzmark_sfs.inc -string.@LTO@: $(COMMON_HEADERS) \ +string.@LTO@: $(COMMON_HEADERS) $(RKTIO_HEADERS) \ $(srcdir)/stypes.h $(srcdir)/schvers.h $(srcdir)/mzmark_string.inc $(srcdir)/strops.inc \ $(srcdir)/schustr.inc $(srcdir)/systype.inc struct.@LTO@: $(COMMON_HEADERS) \ diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index 4ef3785b9b..2f88ea861e 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -1043,9 +1043,7 @@ char *scheme_os_getcwd(char *buf, int buflen, int *actlen, int noexn) *actlen = slen+1; if (buflen < slen) { - buf = scheme_strdup(s); - free(s); - return buf; + return scheme_strdup_and_free(s); } else { memcpy(buf, s, slen+1); free(s); @@ -1720,10 +1718,7 @@ static char *do_expand_filename(Scheme_Object *o, char* filename, int ilen, cons errorin, filename); } - filename = scheme_strdup(new_filename); - free(new_filename); - - filename = new_filename; + filename = scheme_strdup_and_free(new_filename); ilen = strlen(filename); } #endif diff --git a/racket/src/racket/src/salloc.c b/racket/src/racket/src/salloc.c index ac596cd374..a168c7f111 100644 --- a/racket/src/racket/src/salloc.c +++ b/racket/src/racket/src/salloc.c @@ -547,7 +547,7 @@ scheme_calloc (size_t num, size_t size) memset(space, 0, (num*size)); #endif - return (space); + return space; } char * @@ -558,7 +558,7 @@ scheme_strdup(const char *str) len = strlen(str) + 1; naya = (char *)scheme_malloc_atomic (len * sizeof (char)); - memcpy (naya, str, len); + memcpy(naya, str, len); return naya; } @@ -571,7 +571,22 @@ scheme_strdup_eternal(const char *str) len = strlen(str) + 1; naya = (char *)scheme_malloc_eternal(len * sizeof (char)); - memcpy (naya, str, len); + memcpy(naya, str, len); + + return naya; +} + +char * +scheme_strdup_and_free(const char *str) +{ + char *naya; + intptr_t len; + + len = strlen(str) + 1; + naya = (char *)scheme_malloc_atomic (len * sizeof (char)); + memcpy(naya, str, len); + + free((void *)str); return naya; } diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 0c45bda527..2f725c2528 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -4568,6 +4568,7 @@ int scheme_regexp_match_p(Scheme_Object *regexp, Scheme_Object *target); Scheme_Object *scheme_gensym(Scheme_Object *base); Scheme_Object *scheme_symbol_to_string(Scheme_Object *sym); +char *scheme_strdup_and_free(const char *str); Scheme_Object *scheme_maybe_build_path(Scheme_Object *base, Scheme_Object *elem); diff --git a/racket/src/racket/src/string.c b/racket/src/racket/src/string.c index a342241849..c64fab04ac 100644 --- a/racket/src/racket/src/string.c +++ b/racket/src/racket/src/string.c @@ -25,6 +25,7 @@ #include "schpriv.h" #include "schvers.h" +#include "schrktio.h" #include #include #ifdef NO_ERRNO_GLOBAL @@ -384,8 +385,6 @@ ROSYM static Scheme_Object *platform_3m_path, *platform_cgc_path; READ_ONLY static Scheme_Object *zero_length_char_string; READ_ONLY static Scheme_Object *zero_length_byte_string; -SHARED_OK static Scheme_Hash_Table *putenv_str_table; - SHARED_OK static char *embedding_banner; SHARED_OK static Scheme_Object *vers_str; SHARED_OK static Scheme_Object *banner_str; @@ -469,8 +468,6 @@ scheme_init_string (Scheme_Env *env) platform_cgc_path = scheme_make_path(SCHEME_PLATFORM_LIBRARY_SUBPATH SPLS_SUFFIX); platform_3m_path = scheme_make_path(SCHEME_PLATFORM_LIBRARY_SUBPATH SPLS_SUFFIX MZ3M_SUBDIR); - REGISTER_SO(putenv_str_table); - REGISTER_SO(embedding_banner); REGISTER_SO(vers_str); REGISTER_SO(banner_str); @@ -2211,16 +2208,6 @@ int scheme_any_string_has_null(Scheme_Object *o) /* Environment Variables */ /***********************************************************************/ -#if defined(OS_X) && !TARGET_OS_IPHONE -# include -# define GET_ENVIRON_ARRAY *_NSGetEnviron() -#endif - -#if !defined(DOS_FILE_SYSTEM) && !defined(GET_ENVIRON_ARRAY) -extern char **environ; -# define GET_ENVIRON_ARRAY environ -#endif - #define SCHEME_ENVVARS_TABLE(ev) ((Scheme_Hash_Tree *)SCHEME_PTR_VAL(ev)) Scheme_Object *scheme_make_environment_variables(Scheme_Hash_Tree *ht) @@ -2253,138 +2240,56 @@ static Scheme_Object *current_environment_variables(int argc, Scheme_Object *arg return v; } -#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) -static char* clone_str_with_gc(const char* buffer) { - int length; - char *newbuffer; - length = strlen(buffer); - newbuffer = scheme_malloc_atomic(length+1); - memcpy(newbuffer, buffer, length+1); - return newbuffer; -} -#endif - -static void create_putenv_str_table_if_needed() { - if (!putenv_str_table) { - putenv_str_table = scheme_make_hash_table(SCHEME_hash_string); - } -} - -#ifndef DOS_FILE_SYSTEM -static void putenv_str_table_put_name(const char *name, char *value) { -#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) - void *original_gc; - const char *name_copy; - original_gc = GC_switch_to_master_gc(); - scheme_start_atomic(); - - name_copy = clone_str_with_gc(name); - create_putenv_str_table_if_needed(); - scheme_hash_set(putenv_str_table, (Scheme_Object *)name_copy, (Scheme_Object *)value); - - scheme_end_atomic_no_swap(); - GC_switch_back_from_master(original_gc); -#else - create_putenv_str_table_if_needed(); - scheme_hash_set(putenv_str_table, (Scheme_Object *)name, (Scheme_Object *)value); -#endif -} -#endif - -#if defined(MZ_PRECISE_GC) -static Scheme_Object *putenv_str_table_get(const char *name) { -#if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) - void *original_gc; - Scheme_Object *value; - original_gc = GC_switch_to_master_gc(); - scheme_start_atomic(); - - create_putenv_str_table_if_needed(); - value = scheme_hash_get(putenv_str_table, (Scheme_Object *)name); - - scheme_end_atomic_no_swap(); - GC_switch_back_from_master(original_gc); - return value; -#else - create_putenv_str_table_if_needed(); - return scheme_hash_get(putenv_str_table, (Scheme_Object *)name); -#endif -} -#endif - - static int sch_bool_getenv(const char* name); -void -scheme_init_getenv(void) +void scheme_init_getenv(void) { if (sch_bool_getenv("PLTNOMZJIT")) { scheme_set_startup_use_jit(0); } } -#ifdef DOS_FILE_SYSTEM -# include -static char *dos_win_getenv(const char *name) { - int value_size; - value_size = GetEnvironmentVariableW(WIDE_PATH(name), NULL, 0); - if (value_size) { - wchar_t *value; - int got; - value = scheme_malloc_atomic(sizeof(wchar_t) * value_size); - got = GetEnvironmentVariableW(WIDE_PATH(name), value, value_size); - if (got < value_size) - value[got] = 0; - return NARROW_PATH(value); - } - return NULL; -} -#endif - static int sch_bool_getenv(const char* name) { - int rc = 0; - -#ifdef DOS_FILE_SYSTEM - if (GetEnvironmentVariable(name, NULL, 0)) rc = 1; -#else - if (getenv(name)) rc = 1; -#endif - - return rc; + if (rktio_getenv(scheme_rktio, name)) + return 1; + else + return 0; } int byte_string_ok_name(Scheme_Object *o) { const char *s = SCHEME_BYTE_STR_VAL(o); int i = SCHEME_BYTE_STRTAG_VAL(o); -#ifdef DOS_FILE_SYSTEM - if (!i) return 0; -#endif + while (i--) { - if (!s[i] || s[i] == '=') + if (!s[i]) return 0; } + + return rktio_is_ok_envvar_name(scheme_rktio, s); + return 1; } static Scheme_Object *normalize_env_case(Scheme_Object *bs) { -#ifdef DOS_FILE_SYSTEM - bs = scheme_byte_string_to_char_string(bs); - bs = string_locale_downcase(1, &bs); - bs = scheme_char_string_to_byte_string(bs); -#endif + if (rktio_are_envvar_names_case_insensitive(scheme_rktio)) { + bs = scheme_byte_string_to_char_string(bs); + bs = string_locale_downcase(1, &bs); + bs = scheme_char_string_to_byte_string(bs); + } return bs; } char *scheme_getenv(char *name) { -#ifdef DOS_FILE_SYSTEM - return dos_win_getenv(name); -#else - return getenv(name); -#endif + char *s; + s = rktio_getenv(scheme_rktio, name); + if (s) + return scheme_strdup_and_free(s); + else + return NULL; } static Scheme_Object *sch_getenv(int argc, Scheme_Object *argv[]) @@ -2408,9 +2313,14 @@ static Scheme_Object *sch_getenv(int argc, Scheme_Object *argv[]) if (!ht) { name = SCHEME_BYTE_STR_VAL(bs); - value = scheme_getenv(name); + value = rktio_getenv(scheme_rktio, name); + if (value) { + val = scheme_make_byte_string(value); + free(value); + } else + val = scheme_false; - return value ? scheme_make_byte_string(value) : scheme_false; + return val; } else { bs = normalize_env_case(bs); val = scheme_hash_tree_get(ht, bs); @@ -2418,69 +2328,12 @@ static Scheme_Object *sch_getenv(int argc, Scheme_Object *argv[]) } } -#ifndef DOS_FILE_SYSTEM -static int sch_unix_putenv(const char *var, const char *val, const intptr_t varlen, const intptr_t vallen) { - char *buffer; - intptr_t total_length, r; - total_length = varlen + vallen + 2; - - if (val) { -#ifdef MZ_PRECISE_GC - /* Can't put movable string into environ 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); - } else { - buffer = NULL; - } - - if (buffer) - r = putenv(buffer); - else { - /* on some platforms, unsetenv() returns void */ - unsetenv(var); - r = 0; - } - - if (!r) { -#ifdef MZ_PRECISE_GC - char *oldbuffer; - - /* Will free old, if in table: */ - oldbuffer = (char *)putenv_str_table_get(var); -#endif - - /* If precise GC, the buffer needs to be remembered so it can be freed; - otherwise, the buffer needs to be referenced so it doesn't get GCed */ - putenv_str_table_put_name(var, buffer); - -#ifdef MZ_PRECISE_GC - if (oldbuffer) - free(oldbuffer); -#endif - } else { -#ifdef MZ_PRECISE_GC - if (buffer) - free(buffer); -#endif - } - - return r; -} -#endif - static Scheme_Object *sch_putenv(int argc, Scheme_Object *argv[]) { Scheme_Object *varbs, *valbs, *ev; Scheme_Hash_Tree *ht; char *var; char *val; - int rc = 0, errid = 0; if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_environment_variables_type)) scheme_wrong_contract("environment-variables-set!", "environment-variables?", 0, argc, argv); @@ -2524,23 +2377,13 @@ static Scheme_Object *sch_putenv(int argc, Scheme_Object *argv[]) val = SCHEME_BYTE_STR_VAL(valbs); } -#ifdef DOS_FILE_SYSTEM - rc = !SetEnvironmentVariable(var, val); - if (rc) - errid = GetLastError(); -#else - rc = sch_unix_putenv(var, val, SCHEME_BYTE_STRLEN_VAL(varbs), (val ? SCHEME_BYTE_STRLEN_VAL(valbs) : 0)); - errid = errno; -#endif - - if (rc) { + if (!rktio_setenv(scheme_rktio, var, val)) { if (argc > 3) return _scheme_tail_apply(argv[3], 0, NULL); else { scheme_raise_exn(MZEXN_FAIL, "environment-variables-set!: change failed\n" - " system error: %e", - errid); + " system error: %E"); } } @@ -2562,52 +2405,20 @@ static Scheme_Object *env_copy(int argc, Scheme_Object *argv[]) /* copy system environment variables into a hash table: */ ht = scheme_make_hash_tree(SCHEME_hashtr_equal); -#ifdef DOS_FILE_SYSTEM { - char *p; - GC_CAN_IGNORE wchar_t *e; - int i, start, j; + intptr_t i; + rktio_envvars_t *envvars; Scheme_Object *var, *val; - e = GetEnvironmentStringsW(); - - for (i = 0; e[i]; ) { - start = i; - while (e[i]) { i++; } - p = NARROW_PATH(e XFORM_OK_PLUS start); - for (j = 0; p[j] && p[j] != '='; j++) { - } - if (j && p[j]) { - var = scheme_make_immutable_sized_byte_string(p, j, 1); - val = scheme_make_immutable_sized_byte_string(p XFORM_OK_PLUS j + 1, -1, 1); - var = normalize_env_case(var); - ht = scheme_hash_tree_set(ht, var, val); - } - i++; + envvars = rktio_envvars(scheme_rktio); + for (i = rktio_envvars_count(scheme_rktio, envvars); i--; ) { + var = scheme_make_immutable_sized_byte_string(rktio_envvars_name_ref(scheme_rktio, envvars, i), -1, 1); + val = scheme_make_immutable_sized_byte_string(rktio_envvars_value_ref(scheme_rktio, envvars, i), -1, 1); + ht = scheme_hash_tree_set(ht, var, val); } - FreeEnvironmentStringsW(e); + rktio_envvars_free(scheme_rktio, envvars); } -#else - { - int i, j; - char **ea, *p; - Scheme_Object *var, *val; - - ea = GET_ENVIRON_ARRAY; - - for (i = 0; ea[i]; i++) { - p = ea[i]; - for (j = 0; p[j] && p[j] != '='; j++) { - } - if (p[j]) { - var = scheme_make_immutable_sized_byte_string(p, j, 1); - val = scheme_make_immutable_sized_byte_string(p XFORM_OK_PLUS j + 1, -1, 1); - ht = scheme_hash_tree_set(ht, var, val); - } - } - } -#endif return scheme_make_environment_variables(ht); } @@ -2674,99 +2485,52 @@ static Scheme_Object *sch_getenv_names(int argc, Scheme_Object *argv[]) return r; } -#ifdef DOS_FILE_SYSTEM -static int wc_strlen(const wchar_t *ws) -{ - int l; - for (l =0; ws[l]; l++) { } - return l; -} -#endif +/* Temporarily use internal function: */ +extern void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars); +/* This will go away when we use rktio processes: */ void *scheme_environment_variables_to_block(Scheme_Object *ev, int *_need_free) { + Scheme_Hash_Tree *ht; Scheme_Object *key, *val; - - ht = SCHEME_ENVVARS_TABLE(ev); - if (!ht) { - *_need_free = 0; -#ifdef DOS_FILE_SYSTEM - return NULL; -#else - return GET_ENVIRON_ARRAY; -#endif - } + void *p; *_need_free = 1; -#ifdef DOS_FILE_SYSTEM - { - mzlonglong i; - int len = 0, slen; - GC_CAN_IGNORE wchar_t *r, *s; + ht = SCHEME_ENVVARS_TABLE(ev); + if (!ht) { + rktio_envvars_t *envvars; + envvars = rktio_envvars(scheme_rktio); - for (i = scheme_hash_tree_next(ht, -1); i != -1; i = scheme_hash_tree_next(ht, i)) { - scheme_hash_tree_index(ht, i, &key, &val); - len += wc_strlen(WIDE_PATH(SCHEME_BYTE_STR_VAL(key))); - len += wc_strlen(WIDE_PATH(SCHEME_BYTE_STR_VAL(val))); - len += 2; - } + p = rktio_envvars_to_block(scheme_rktio, envvars); + + rktio_envvars_free(scheme_rktio, envvars); - r = (wchar_t *)malloc((len + 1) * sizeof(wchar_t)); - - len = 0; - - for (i = scheme_hash_tree_next(ht, -1); i != -1; i = scheme_hash_tree_next(ht, i)) { - scheme_hash_tree_index(ht, i, &key, &val); - s = WIDE_PATH(SCHEME_BYTE_STR_VAL(key)); - slen = wc_strlen(s); - memcpy(r XFORM_OK_PLUS len, s, slen * sizeof(wchar_t)); - len += slen; - r[len++] = '='; - s = WIDE_PATH(SCHEME_BYTE_STR_VAL(val)); - slen = wc_strlen(s); - memcpy(r XFORM_OK_PLUS len, s, slen * sizeof(wchar_t)); - len += slen; - r[len++] = 0; - } - r[len] = 0; - - return r; + return p; } -#else + { - GC_CAN_IGNORE char **r, *s; + rktio_envvars_t *envvars; mzlonglong i; - intptr_t len = 0, slen, c; + envvars = rktio_empty_envvars(scheme_rktio); + for (i = scheme_hash_tree_next(ht, -1); i != -1; i = scheme_hash_tree_next(ht, i)) { scheme_hash_tree_index(ht, i, &key, &val); - len += SCHEME_BYTE_STRLEN_VAL(key); - len += SCHEME_BYTE_STRLEN_VAL(val); - len += 2; + + rktio_envvars_set(scheme_rktio, + envvars, + SCHEME_BYTE_STR_VAL(key), + SCHEME_BYTE_STR_VAL(val)); } - r = (char **)malloc((ht->count+1) * sizeof(char*) + len); - s = (char *)(r + (ht->count+1)); - c = 0; - for (i = scheme_hash_tree_next(ht, -1); i != -1; i = scheme_hash_tree_next(ht, i)) { - scheme_hash_tree_index(ht, i, &key, &val); - r[c++] = s; - slen = SCHEME_BYTE_STRLEN_VAL(key); - memcpy(s, SCHEME_BYTE_STR_VAL(key), slen); - s[slen] = '='; - s = s XFORM_OK_PLUS (slen + 1); - slen = SCHEME_BYTE_STRLEN_VAL(val); - memcpy(s, SCHEME_BYTE_STR_VAL(val), slen); - s[slen] = 0; - s = s XFORM_OK_PLUS (slen + 1); - } - r[c] = NULL; + p = rktio_envvars_to_block(scheme_rktio, envvars); - return r; + rktio_envvars_free(scheme_rktio, envvars); + + return p; } -#endif } /***********************************************************************/ diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index 5cf6fe984e..24f565bb04 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -169,19 +169,39 @@ RKTIO_EXTERN int rktio_udp_change_multicast_group(rktio_t *rktio, rktio_fd_t *rf /*************************************************/ /* Environment variables */ +/* Check whether a string is valid as a new (e.g., no "=") */ +RKTIO_EXTERN int rktio_is_ok_envvar_name(rktio_t *rktio, const char *name); + +/* Checks whether environment variables are case-folded by the OS. + That doesn't mean that clients need to case-fold names, but clients + may want to immitate the OS. */ +RKTIO_EXTERN int rktio_are_envvar_names_case_insensitive(rktio_t *rktio); + +/* Gets an environment variable value, or reports + `RKTIO_ERROR_NO_SUCH_ENVVAR` when returning NULL; the result must + be freed. */ +RKTIO_EXTERN char *rktio_getenv(rktio_t *rktio, const char *name); + +/* Set an environment variable's value, where a NULL value for `val` + unsets it. */ +RKTIO_EXTERN rktio_ok_t rktio_setenv(rktio_t *rktio, const char *name, const char *val); + typedef struct rktio_envvars_t rktio_envvars_t; -RKTIO_EXTERN char *rktio_getenv(rktio_t *rktio, char *name); -RKTIO_EXTERN int rktio_setenv(rktio_t *rktio, const char *name, const char *val); - +/* Extracts all environment variables into a record */ RKTIO_EXTERN rktio_envvars_t *rktio_envvars(rktio_t *rktio); +/* Create an empty environment-variables record: */ RKTIO_EXTERN rktio_envvars_t *rktio_empty_envvars(rktio_t *rktio); +/* Clones an environment-variable record: */ RKTIO_EXTERN rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars); +/* Deallocates an environment-variables record: */ RKTIO_EXTERN void rktio_envvars_free(rktio_t *rktio, rktio_envvars_t *envvars); +/* Access/update environment-variables record by name: */ RKTIO_EXTERN char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, char *name); RKTIO_EXTERN void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, char *name, char *value); +/* Access/update environment-variables record by index: */ RKTIO_EXTERN intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars); RKTIO_EXTERN char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i); RKTIO_EXTERN char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i); @@ -496,6 +516,7 @@ enum { RKTIO_ERROR_TRY_AGAIN, /* for UDP */ RKTIO_ERROR_TRY_AGAIN_WITH_IPV4, /* for TCP listen */ RKTIO_ERROR_TIME_OUT_OF_RANGE, + RKTIO_ERROR_NO_SUCH_ENVVAR, }; /* GAI error sub-codes */ diff --git a/racket/src/rktio/rktio_envvars.c b/racket/src/rktio/rktio_envvars.c index 748c0829d3..2ddd0cd3b8 100644 --- a/racket/src/rktio/rktio_envvars.c +++ b/racket/src/rktio/rktio_envvars.c @@ -19,15 +19,40 @@ extern char **environ; # define GET_ENVIRON_ARRAY environ #endif -char *rktio_getenv(rktio_t *rktio, char *name) + +int rktio_is_ok_envvar_name(rktio_t *rktio, const char *s) +{ + int i = strlen(s); +#ifdef RKTIO_SYSTEM_WINDOWS + if (!s[0]) return 0; +#endif + while (i--) { + if (s[i] == '=') + return 0; + } + return 1; +} + +int rktio_are_envvar_names_case_insensitive(rktio_t *rktio) +{ +#ifdef RKTIO_SYSTEM_WINDOWS + return 1; +#else + return 0; +#endif +} + +char *rktio_getenv(rktio_t *rktio, const char *name) { #ifdef RKTIO_SYSTEM_UNIX char *s; s = getenv(name); if (s) return MSC_IZE(strdup)(s); - else + else { + set_racket_error(RKTIO_ERROR_NO_SUCH_ENVVAR); return NULL; + } #endif #ifdef RKTIO_SYSTEM_WINDOWS intptr_t value_size; @@ -44,6 +69,7 @@ char *rktio_getenv(rktio_t *rktio, char *name) free(value_w); return value; } + set_racket_error(RKTIO_ERROR_NO_SUCH_ENVVAR); return NULL; #endif } @@ -52,25 +78,13 @@ int rktio_setenv(rktio_t *rktio, const char *name, const char *val) { #ifdef RKTIO_SYSTEM_UNIX if (val) { - char *buffer; - intptr_t total_length, r, varlen, vallen; - - varlen = strlen(name); - vallen = strlen(val); - total_length = varlen + vallen + 2; - - buffer = malloc(total_length); - - memcpy(buffer, name, varlen); - buffer[varlen] = '='; - memcpy(buffer + varlen + 1, val, vallen + 1); + int r; - r = putenv(buffer); + r = setenv(name, val, 1); + if (r) get_posix_error(); - free(buffer); - return (r ? 0 : 1); } else { /* on some platforms, unsetenv() returns void */ @@ -238,6 +252,7 @@ static void envvars_resize(rktio_envvars_t *envvars, intptr_t new_size) free(envvars->names); free(envvars->vals); + envvars->size = new_size; envvars->names = new_names; envvars->vals = new_vals; } diff --git a/racket/src/rktio/rktio_error.c b/racket/src/rktio/rktio_error.c index 0560bbd954..8a061205b8 100644 --- a/racket/src/rktio/rktio_error.c +++ b/racket/src/rktio/rktio_error.c @@ -32,6 +32,7 @@ err_str_t err_strs[] = { { RKTIO_ERROR_TRY_AGAIN, "no UDP message available" }, { RKTIO_ERROR_TRY_AGAIN_WITH_IPV4, "listen failed, but try again with just IPv4 addresses" }, { RKTIO_ERROR_TIME_OUT_OF_RANGE, "time value out-of-range for date conversion" }, + { RKTIO_ERROR_NO_SUCH_ENVVAR, "no value as an environment variable" }, { 0, NULL } };