1
0
mirror of https://github.com/janet-lang/janet synced 2025-01-14 09:25:41 +00:00

Change os/execute implementation for windows.

This commit is contained in:
Calvin Rose 2021-02-14 11:04:59 -06:00
parent 69095fbb48
commit 60078e7950

View File

@ -187,57 +187,81 @@ static Janet os_exit(int32_t argc, Janet *argv) {
#ifndef JANET_NO_PROCESSES #ifndef JANET_NO_PROCESSES
/* Get env for os_execute */ /* Get env for os_execute */
static char **os_execute_env(int32_t argc, const Janet *argv) { #ifdef JANET_WINDOWS
char **envp = NULL; typedef char *EnvBlock;
if (argc > 2) { #else
JanetDictView dict = janet_getdictionary(argv, 2); typedef char **EnvBlock;
envp = janet_smalloc(sizeof(char *) * ((size_t)dict.len + 1)); #endif
int32_t j = 0;
for (int32_t i = 0; i < dict.cap; i++) { /* Get env for os_execute */
const JanetKV *kv = dict.kvs + i; static EnvBlock os_execute_env(int32_t argc, const Janet *argv) {
if (!janet_checktype(kv->key, JANET_STRING)) continue; if (argc <= 2) return NULL;
if (!janet_checktype(kv->value, JANET_STRING)) continue; JanetDictView dict = janet_getdictionary(argv, 2);
const uint8_t *keys = janet_unwrap_string(kv->key); #ifdef JANET_WINDOWS
const uint8_t *vals = janet_unwrap_string(kv->value); JanetBuffer *temp = janet_buffer(10);
int32_t klen = janet_string_length(keys); for (int32_t i = 0; i < dict.cap; i++) {
int32_t vlen = janet_string_length(vals); const JanetKV *kv = dict.kvs + i;
/* Check keys has no embedded 0s or =s. */ if (!janet_checktype(kv->key, JANET_STRING)) continue;
int skip = 0; if (!janet_checktype(kv->value, JANET_STRING)) continue;
for (int32_t k = 0; k < klen; k++) { const uint8_t *keys = janet_unwrap_string(kv->key);
if (keys[k] == '\0' || keys[k] == '=') { const uint8_t *vals = janet_unwrap_string(kv->value);
skip = 1; janet_buffer_push_bytes(temp, keys, janet_string_length(keys));
break; janet_buffer_push_u8(temp, '=');
} janet_buffer_push_bytes(temp, vals, janet_string_length(vals));
} janet_buffer_push_u8(temp, '\0');
if (skip) continue;
char *envitem = janet_smalloc((size_t) klen + (size_t) vlen + 2);
memcpy(envitem, keys, klen);
envitem[klen] = '=';
memcpy(envitem + klen + 1, vals, vlen);
envitem[klen + vlen + 1] = 0;
envp[j++] = envitem;
}
envp[j] = NULL;
} }
if (temp->count == 0) return NULL;
janet_buffer_push_u8(temp, '\0');
char *ret = janet_smalloc(temp->count);
memcpy(ret, temp->data, temp->count);
return ret;
#else
char **envp = janet_smalloc(sizeof(char *) * ((size_t)dict.len + 1));
int32_t j = 0;
for (int32_t i = 0; i < dict.cap; i++) {
const JanetKV *kv = dict.kvs + i;
if (!janet_checktype(kv->key, JANET_STRING)) continue;
if (!janet_checktype(kv->value, JANET_STRING)) continue;
const uint8_t *keys = janet_unwrap_string(kv->key);
const uint8_t *vals = janet_unwrap_string(kv->value);
int32_t klen = janet_string_length(keys);
int32_t vlen = janet_string_length(vals);
/* Check keys has no embedded 0s or =s. */
int skip = 0;
for (int32_t k = 0; k < klen; k++) {
if (keys[k] == '\0' || keys[k] == '=') {
skip = 1;
break;
}
}
if (skip) continue;
char *envitem = janet_smalloc((size_t) klen + (size_t) vlen + 2);
memcpy(envitem, keys, klen);
envitem[klen] = '=';
memcpy(envitem + klen + 1, vals, vlen);
envitem[klen + vlen + 1] = 0;
envp[j++] = envitem;
}
envp[j] = NULL;
return envp; return envp;
#endif
} }
/* Free memory from os_execute. Not actually needed, but doesn't pressure the GC static void os_execute_cleanup(EnvBlock envp, const char **child_argv) {
in the happy path. */
static void os_execute_cleanup(char **envp, const char **child_argv) {
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
(void) child_argv; (void) child_argv;
janet_sfree(envp);
#else #else
janet_sfree((void *)child_argv); janet_sfree((void *)child_argv);
#endif
if (NULL != envp) { if (NULL != envp) {
char **envitem = envp; char **envitem = envp;
while (*envitem != NULL) { while (*envitem != NULL) {
janet_sfree(*envitem); free(*envitem);
envitem++; envitem++;
} }
} }
janet_sfree(envp); janet_sfree(envp);
#endif
} }
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
@ -730,12 +754,11 @@ static Janet os_execute_impl(int32_t argc, Janet *argv, int is_spawn) {
uint64_t flags = 0; uint64_t flags = 0;
if (argc > 1) { if (argc > 1) {
flags = janet_getflags(argv, 1, "epx"); flags = janet_getflags(argv, 1, "epx");
} }
/* Get environment */ /* Get environment */
int use_environ = !janet_flag_at(flags, 0); int use_environ = !janet_flag_at(flags, 0);
char **envp = os_execute_env(argc, argv); EnvBlock envp = os_execute_env(argc, argv);
/* Get arguments */ /* Get arguments */
JanetView exargs = janet_getindexed(argv, 0); JanetView exargs = janet_getindexed(argv, 0);