rktio: environment variables
This commit is contained in:
parent
a767ea38fc
commit
b5e88e70c2
|
@ -723,13 +723,13 @@ int main()
|
||||||
rktio_status_t *status;
|
rktio_status_t *status;
|
||||||
rktio_process_result_t *result;
|
rktio_process_result_t *result;
|
||||||
char *argv[1] = { "/bin/cat" };
|
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);
|
rktio_fd_t *err_fd = rktio_system_fd(rktio, 2, RKTIO_OPEN_WRITE);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
result = rktio_process(rktio, "/bin/cat", 1, argv,
|
result = rktio_process(rktio, argv[0], 1, argv,
|
||||||
NULL, NULL, err_fd,
|
NULL, NULL, err_fd,
|
||||||
rktio_get_current_directory(rktio), envvars,
|
pwd, envvars,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
check_valid(result);
|
check_valid(result);
|
||||||
|
@ -757,13 +757,11 @@ int main()
|
||||||
rktio_process_forget(rktio, result->process);
|
rktio_process_forget(rktio, result->process);
|
||||||
free(result);
|
free(result);
|
||||||
|
|
||||||
check_valid(rktio_close(rktio, err_fd));
|
/* Run and then break or kill `cat` */
|
||||||
|
|
||||||
/* Run and then break or kill "/bin/cat" */
|
|
||||||
for (i = 0; i < 2; i++) {
|
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,
|
NULL, NULL, err_fd,
|
||||||
rktio_get_current_directory(rktio), envvars,
|
pwd, envvars,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
check_valid(result);
|
check_valid(result);
|
||||||
|
@ -802,7 +800,49 @@ int main()
|
||||||
rktio_process_forget(rktio, result->process);
|
rktio_process_forget(rktio, result->process);
|
||||||
free(result);
|
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;
|
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;
|
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 */
|
/* Processes */
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,360 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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 *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars)
|
||||||
{
|
{
|
||||||
void *p;
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
p = malloc(sizeof(char *));
|
char **r, *s;
|
||||||
*(char **)p = NULL;
|
intptr_t i;
|
||||||
return p;
|
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