rktio: environment variables
This commit is contained in:
parent
a767ea38fc
commit
b5e88e70c2
|
@ -723,13 +723,13 @@ int main()
|
|||
rktio_status_t *status;
|
||||
rktio_process_result_t *result;
|
||||
char *argv[1] = { "/bin/cat" };
|
||||
rktio_envvars_t *envvars = NULL;
|
||||
rktio_envvars_t *envvars = rktio_envvars(rktio);
|
||||
rktio_fd_t *err_fd = rktio_system_fd(rktio, 2, RKTIO_OPEN_WRITE);
|
||||
int i;
|
||||
|
||||
result = rktio_process(rktio, "/bin/cat", 1, argv,
|
||||
result = rktio_process(rktio, argv[0], 1, argv,
|
||||
NULL, NULL, err_fd,
|
||||
rktio_get_current_directory(rktio), envvars,
|
||||
pwd, envvars,
|
||||
0,
|
||||
NULL);
|
||||
check_valid(result);
|
||||
|
@ -757,13 +757,11 @@ int main()
|
|||
rktio_process_forget(rktio, result->process);
|
||||
free(result);
|
||||
|
||||
check_valid(rktio_close(rktio, err_fd));
|
||||
|
||||
/* Run and then break or kill "/bin/cat" */
|
||||
/* Run and then break or kill `cat` */
|
||||
for (i = 0; i < 2; i++) {
|
||||
result = rktio_process(rktio, "/bin/cat", 1, argv,
|
||||
result = rktio_process(rktio, argv[0], 1, argv,
|
||||
NULL, NULL, err_fd,
|
||||
rktio_get_current_directory(rktio), envvars,
|
||||
pwd, envvars,
|
||||
0,
|
||||
NULL);
|
||||
check_valid(result);
|
||||
|
@ -802,7 +800,49 @@ int main()
|
|||
rktio_process_forget(rktio, result->process);
|
||||
free(result);
|
||||
}
|
||||
|
||||
{
|
||||
char *argv[2] = { "/usr/bin/printenv", "RKTIO_EXAMPLE" };
|
||||
|
||||
check_valid(!rktio_envvars_get(rktio, envvars, "RKTIO_EXAMPLE"));
|
||||
rktio_envvars_set(rktio, envvars, "RKTIO_EXAMPLE", "howdy");
|
||||
s = rktio_envvars_get(rktio, envvars, "RKTIO_EXAMPLE");
|
||||
check_valid(s);
|
||||
check_valid(!strcmp(s, "howdy"));
|
||||
free(s);
|
||||
|
||||
result = rktio_process(rktio, argv[0], 2, argv,
|
||||
NULL, NULL, err_fd,
|
||||
pwd, envvars,
|
||||
0,
|
||||
NULL);
|
||||
check_valid(result);
|
||||
|
||||
/* Assume that a pipe can buffer the minimal output from `printenv`: */
|
||||
pause_for_process(rktio, result->process);
|
||||
wait_read(rktio, result->stdout_fd);
|
||||
|
||||
{
|
||||
char buffer[32];
|
||||
intptr_t amt;
|
||||
amt = rktio_read(rktio, result->stdout_fd, buffer, sizeof(buffer));
|
||||
check_valid(amt == 6);
|
||||
check_valid(!strncmp(buffer, "howdy\n", 6));
|
||||
}
|
||||
|
||||
check_valid(rktio_close(rktio, result->stdin_fd));
|
||||
check_valid(rktio_close(rktio, result->stdout_fd));
|
||||
|
||||
rktio_process_forget(rktio, result->process);
|
||||
free(result);
|
||||
}
|
||||
|
||||
rktio_ennvars_free(rktio, envvars);
|
||||
|
||||
rktio_forget(rktio, err_fd);
|
||||
}
|
||||
|
||||
free(pwd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -145,6 +145,21 @@ int rktio_udp_change_multicast_group(rktio_t *rktio, rktio_fd_t *rfd,
|
|||
|
||||
typedef struct rktio_envvars_t rktio_envvars_t;
|
||||
|
||||
char *rktio_getenv(rktio_t *rktio, char *name);
|
||||
int rktio_setenv(rktio_t *rktio, const char *name, const char *val);
|
||||
|
||||
rktio_envvars_t *rktio_envvars(rktio_t *rktio);
|
||||
rktio_envvars_t *rktio_empty_envvars(rktio_t *rktio);
|
||||
rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
void rktio_ennvars_free(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
|
||||
char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, char *name);
|
||||
void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, char *name, char *value);
|
||||
|
||||
intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||
char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
|
||||
char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
|
||||
|
||||
/*************************************************/
|
||||
/* Processes */
|
||||
|
||||
|
|
|
@ -3,10 +3,360 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct rktio_envvars_t {
|
||||
intptr_t count, size;
|
||||
char **names;
|
||||
char **vals;
|
||||
};
|
||||
|
||||
#if defined(OS_X) && !TARGET_OS_IPHONE
|
||||
# include <crt_externs.h>
|
||||
# define GET_ENVIRON_ARRAY *_NSGetEnviron()
|
||||
#endif
|
||||
|
||||
#if defined(RKTIO_SYSTEM_UNIX) && !defined(GET_ENVIRON_ARRAY)
|
||||
extern char **environ;
|
||||
# define GET_ENVIRON_ARRAY environ
|
||||
#endif
|
||||
|
||||
char *rktio_getenv(rktio_t *rktio, char *name)
|
||||
{
|
||||
#ifdef RKTIO_SYSTEM_UNIX
|
||||
char *s;
|
||||
s = getenv(name);
|
||||
if (s)
|
||||
return strdup(s);
|
||||
else
|
||||
return NULL;
|
||||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
intptr_t value_size;
|
||||
value_size = GetEnvironmentVariableW(WIDE_PATH_temp(name), NULL, 0);
|
||||
if (value_size) {
|
||||
wchar_t *value_w;
|
||||
char *value;
|
||||
intptr_t got;
|
||||
value_w = malloc(sizeof(wchar_t) * value_size);
|
||||
got = GetEnvironmentVariableW(WIDE_PATH_temp(name), value_w, value_size);
|
||||
if (got < value_size)
|
||||
value_w[got] = 0;
|
||||
value = NARROW_PATH_copy(value_w);
|
||||
free(value_w);
|
||||
return value;
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
r = putenv(buffer);
|
||||
if (r)
|
||||
get_posix_error();
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (r ? 0 : 1);
|
||||
} else {
|
||||
/* on some platforms, unsetenv() returns void */
|
||||
unsetenv(name);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
int rc;
|
||||
char *val_w;
|
||||
|
||||
if (val)
|
||||
val_w = WIDE_PATH_copy(val);
|
||||
else
|
||||
val_w = NULL;
|
||||
|
||||
rc = SetEnvironmentVariableW(WIDE_PATH_temp(var), val_w);
|
||||
|
||||
if (val_w)
|
||||
free(val_w);
|
||||
|
||||
if (rc)
|
||||
return 1;
|
||||
|
||||
set_windows_error();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
rktio_envvars_t *rktio_envvars(rktio_t *rktio)
|
||||
{
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
{
|
||||
char *p;
|
||||
wchar_t *e;
|
||||
intptr_t i, start, j, count;
|
||||
rktio_envvars_t *envvars;
|
||||
|
||||
e = GetEnvironmentStringsW();
|
||||
if (!e) {
|
||||
get_windows_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (e[i]) {
|
||||
count++;
|
||||
for (i = 0; e[i]; ) {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
ennvars = malloc(sizeof(rktio_envvars_t));
|
||||
envvars->size = count;
|
||||
envvars->count = count;
|
||||
envvars->names = malloc(count * sizeof(char *));
|
||||
envvars->vals = malloc(count * sizeof(char *));
|
||||
|
||||
count = 0;
|
||||
for (i = 0; e[i]; ) {
|
||||
start = i;
|
||||
while (e[i]) { i++; }
|
||||
p = NARROW_PATH_copy(e + start);
|
||||
for (j = 0; p[j] && p[j] != '='; j++) {
|
||||
}
|
||||
p[j] = 0;
|
||||
envvars->names[count] = strdup(p);
|
||||
envvars->vals[count] = strdup(p+j+1);
|
||||
free(p);
|
||||
i++;
|
||||
}
|
||||
|
||||
FreeEnvironmentStringsW(e);
|
||||
|
||||
return envvars;
|
||||
}
|
||||
#else
|
||||
{
|
||||
intptr_t i, j;
|
||||
char **ea, *p;
|
||||
rktio_envvars_t *envvars;
|
||||
|
||||
ea = GET_ENVIRON_ARRAY;
|
||||
|
||||
for (i = 0; ea[i]; i++) {
|
||||
}
|
||||
|
||||
envvars = malloc(sizeof(rktio_envvars_t));
|
||||
envvars->size = i;
|
||||
envvars->count = i;
|
||||
envvars->names = malloc(i * sizeof(char *));
|
||||
envvars->vals = malloc(i * sizeof(char *));
|
||||
|
||||
for (i = 0; ea[i]; i++) {
|
||||
p = ea[i];
|
||||
for (j = 0; p[j] && p[j] != '='; j++) {
|
||||
}
|
||||
envvars->names[i] = strndup(p, j);
|
||||
envvars->vals[i] = strdup(p+j+1);
|
||||
}
|
||||
|
||||
return envvars;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rktio_envvars_t *rktio_empty_envvars(rktio_t *rktio)
|
||||
{
|
||||
rktio_envvars_t *envvars;
|
||||
|
||||
envvars = malloc(sizeof(rktio_envvars_t));
|
||||
envvars->size = 2;
|
||||
envvars->count = 0;
|
||||
envvars->names = malloc(envvars->size * sizeof(char *));
|
||||
envvars->vals = malloc(envvars->size * sizeof(char *));
|
||||
|
||||
return envvars;
|
||||
}
|
||||
|
||||
rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||
{
|
||||
rktio_envvars_t *new_envvars;
|
||||
intptr_t i;
|
||||
|
||||
new_envvars = malloc(sizeof(rktio_envvars_t));
|
||||
new_envvars->size = envvars->count;
|
||||
new_envvars->count = envvars->count;
|
||||
new_envvars->names = malloc(envvars->count * sizeof(char *));
|
||||
new_envvars->vals = malloc(envvars->count * sizeof(char *));
|
||||
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
new_envvars->names[i] = strdup(envvars->names[i]);
|
||||
new_envvars->vals[i] = strdup(envvars->vals[i]);
|
||||
}
|
||||
|
||||
return new_envvars;
|
||||
}
|
||||
|
||||
void rktio_ennvars_free(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||
{
|
||||
free(envvars->names);
|
||||
free(envvars->vals);
|
||||
free(envvars);
|
||||
}
|
||||
|
||||
static void envvars_resize(rktio_envvars_t *envvars, intptr_t new_size)
|
||||
{
|
||||
char **new_names;
|
||||
char **new_vals;
|
||||
|
||||
new_names = malloc(sizeof(char *) * new_size);
|
||||
new_vals = malloc(sizeof(char *) * new_size);
|
||||
|
||||
memcpy(new_names, envvars->names, sizeof(char*) * envvars->count);
|
||||
memcpy(new_vals, envvars->vals, sizeof(char*) * envvars->count);
|
||||
|
||||
free(envvars->names);
|
||||
free(envvars->vals);
|
||||
|
||||
envvars->names = new_names;
|
||||
envvars->vals = new_vals;
|
||||
}
|
||||
|
||||
intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||
{
|
||||
return envvars->count;
|
||||
}
|
||||
|
||||
char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i)
|
||||
{
|
||||
return strdup(envvars->names[i]);
|
||||
}
|
||||
|
||||
char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i)
|
||||
{
|
||||
return strdup(envvars->vals[i]);
|
||||
}
|
||||
|
||||
char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, char *name)
|
||||
{
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
if (!strcmp(envvars->names[i], name))
|
||||
return strdup(envvars->vals[i]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, char *name, char *value)
|
||||
{
|
||||
intptr_t i, j;
|
||||
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
if (!strcmp(envvars->names[i], name)) {
|
||||
if (value) {
|
||||
free(envvars->vals[i]);
|
||||
envvars->vals[i] = strdup(value);
|
||||
} else {
|
||||
free(envvars->names[i]);
|
||||
free(envvars->vals[i]);
|
||||
for (j = i + 1; j < envvars->count; j++) {
|
||||
envvars->names[j-1] = envvars->names[j];
|
||||
envvars->vals[j-1] = envvars->vals[j];
|
||||
}
|
||||
if ((envvars->size > 4)
|
||||
&& (envvars->count <= (envvars->size >> 2))) {
|
||||
envvars_resize(envvars, envvars->size >> 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
if (envvars->count == envvars->size)
|
||||
envvars_resize(envvars, envvars->size * 2);
|
||||
|
||||
envvars->names[envvars->count] = name;
|
||||
envvars->vals[envvars->count] = value;
|
||||
envvars->count++;
|
||||
}
|
||||
|
||||
void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||
{
|
||||
void *p;
|
||||
p = malloc(sizeof(char *));
|
||||
*(char **)p = NULL;
|
||||
return p;
|
||||
#ifdef RKTIO_SYSTEM_UNIX
|
||||
char **r, *s;
|
||||
intptr_t i;
|
||||
intptr_t len = 0, slen, c;
|
||||
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
len += strlen(envvars->names[i]);
|
||||
len += strlen(envvars->vals[i]);
|
||||
len += 2;
|
||||
}
|
||||
|
||||
r = (char **)malloc((envvars->count+1) * sizeof(char*) + len);
|
||||
s = (char *)(r + (envvars->count+1));
|
||||
c = 0;
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
r[c++] = s;
|
||||
slen = strlen(envvars->names[i]);
|
||||
memcpy(s, envvars->names[i], slen);
|
||||
s[slen] = '=';
|
||||
s = s + (slen + 1);
|
||||
slen = strlen(envvars->vals[i]);
|
||||
memcpy(s, envvars->vals[i], slen);
|
||||
s[slen] = 0;
|
||||
s = s + (slen + 1);
|
||||
}
|
||||
r[c] = NULL;
|
||||
|
||||
return r;
|
||||
#endif
|
||||
#ifdef RKTIO_SYSTEM_WINDOWS
|
||||
intptr_t i;
|
||||
intptr_t len = 0, slen;
|
||||
wchar_t *r, *s;
|
||||
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
len += wc_strlen(WIDE_PATH_temp(envvars->names[i]));
|
||||
len += wc_strlen(WIDE_PATH_temp(envvars->vals[i]));
|
||||
len += 2;
|
||||
}
|
||||
|
||||
r = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
||||
|
||||
len = 0;
|
||||
|
||||
for (i = 0; i < envvars->count; i++) {
|
||||
s = WIDE_PATH_temp(envvars->names[i]);
|
||||
slen = wc_strlen(s);
|
||||
memcpy(r XFORM_OK_PLUS len, s, slen * sizeof(wchar_t));
|
||||
len += slen;
|
||||
r[len++] = '=';
|
||||
s = WIDE_PATH(envvars->vals[i]);
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user