740 lines
14 KiB
Plaintext
740 lines
14 KiB
Plaintext
#include <assert.h>
|
|
#include <bare.h>
|
|
#include <js.h>
|
|
#include <stdlib.h>
|
|
#include <utf.h>
|
|
#include <uv.h>
|
|
|
|
static uv_rwlock_t bare_os_env_lock;
|
|
|
|
static uv_once_t bare_os_env_lock_guard = UV_ONCE_INIT;
|
|
|
|
static void
|
|
bare_os_env_on_lock_init (void) {
|
|
int err = uv_rwlock_init(&bare_os_env_lock);
|
|
assert(err == 0);
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_type (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
uv_utsname_t buffer;
|
|
err = uv_os_uname(&buffer);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) buffer.sysname, -1, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_version (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
uv_utsname_t buffer;
|
|
err = uv_os_uname(&buffer);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) buffer.version, -1, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_release (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
uv_utsname_t buffer;
|
|
err = uv_os_uname(&buffer);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) buffer.release, -1, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_machine (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
uv_utsname_t buffer;
|
|
err = uv_os_uname(&buffer);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) buffer.machine, -1, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_exec_path (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t len = 4096;
|
|
char exec_path[4096];
|
|
|
|
err = uv_exepath(exec_path, &len);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) exec_path, len, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_pid (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
js_value_t *result;
|
|
err = js_create_uint32(env, uv_os_getpid(), &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_ppid (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
js_value_t *result;
|
|
err = js_create_uint32(env, uv_os_getppid(), &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_cwd (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t len = 4096;
|
|
char cwd[4096];
|
|
|
|
err = uv_cwd(cwd, &len);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) cwd, len, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_chdir (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 1;
|
|
js_value_t *argv[1];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 1);
|
|
|
|
utf8_t dir[4096];
|
|
err = js_get_value_string_utf8(env, argv[0], dir, 4096, NULL);
|
|
assert(err == 0);
|
|
|
|
err = uv_chdir((char *) dir);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_tmpdir (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t len = 4096;
|
|
char tmpdir[4096];
|
|
|
|
err = uv_os_tmpdir(tmpdir, &len);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) tmpdir, len, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_homedir (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t len = 4096;
|
|
char homedir[4096];
|
|
|
|
err = uv_os_homedir(homedir, &len);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) homedir, len, &result);
|
|
if (err < 0) return NULL;
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_kill (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 2;
|
|
js_value_t *argv[2];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 2);
|
|
|
|
uint32_t pid;
|
|
err = js_get_value_uint32(env, argv[0], &pid);
|
|
assert(err == 0);
|
|
|
|
uint32_t signum;
|
|
err = js_get_value_uint32(env, argv[1], &signum);
|
|
assert(err == 0);
|
|
|
|
err = uv_kill(pid, signum);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_get_process_title (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
char title[256];
|
|
err = uv_get_process_title(title, 256);
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_string_utf8(env, (utf8_t *) title, -1, &result);
|
|
assert(err == 0);
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_set_process_title (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 1;
|
|
js_value_t *argv[1];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 1);
|
|
|
|
utf8_t data[256];
|
|
err = js_get_value_string_utf8(env, argv[0], data, 256, NULL);
|
|
assert(err == 0);
|
|
|
|
err = uv_set_process_title((char *) data);
|
|
assert(err == 0);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_get_env_keys (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
uv_env_item_t *items;
|
|
int len;
|
|
|
|
uv_rwlock_rdlock(&bare_os_env_lock);
|
|
|
|
err = uv_os_environ(&items, &len);
|
|
|
|
uv_rwlock_rdunlock(&bare_os_env_lock);
|
|
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
return NULL;
|
|
}
|
|
|
|
js_value_t *result;
|
|
err = js_create_array_with_length(env, len, &result);
|
|
assert(err == 0);
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
uv_env_item_t *item = &items[i];
|
|
|
|
js_value_t *val;
|
|
err = js_create_string_utf8(env, (utf8_t *) item->name, -1, &val);
|
|
assert(err == 0);
|
|
|
|
err = js_set_element(env, result, i, val);
|
|
assert(err == 0);
|
|
}
|
|
|
|
uv_os_free_environ(items, len);
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_get_env (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 1;
|
|
js_value_t *argv[1];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 1);
|
|
|
|
size_t name_len;
|
|
err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
|
|
assert(err == 0);
|
|
|
|
name_len += 1 /* NULL */;
|
|
|
|
utf8_t *name = malloc(name_len);
|
|
err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
|
|
assert(err == 0);
|
|
|
|
uv_rwlock_rdlock(&bare_os_env_lock);
|
|
|
|
size_t value_len = 256;
|
|
char *value = malloc(value_len);
|
|
err = uv_os_getenv((char *) name, value, &value_len);
|
|
|
|
js_value_t *result;
|
|
|
|
if (err == UV_ENOENT) {
|
|
err = js_get_undefined(env, &result);
|
|
assert(err == 0);
|
|
} else {
|
|
if (err == UV_ENOBUFS) {
|
|
value = realloc(value, value_len);
|
|
|
|
err = uv_os_getenv((char *) name, value, &value_len);
|
|
assert(err == 0);
|
|
} else if (err < 0) {
|
|
uv_rwlock_rdunlock(&bare_os_env_lock);
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
free(name);
|
|
return NULL;
|
|
}
|
|
|
|
err = js_create_string_utf8(env, (utf8_t *) value, value_len, &result);
|
|
assert(err == 0);
|
|
}
|
|
|
|
uv_rwlock_rdunlock(&bare_os_env_lock);
|
|
|
|
free(name);
|
|
free(value);
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_has_env (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 1;
|
|
js_value_t *argv[1];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 1);
|
|
|
|
size_t name_len;
|
|
err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
|
|
assert(err == 0);
|
|
|
|
utf8_t *name = malloc(++name_len);
|
|
err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
|
|
assert(err == 0);
|
|
|
|
uv_rwlock_rdlock(&bare_os_env_lock);
|
|
|
|
size_t value_len = 1;
|
|
char value[1];
|
|
err = uv_os_getenv((char *) name, value, &value_len);
|
|
|
|
uv_rwlock_rdunlock(&bare_os_env_lock);
|
|
|
|
if (err != 0 && err != UV_ENOENT && err != UV_ENOBUFS) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
free(name);
|
|
return NULL;
|
|
}
|
|
|
|
free(name);
|
|
|
|
js_value_t *result;
|
|
err = js_get_boolean(env, err != UV_ENOENT, &result);
|
|
assert(err == 0);
|
|
|
|
return result;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_set_env (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 2;
|
|
js_value_t *argv[2];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 2);
|
|
|
|
size_t name_len;
|
|
err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
|
|
assert(err == 0);
|
|
|
|
utf8_t *name = malloc(++name_len);
|
|
err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
|
|
assert(err == 0);
|
|
|
|
size_t value_len;
|
|
err = js_get_value_string_utf8(env, argv[1], NULL, 0, &value_len);
|
|
assert(err == 0);
|
|
|
|
utf8_t *value = malloc(++value_len);
|
|
err = js_get_value_string_utf8(env, argv[1], value, value_len, &value_len);
|
|
assert(err == 0);
|
|
|
|
uv_rwlock_wrlock(&bare_os_env_lock);
|
|
|
|
err = uv_os_setenv((char *) name, (char *) value);
|
|
|
|
uv_rwlock_wrunlock(&bare_os_env_lock);
|
|
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
free(name);
|
|
free(value);
|
|
return NULL;
|
|
}
|
|
|
|
free(name);
|
|
free(value);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static js_value_t *
|
|
bare_os_unset_env (js_env_t *env, js_callback_info_t *info) {
|
|
int err;
|
|
|
|
size_t argc = 1;
|
|
js_value_t *argv[1];
|
|
|
|
err = js_get_callback_info(env, info, &argc, argv, NULL, NULL);
|
|
assert(err == 0);
|
|
|
|
assert(argc == 1);
|
|
|
|
size_t name_len;
|
|
err = js_get_value_string_utf8(env, argv[0], NULL, 0, &name_len);
|
|
assert(err == 0);
|
|
|
|
utf8_t *name = malloc(++name_len);
|
|
err = js_get_value_string_utf8(env, argv[0], name, name_len, &name_len);
|
|
assert(err == 0);
|
|
|
|
uv_rwlock_wrlock(&bare_os_env_lock);
|
|
|
|
err = uv_os_unsetenv((char *) name);
|
|
|
|
uv_rwlock_wrunlock(&bare_os_env_lock);
|
|
|
|
if (err < 0) {
|
|
js_throw_error(env, uv_err_name(err), uv_strerror(err));
|
|
free(name);
|
|
return NULL;
|
|
}
|
|
|
|
free(name);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static js_value_t *
|
|
init (js_env_t *env, js_value_t *exports) {
|
|
uv_once(&bare_os_env_lock_guard, bare_os_env_on_lock_init);
|
|
|
|
int err;
|
|
|
|
#define V(name, str) \
|
|
{ \
|
|
js_value_t *val; \
|
|
err = js_create_string_utf8(env, (utf8_t *) str, -1, &val); \
|
|
assert(err == 0); \
|
|
err = js_set_named_property(env, exports, name, val); \
|
|
assert(err == 0); \
|
|
}
|
|
V("platform", BARE_PLATFORM);
|
|
V("arch", BARE_ARCH);
|
|
#undef V
|
|
|
|
#define V(name, fn) \
|
|
{ \
|
|
js_value_t *val; \
|
|
err = js_create_function(env, name, -1, fn, NULL, &val); \
|
|
assert(err == 0); \
|
|
err = js_set_named_property(env, exports, name, val); \
|
|
assert(err == 0); \
|
|
}
|
|
V("type", bare_os_type);
|
|
V("version", bare_os_version);
|
|
V("release", bare_os_release);
|
|
V("machine", bare_os_machine);
|
|
V("execPath", bare_os_exec_path);
|
|
V("pid", bare_os_pid);
|
|
V("ppid", bare_os_ppid);
|
|
V("cwd", bare_os_cwd);
|
|
V("chdir", bare_os_chdir);
|
|
V("tmpdir", bare_os_tmpdir);
|
|
V("homedir", bare_os_homedir);
|
|
V("kill", bare_os_kill);
|
|
V("getProcessTitle", bare_os_get_process_title);
|
|
V("setProcessTitle", bare_os_set_process_title);
|
|
V("getEnvKeys", bare_os_get_env_keys)
|
|
V("getEnv", bare_os_get_env)
|
|
V("hasEnv", bare_os_get_env)
|
|
V("setEnv", bare_os_set_env)
|
|
V("unsetEnv", bare_os_unset_env)
|
|
#undef V
|
|
|
|
js_value_t *signals;
|
|
err = js_create_object(env, &signals);
|
|
assert(err == 0);
|
|
|
|
err = js_set_named_property(env, exports, "signals", signals);
|
|
assert(err == 0);
|
|
|
|
#define V(name) \
|
|
{ \
|
|
js_value_t *val; \
|
|
err = js_create_uint32(env, name, &val); \
|
|
assert(err == 0); \
|
|
err = js_set_named_property(env, signals, #name, val); \
|
|
assert(err == 0); \
|
|
}
|
|
#ifdef SIGHUP
|
|
V(SIGHUP);
|
|
#endif
|
|
|
|
#ifdef SIGINT
|
|
V(SIGINT);
|
|
#endif
|
|
|
|
#ifdef SIGQUIT
|
|
V(SIGQUIT);
|
|
#endif
|
|
|
|
#ifdef SIGILL
|
|
V(SIGILL);
|
|
#endif
|
|
|
|
#ifdef SIGTRAP
|
|
V(SIGTRAP);
|
|
#endif
|
|
|
|
#ifdef SIGABRT
|
|
V(SIGABRT);
|
|
#endif
|
|
|
|
#ifdef SIGIOT
|
|
V(SIGIOT);
|
|
#endif
|
|
|
|
#ifdef SIGBUS
|
|
V(SIGBUS);
|
|
#endif
|
|
|
|
#ifdef SIGFPE
|
|
V(SIGFPE);
|
|
#endif
|
|
|
|
#ifdef SIGKILL
|
|
V(SIGKILL);
|
|
#endif
|
|
|
|
#ifdef SIGUSR1
|
|
V(SIGUSR1);
|
|
#endif
|
|
|
|
#ifdef SIGSEGV
|
|
V(SIGSEGV);
|
|
#endif
|
|
|
|
#ifdef SIGUSR2
|
|
V(SIGUSR2);
|
|
#endif
|
|
|
|
#ifdef SIGPIPE
|
|
V(SIGPIPE);
|
|
#endif
|
|
|
|
#ifdef SIGALRM
|
|
V(SIGALRM);
|
|
#endif
|
|
|
|
V(SIGTERM);
|
|
|
|
#ifdef SIGCHLD
|
|
V(SIGCHLD);
|
|
#endif
|
|
|
|
#ifdef SIGSTKFLT
|
|
V(SIGSTKFLT);
|
|
#endif
|
|
|
|
#ifdef SIGCONT
|
|
V(SIGCONT);
|
|
#endif
|
|
|
|
#ifdef SIGSTOP
|
|
V(SIGSTOP);
|
|
#endif
|
|
|
|
#ifdef SIGTSTP
|
|
V(SIGTSTP);
|
|
#endif
|
|
|
|
#ifdef SIGBREAK
|
|
V(SIGBREAK);
|
|
#endif
|
|
|
|
#ifdef SIGTTIN
|
|
V(SIGTTIN);
|
|
#endif
|
|
|
|
#ifdef SIGTTOU
|
|
V(SIGTTOU);
|
|
#endif
|
|
|
|
#ifdef SIGURG
|
|
V(SIGURG);
|
|
#endif
|
|
|
|
#ifdef SIGXCPU
|
|
V(SIGXCPU);
|
|
#endif
|
|
|
|
#ifdef SIGXFSZ
|
|
V(SIGXFSZ);
|
|
#endif
|
|
|
|
#ifdef SIGVTALRM
|
|
V(SIGVTALRM);
|
|
#endif
|
|
|
|
#ifdef SIGPROF
|
|
V(SIGPROF);
|
|
#endif
|
|
|
|
#ifdef SIGWINCH
|
|
V(SIGWINCH);
|
|
#endif
|
|
|
|
#ifdef SIGIO
|
|
V(SIGIO);
|
|
#endif
|
|
|
|
#ifdef SIGPOLL
|
|
V(SIGPOLL);
|
|
#endif
|
|
|
|
#ifdef SIGLOST
|
|
V(SIGLOST);
|
|
#endif
|
|
|
|
#ifdef SIGPWR
|
|
V(SIGPWR);
|
|
#endif
|
|
|
|
#ifdef SIGINFO
|
|
V(SIGINFO);
|
|
#endif
|
|
|
|
#ifdef SIGSYS
|
|
V(SIGSYS);
|
|
#endif
|
|
|
|
#ifdef SIGUNUSED
|
|
V(SIGUNUSED);
|
|
#endif
|
|
#undef V
|
|
|
|
js_value_t *errnos;
|
|
err = js_create_object(env, &errnos);
|
|
assert(err == 0);
|
|
|
|
err = js_set_named_property(env, exports, "errnos", errnos);
|
|
assert(err == 0);
|
|
|
|
#define V(name, msg) \
|
|
{ \
|
|
js_value_t *val; \
|
|
err = js_create_int32(env, UV_##name, &val); \
|
|
assert(err == 0); \
|
|
err = js_set_named_property(env, errnos, #name, val); \
|
|
assert(err == 0); \
|
|
}
|
|
UV_ERRNO_MAP(V);
|
|
#undef V
|
|
|
|
return exports;
|
|
}
|
|
|
|
BARE_MODULE(bare_os, init)
|