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:
parent
69095fbb48
commit
60078e7950
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user