rktio: switch to rktio envvars

This commit is contained in:
Matthew Flatt 2017-06-14 17:04:27 -06:00
parent 49e30ea6fb
commit 63505d3e16
8 changed files with 144 additions and 332 deletions

View File

@ -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) \

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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
}
/***********************************************************************/

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 }
};