rktio: switch to rktio envvars
This commit is contained in:
parent
49e30ea6fb
commit
63505d3e16
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "schpriv.h"
|
||||
#include "schvers.h"
|
||||
#include "schrktio.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#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 <crt_externs.h>
|
||||
# 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 <windows.h>
|
||||
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
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user