configurable trans-membrance hostcall blocklist
This commit is contained in:
+311
-95
@@ -22,6 +22,25 @@ void uce_host_file_unlink(const char* path, size_t path_len, const char* current
|
||||
size_t uce_host_file_list(const char* path, size_t path_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
int uce_host_file_mkdir(const char* path, size_t path_len, const char* current, size_t current_len);
|
||||
int64_t uce_host_file_mtime(const char* path, size_t path_len, const char* current, size_t current_len);
|
||||
uint64_t uce_host_file_open(const char* path, size_t path_len, const char* current, size_t current_len, const char* mode, size_t mode_len);
|
||||
size_t uce_host_file_handle_read(uint64_t handle, uint64_t len, char* buf, size_t cap);
|
||||
size_t uce_host_file_handle_pread(uint64_t handle, uint64_t offset, uint64_t len, char* buf, size_t cap);
|
||||
uint64_t uce_host_file_handle_write(uint64_t handle, const char* data, size_t data_len);
|
||||
uint64_t uce_host_file_handle_pwrite(uint64_t handle, uint64_t offset, const char* data, size_t data_len);
|
||||
int64_t uce_host_file_handle_seek(uint64_t handle, int64_t offset, int whence);
|
||||
int64_t uce_host_file_handle_tell(uint64_t handle);
|
||||
void uce_host_file_handle_close(uint64_t handle);
|
||||
size_t uce_host_file_stat(const char* path, size_t path_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
size_t uce_host_dir_list(const char* path, size_t path_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
int uce_host_file_rename(const char* from, size_t from_len, const char* to, size_t to_len, const char* current, size_t current_len);
|
||||
int uce_host_file_copy(const char* from, size_t from_len, const char* to, size_t to_len, const char* current, size_t current_len);
|
||||
int uce_host_file_truncate(const char* path, size_t path_len, const char* current, size_t current_len, uint64_t size);
|
||||
int uce_host_dir_remove(const char* path, size_t path_len, const char* current, size_t current_len, int recursive);
|
||||
size_t uce_host_file_temp(const char* prefix, size_t prefix_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
int uce_host_file_chmod(const char* path, size_t path_len, const char* current, size_t current_len, uint32_t mode);
|
||||
int uce_host_file_symlink(const char* target, size_t target_len, const char* linkpath, size_t linkpath_len, const char* current, size_t current_len);
|
||||
size_t uce_host_file_readlink(const char* path, size_t path_len, const char* current, size_t current_len, char* buf, size_t cap);
|
||||
int uce_host_file_fsync(uint64_t handle);
|
||||
int uce_host_task_spawn(const char* key, size_t key_len, uint64_t callback_id, double interval, uint64_t timeout, int repeat);
|
||||
int uce_host_task_pid(const char* key, size_t key_len);
|
||||
int uce_host_task_kill(int pid, int sig);
|
||||
@@ -36,11 +55,21 @@ size_t uce_host_memcache_command(uint64_t sockfd, const char* command, size_t co
|
||||
size_t uce_host_mysql(const char* in, size_t in_len, char* out, size_t cap);
|
||||
size_t uce_host_request_perf(const char* in, size_t in_len, char* out, size_t cap);
|
||||
size_t uce_host_shell_exec(const char* cmd, size_t cmd_len, char* buf, size_t cap);
|
||||
int uce_host_file_open_locked(const char* path, size_t path_len, int open_flags, int lock_type, int create_mode, double wait_timeout_seconds, const char* purpose, size_t purpose_len, const char* current, size_t current_len);
|
||||
void uce_host_file_close_locked(int handle);
|
||||
void uce_host_file_release_process_locks(const char* reason, size_t reason_len);
|
||||
size_t uce_host_file_read_locked_fd(int handle, char* buf, size_t cap);
|
||||
int uce_host_file_write_locked_fd(int handle, const char* content, size_t content_len);
|
||||
size_t uce_host_sha256(const char* data, size_t data_len, char* out, size_t cap);
|
||||
size_t uce_host_sha256_hex(const char* data, size_t data_len, char* out, size_t cap);
|
||||
size_t uce_host_hmac_sha256(const char* key, size_t key_len, const char* data, size_t data_len, char* out, size_t cap);
|
||||
size_t uce_host_hmac_sha256_hex(const char* key, size_t key_len, const char* data, size_t data_len, char* out, size_t cap);
|
||||
size_t uce_host_base64_encode(const char* data, size_t data_len, char* out, size_t cap);
|
||||
size_t uce_host_base64_decode(const char* data, size_t data_len, char* out, size_t cap);
|
||||
int uce_host_crypto_equal(const char* a, size_t a_len, const char* b, size_t b_len);
|
||||
size_t uce_host_http_request(const char* in, size_t in_len, char* out, size_t cap);
|
||||
uint64_t uce_host_http_request_async(const char* in, size_t in_len);
|
||||
size_t uce_host_shell_exec_dv(const char* in, size_t in_len, char* out, size_t cap);
|
||||
uint64_t uce_host_shell_spawn(const char* in, size_t in_len);
|
||||
size_t uce_host_job_status(uint64_t job_id, char* out, size_t cap);
|
||||
size_t uce_host_job_result(uint64_t job_id, char* out, size_t cap);
|
||||
size_t uce_host_job_await(uint64_t job_id, uint64_t timeout_ms, char* out, size_t cap);
|
||||
int uce_host_job_cancel(uint64_t job_id);
|
||||
size_t uce_host_path_real(const char* path, size_t path_len, char* buf, size_t cap);
|
||||
int uce_host_path_is_within(const char* path, size_t path_len, const char* root, size_t root_len);
|
||||
size_t uce_host_cwd_get(char* buf, size_t cap);
|
||||
@@ -103,30 +132,6 @@ bool file_exists(String path)
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_exists(path.data(), path.size(), current.data(), current.size()) != 0);
|
||||
}
|
||||
int file_open_locked(String file_name, int open_flags, int lock_type, int create_mode, f64 wait_timeout_seconds, String purpose)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_open_locked(
|
||||
file_name.data(), file_name.size(), open_flags, lock_type, create_mode, wait_timeout_seconds,
|
||||
purpose.data(), purpose.size(), current.data(), current.size()
|
||||
));
|
||||
}
|
||||
void file_close_locked(int fd) { uce_host_file_close_locked(fd); }
|
||||
void file_release_process_locks(String reason) { uce_host_file_release_process_locks(reason.data(), reason.size()); }
|
||||
String file_get_contents_locked_fd(int fd)
|
||||
{
|
||||
size_t required = uce_host_file_read_locked_fd(fd, 0, 0);
|
||||
if(required == 0)
|
||||
return("");
|
||||
String content(required, 0);
|
||||
size_t got = uce_host_file_read_locked_fd(fd, &content[0], required);
|
||||
content.resize(got <= required ? got : 0);
|
||||
return(content);
|
||||
}
|
||||
bool file_put_contents_locked_fd(int fd, String content)
|
||||
{
|
||||
return(uce_host_file_write_locked_fd(fd, content.data(), content.size()) != 0);
|
||||
}
|
||||
String file_get_contents(String file_name)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
@@ -143,11 +148,200 @@ bool file_put_contents(String file_name, String content)
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_write(file_name.data(), file_name.size(), current.data(), current.size(), content.data(), content.size(), 0) != 0);
|
||||
}
|
||||
bool file_append_contents(String file_name, String content)
|
||||
bool file_append(String file_name, String content)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_write(file_name.data(), file_name.size(), current.data(), current.size(), content.data(), content.size(), 1) != 0);
|
||||
}
|
||||
u64 file_open(String path, String mode)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return((u64)uce_host_file_open(path.data(), path.size(), current.data(), current.size(), mode.data(), mode.size()));
|
||||
}
|
||||
String file_read(u64 h, u64 len)
|
||||
{
|
||||
size_t required = uce_host_file_handle_read(h, len, 0, 0);
|
||||
if(required == 0)
|
||||
return("");
|
||||
String content(required, 0);
|
||||
size_t got = uce_host_file_handle_read(h, len, &content[0], required);
|
||||
content.resize(got <= required ? got : 0);
|
||||
return(content);
|
||||
}
|
||||
String file_pread(u64 h, u64 offset, u64 len)
|
||||
{
|
||||
size_t required = uce_host_file_handle_pread(h, offset, len, 0, 0);
|
||||
if(required == 0)
|
||||
return("");
|
||||
String content(required, 0);
|
||||
size_t got = uce_host_file_handle_pread(h, offset, len, &content[0], required);
|
||||
content.resize(got <= required ? got : 0);
|
||||
return(content);
|
||||
}
|
||||
u64 file_write(u64 h, String data) { return(uce_host_file_handle_write(h, data.data(), data.size())); }
|
||||
u64 file_pwrite(u64 h, u64 offset, String data) { return(uce_host_file_handle_pwrite(h, offset, data.data(), data.size())); }
|
||||
s64 file_seek(u64 h, s64 offset, int whence) { return((s64)uce_host_file_handle_seek(h, offset, whence)); }
|
||||
s64 file_tell(u64 h) { return((s64)uce_host_file_handle_tell(h)); }
|
||||
void file_close(u64 h) { uce_host_file_handle_close(h); }
|
||||
static DValue wasm_decode_dvalue_result(String encoded)
|
||||
{
|
||||
DValue out;
|
||||
String error;
|
||||
ucb_decode(encoded, out, &error);
|
||||
return(out);
|
||||
}
|
||||
DValue file_stat(String path)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
size_t required = uce_host_file_stat(path.data(), path.size(), current.data(), current.size(), 0, 0);
|
||||
String encoded(required, 0);
|
||||
size_t got = required ? uce_host_file_stat(path.data(), path.size(), current.data(), current.size(), &encoded[0], required) : 0;
|
||||
encoded.resize(got <= required ? got : 0);
|
||||
return(wasm_decode_dvalue_result(encoded));
|
||||
}
|
||||
DValue dir_list(String path)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
size_t required = uce_host_dir_list(path.data(), path.size(), current.data(), current.size(), 0, 0);
|
||||
String encoded(required, 0);
|
||||
size_t got = required ? uce_host_dir_list(path.data(), path.size(), current.data(), current.size(), &encoded[0], required) : 0;
|
||||
encoded.resize(got <= required ? got : 0);
|
||||
return(wasm_decode_dvalue_result(encoded));
|
||||
}
|
||||
bool file_rename(String from, String to)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_rename(from.data(), from.size(), to.data(), to.size(), current.data(), current.size()) != 0);
|
||||
}
|
||||
bool file_copy(String from, String to)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_copy(from.data(), from.size(), to.data(), to.size(), current.data(), current.size()) != 0);
|
||||
}
|
||||
bool file_truncate(String path, u64 size)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_truncate(path.data(), path.size(), current.data(), current.size(), size) != 0);
|
||||
}
|
||||
bool dir_remove(String path, bool recursive)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_dir_remove(path.data(), path.size(), current.data(), current.size(), recursive ? 1 : 0) != 0);
|
||||
}
|
||||
String file_temp(String prefix)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
size_t required = uce_host_file_temp(prefix.data(), prefix.size(), current.data(), current.size(), 0, 0);
|
||||
if(required == 0) return("");
|
||||
String out(required, 0);
|
||||
size_t got = uce_host_file_temp(prefix.data(), prefix.size(), current.data(), current.size(), &out[0], required);
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(out);
|
||||
}
|
||||
bool file_chmod(String path, u32 mode)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_chmod(path.data(), path.size(), current.data(), current.size(), mode) != 0);
|
||||
}
|
||||
bool file_symlink(String target, String linkpath)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
return(uce_host_file_symlink(target.data(), target.size(), linkpath.data(), linkpath.size(), current.data(), current.size()) != 0);
|
||||
}
|
||||
String file_readlink(String path)
|
||||
{
|
||||
String current = wasm_current_unit_file();
|
||||
size_t required = uce_host_file_readlink(path.data(), path.size(), current.data(), current.size(), 0, 0);
|
||||
if(required == 0) return("");
|
||||
String out(required, 0);
|
||||
size_t got = uce_host_file_readlink(path.data(), path.size(), current.data(), current.size(), &out[0], required);
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(out);
|
||||
}
|
||||
bool file_fsync(u64 h) { return(uce_host_file_fsync(h) != 0); }
|
||||
|
||||
|
||||
static String wasm_string_hostcall_1(size_t (*fn)(const char*, size_t, char*, size_t), String data)
|
||||
{
|
||||
size_t required = fn(data.data(), data.size(), 0, 0);
|
||||
String out(required, 0);
|
||||
size_t got = required ? fn(data.data(), data.size(), &out[0], required) : 0;
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(out);
|
||||
}
|
||||
String sha256(String data) { return(wasm_string_hostcall_1(uce_host_sha256, data)); }
|
||||
String sha256_hex(String data) { return(wasm_string_hostcall_1(uce_host_sha256_hex, data)); }
|
||||
String hmac_sha256(String key, String data)
|
||||
{
|
||||
size_t required = uce_host_hmac_sha256(key.data(), key.size(), data.data(), data.size(), 0, 0);
|
||||
String out(required, 0); size_t got = required ? uce_host_hmac_sha256(key.data(), key.size(), data.data(), data.size(), &out[0], required) : 0; out.resize(got <= required ? got : 0); return(out);
|
||||
}
|
||||
String hmac_sha256_hex(String key, String data)
|
||||
{
|
||||
size_t required = uce_host_hmac_sha256_hex(key.data(), key.size(), data.data(), data.size(), 0, 0);
|
||||
String out(required, 0); size_t got = required ? uce_host_hmac_sha256_hex(key.data(), key.size(), data.data(), data.size(), &out[0], required) : 0; out.resize(got <= required ? got : 0); return(out);
|
||||
}
|
||||
String base64_decode(String raw) { return(wasm_string_hostcall_1(uce_host_base64_decode, raw)); }
|
||||
String random_bytes(u64 n)
|
||||
{
|
||||
if(n > 1024 * 1024) n = 1024 * 1024;
|
||||
String out(n, 0); size_t got = n ? uce_host_random(&out[0], n) : 0; out.resize(got <= n ? got : 0); return(out);
|
||||
}
|
||||
bool crypto_equal(String a, String b) { return(uce_host_crypto_equal(a.data(), a.size(), b.data(), b.size()) != 0); }
|
||||
|
||||
|
||||
DValue http_request(DValue req)
|
||||
{
|
||||
String encoded = ucb_encode(req);
|
||||
size_t required = uce_host_http_request(encoded.data(), encoded.size(), 0, 0);
|
||||
String out(required, 0); size_t got = required ? uce_host_http_request(encoded.data(), encoded.size(), &out[0], required) : 0; out.resize(got <= required ? got : 0); return(wasm_decode_dvalue_result(out));
|
||||
}
|
||||
u64 http_request_async(DValue req)
|
||||
{
|
||||
String encoded = ucb_encode(req);
|
||||
return((u64)uce_host_http_request_async(encoded.data(), encoded.size()));
|
||||
}
|
||||
|
||||
DValue shell_exec(DValue spec)
|
||||
{
|
||||
String encoded = ucb_encode(spec);
|
||||
size_t required = uce_host_shell_exec_dv(encoded.data(), encoded.size(), 0, 0);
|
||||
String out(required, 0);
|
||||
size_t got = required ? uce_host_shell_exec_dv(encoded.data(), encoded.size(), &out[0], required) : 0;
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(wasm_decode_dvalue_result(out));
|
||||
}
|
||||
u64 shell_spawn(DValue spec)
|
||||
{
|
||||
String encoded = ucb_encode(spec);
|
||||
return((u64)uce_host_shell_spawn(encoded.data(), encoded.size()));
|
||||
}
|
||||
DValue job_status(u64 job_id)
|
||||
{
|
||||
size_t required = uce_host_job_status(job_id, 0, 0);
|
||||
String out(required, 0);
|
||||
size_t got = required ? uce_host_job_status(job_id, &out[0], required) : 0;
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(wasm_decode_dvalue_result(out));
|
||||
}
|
||||
DValue job_result(u64 job_id)
|
||||
{
|
||||
size_t required = uce_host_job_result(job_id, 0, 0);
|
||||
String out(required, 0);
|
||||
size_t got = required ? uce_host_job_result(job_id, &out[0], required) : 0;
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(wasm_decode_dvalue_result(out));
|
||||
}
|
||||
DValue job_await(u64 job_id, u64 timeout_ms)
|
||||
{
|
||||
size_t required = uce_host_job_await(job_id, timeout_ms, 0, 0);
|
||||
String out(required, 0);
|
||||
size_t got = required ? uce_host_job_await(job_id, timeout_ms, &out[0], required) : 0;
|
||||
out.resize(got <= required ? got : 0);
|
||||
return(wasm_decode_dvalue_result(out));
|
||||
}
|
||||
bool job_cancel(u64 job_id) { return(uce_host_job_cancel(job_id) != 0); }
|
||||
|
||||
String cwd_get()
|
||||
{
|
||||
size_t required = uce_host_cwd_get(0, 0);
|
||||
@@ -522,6 +716,15 @@ StringMap default_config()
|
||||
#include <errno.h>
|
||||
#include "sys.h"
|
||||
#include "hash.h"
|
||||
#include "uri.h"
|
||||
|
||||
String sha256(String data) { return(sha256_native(data)); }
|
||||
String sha256_hex(String data) { return(sha256_hex_native(data)); }
|
||||
String hmac_sha256(String key, String data) { return(hmac_sha256_native(key, data)); }
|
||||
String hmac_sha256_hex(String key, String data) { return(hmac_sha256_hex_native(key, data)); }
|
||||
String base64_decode(String raw) { bool ok=false; return(::base64_decode(raw, ok)); }
|
||||
String random_bytes(u64 n) { if(n > 1024*1024) n = 1024*1024; String out(n, 0); int fd=open("/dev/urandom", O_RDONLY); if(fd<0) return(""); size_t off=0; while(off<n) { ssize_t got=read(fd, &out[off], n-off); if(got<0 && errno==EINTR) continue; if(got<=0) break; off += (size_t)got; } close(fd); out.resize(off); return(out); }
|
||||
bool crypto_equal(String a, String b) { return(crypto_equal_native(a, b)); }
|
||||
|
||||
// Single definitions for the native split build (declared extern in sys.h).
|
||||
pid_t parent_pid = 0;
|
||||
@@ -529,7 +732,59 @@ pid_t my_pid = 0;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr f64 FILE_LOCK_WAIT_TIMEOUT_SECONDS = 3.0;
|
||||
u64 file_lock_timeout_ms()
|
||||
{
|
||||
const char* raw = getenv("UCE_FILE_LOCK_TIMEOUT_MS");
|
||||
if(!raw || !*raw)
|
||||
return(2000);
|
||||
char* end = 0;
|
||||
unsigned long long parsed = strtoull(raw, &end, 10);
|
||||
if(end == raw)
|
||||
return(2000);
|
||||
return((u64)parsed);
|
||||
}
|
||||
|
||||
u64 monotonic_ms()
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return((u64)ts.tv_sec * 1000ull + (u64)ts.tv_nsec / 1000000ull);
|
||||
}
|
||||
|
||||
int open_locked_file(String file_name, int open_flags, int lock_type, int create_mode = 0644)
|
||||
{
|
||||
int fd = open(file_name.c_str(), open_flags, create_mode);
|
||||
if(fd == -1)
|
||||
return(-1);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
u64 timeout = file_lock_timeout_ms();
|
||||
u64 deadline = monotonic_ms() + timeout;
|
||||
while(true)
|
||||
{
|
||||
if(flock(fd, lock_type | LOCK_NB) == 0)
|
||||
return(fd);
|
||||
if(errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR)
|
||||
{
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
if(timeout == 0 || monotonic_ms() >= deadline)
|
||||
{
|
||||
fprintf(stderr, "(!) file lock timeout after %llums: %s\n", (unsigned long long)timeout, file_name.c_str());
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
void close_locked_file(int fd)
|
||||
{
|
||||
if(fd == -1)
|
||||
return;
|
||||
flock(fd, LOCK_UN);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -737,36 +992,9 @@ bool file_exists(String path)
|
||||
return(std::filesystem::exists(fp));
|
||||
}
|
||||
|
||||
int file_open_locked(String file_name, int open_flags, int lock_type, int create_mode, f64 wait_timeout_seconds, String purpose)
|
||||
{
|
||||
(void)wait_timeout_seconds;
|
||||
(void)purpose;
|
||||
int fd = open(file_name.c_str(), open_flags, create_mode);
|
||||
if(fd == -1)
|
||||
return(-1);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
if(flock(fd, lock_type) != 0)
|
||||
{
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
return(fd);
|
||||
}
|
||||
namespace {
|
||||
|
||||
void file_close_locked(int fd)
|
||||
{
|
||||
if(fd == -1)
|
||||
return;
|
||||
flock(fd, LOCK_UN);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void file_release_process_locks(String reason)
|
||||
{
|
||||
(void)reason;
|
||||
}
|
||||
|
||||
String file_get_contents_locked_fd(int fd)
|
||||
String file_read_all(int fd)
|
||||
{
|
||||
if(fd == -1)
|
||||
return("");
|
||||
@@ -780,7 +1008,6 @@ String file_get_contents_locked_fd(int fd)
|
||||
return(content);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool file_write_all(int fd, const char* data, size_t remaining)
|
||||
{
|
||||
@@ -803,41 +1030,30 @@ bool file_write_all(int fd, const char* data, size_t remaining)
|
||||
|
||||
}
|
||||
|
||||
bool file_put_contents_locked_fd(int fd, String content)
|
||||
{
|
||||
if(fd == -1)
|
||||
return(false);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
if(ftruncate(fd, 0) != 0)
|
||||
return(false);
|
||||
if(!file_write_all(fd, content.data(), content.length()))
|
||||
return(false);
|
||||
return(true);
|
||||
}
|
||||
|
||||
String file_get_contents(String file_name)
|
||||
{
|
||||
s32 fd = file_open_locked(file_name, O_RDONLY, LOCK_SH, 0644, FILE_LOCK_WAIT_TIMEOUT_SECONDS, "file_get_contents:" + file_name);
|
||||
s32 fd = open_locked_file(file_name, O_RDONLY, LOCK_SH);
|
||||
if(fd == -1)
|
||||
{
|
||||
printf("(!) Could not read %s\n", file_name.c_str());
|
||||
return("");
|
||||
}
|
||||
String content = file_get_contents_locked_fd(fd);
|
||||
file_close_locked(fd);
|
||||
String content = file_read_all(fd);
|
||||
close_locked_file(fd);
|
||||
return(content);
|
||||
}
|
||||
|
||||
bool file_put_contents(String file_name, String content)
|
||||
{
|
||||
s32 fd = file_open_locked(file_name, O_RDWR | O_CREAT, LOCK_EX, 0644, FILE_LOCK_WAIT_TIMEOUT_SECONDS, "file_put_contents:" + file_name);
|
||||
s32 fd = open_locked_file(file_name, O_RDWR | O_CREAT, LOCK_EX, 0644);
|
||||
if(fd == -1)
|
||||
{
|
||||
printf("(!) Could not write %s\n", file_name.c_str());
|
||||
return(false);
|
||||
}
|
||||
bool ok = file_put_contents_locked_fd(fd, content);
|
||||
file_close_locked(fd);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
bool ok = ftruncate(fd, 0) == 0 && file_write_all(fd, content.data(), content.length());
|
||||
close_locked_file(fd);
|
||||
if(!ok)
|
||||
{
|
||||
printf("(!) Could not fully write %s\n", file_name.c_str());
|
||||
@@ -846,9 +1062,9 @@ bool file_put_contents(String file_name, String content)
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool file_append_contents(String file_name, String content)
|
||||
bool file_append(String file_name, String content)
|
||||
{
|
||||
s32 fd = file_open_locked(file_name, O_RDWR | O_CREAT, LOCK_EX, 0644, FILE_LOCK_WAIT_TIMEOUT_SECONDS, "file_append:" + file_name);
|
||||
s32 fd = open_locked_file(file_name, O_RDWR | O_CREAT, LOCK_EX, 0644);
|
||||
if(fd == -1)
|
||||
{
|
||||
printf("(!) Could not append %s\n", file_name.c_str());
|
||||
@@ -856,7 +1072,7 @@ bool file_append_contents(String file_name, String content)
|
||||
}
|
||||
lseek(fd, 0, SEEK_END);
|
||||
bool ok = file_write_all(fd, content.data(), content.length());
|
||||
file_close_locked(fd);
|
||||
close_locked_file(fd);
|
||||
if(!ok)
|
||||
{
|
||||
printf("(!) Could not fully append %s\n", file_name.c_str());
|
||||
@@ -1154,7 +1370,6 @@ pid_t spawn_subprocess(std::function<void()> exec_after_spawn)
|
||||
p = fork();
|
||||
if(p == 0)
|
||||
{
|
||||
file_release_process_locks("fork child startup");
|
||||
my_pid = getpid();
|
||||
//printf("(C) child procress started, PID:%i\n", my_pid);
|
||||
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
||||
@@ -1264,7 +1479,7 @@ pid_t task_pid(String key)
|
||||
{
|
||||
String status_file_name = task_file_prefix(key);
|
||||
String lock_file_name = status_file_name + ".lock";
|
||||
int lock_fd = file_open_locked(lock_file_name, O_RDWR | O_CREAT, LOCK_EX, 0644, FILE_LOCK_WAIT_TIMEOUT_SECONDS, "task-pid:" + key);
|
||||
int lock_fd = open_locked_file(lock_file_name, O_RDWR | O_CREAT, LOCK_EX, 0644);
|
||||
if(lock_fd == -1)
|
||||
{
|
||||
fprintf(stderr, "task_pid(): could not lock task key '%s'\n", key.c_str());
|
||||
@@ -1276,12 +1491,12 @@ pid_t task_pid(String key)
|
||||
TaskStatus status = task_status_parse(status_file);
|
||||
if(task_status_is_alive(status))
|
||||
{
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
return(status.pid);
|
||||
}
|
||||
file_unlink(status_file_name);
|
||||
}
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1289,7 +1504,7 @@ pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
{
|
||||
String status_file_name = task_file_prefix(key);
|
||||
String lock_file_name = status_file_name + ".lock";
|
||||
int lock_fd = file_open_locked(lock_file_name, O_RDWR | O_CREAT, LOCK_EX, 0644, FILE_LOCK_WAIT_TIMEOUT_SECONDS, "task:" + key);
|
||||
int lock_fd = open_locked_file(lock_file_name, O_RDWR | O_CREAT, LOCK_EX, 0644);
|
||||
if(lock_fd == -1)
|
||||
{
|
||||
fprintf(stderr, "task(): could not lock task key '%s'\n", key.c_str());
|
||||
@@ -1303,7 +1518,7 @@ pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
if(task_status_is_alive(status))
|
||||
{
|
||||
printf("(P) worker process '%s' already running: PID %i\n", key.c_str(), status.pid);
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
return(status.pid);
|
||||
}
|
||||
file_unlink(status_file_name);
|
||||
@@ -1312,13 +1527,12 @@ pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
if(p < 0)
|
||||
{
|
||||
fprintf(stderr, "task(): fork failed for key '%s': %s\n", key.c_str(), strerror(errno));
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
return(0);
|
||||
}
|
||||
if(p == 0)
|
||||
{
|
||||
file_release_process_locks("task child startup");
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
my_pid = getpid();
|
||||
signal(SIGALRM, SIG_DFL);
|
||||
if(timeout > 0)
|
||||
@@ -1331,11 +1545,11 @@ pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
}
|
||||
task_close_inherited_fds();
|
||||
exec_after_spawn();
|
||||
int exit_lock_fd = file_open_locked(lock_file_name, O_RDWR | O_CREAT, LOCK_EX, 0644, FILE_LOCK_WAIT_TIMEOUT_SECONDS, "task-exit:" + key);
|
||||
int exit_lock_fd = open_locked_file(lock_file_name, O_RDWR | O_CREAT, LOCK_EX, 0644);
|
||||
if(exit_lock_fd != -1)
|
||||
{
|
||||
file_unlink(status_file_name);
|
||||
file_close_locked(exit_lock_fd);
|
||||
close_locked_file(exit_lock_fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1349,10 +1563,10 @@ pid_t task(String key, std::function<void()> exec_after_spawn, u64 timeout)
|
||||
{
|
||||
fprintf(stderr, "task(): could not write status file for key '%s'; terminating child PID %i\n", key.c_str(), p);
|
||||
kill(p, SIGTERM);
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
return(0);
|
||||
}
|
||||
file_close_locked(lock_fd);
|
||||
close_locked_file(lock_fd);
|
||||
printf("(P) worker process '%s' spawned: PID %i\n", key.c_str(), p);
|
||||
return(p);
|
||||
}
|
||||
@@ -1425,6 +1639,8 @@ StringMap make_server_settings()
|
||||
// command batches here at workspace teardown.
|
||||
cfg["WS_BROKER_SOCKET_PATH"] = "/run/uce/ws-broker.sock";
|
||||
cfg["WS_BROKER_OUTBOUND_TIMEOUT_SECONDS"] = "30";
|
||||
// Comma-separated uce_host_* names a sysadmin disables; empty = nothing blocked.
|
||||
cfg["UCE_HOSTCALL_BLOCKLIST"] = "";
|
||||
cfg["TMP_UPLOAD_PATH"] = "/tmp/uce/uploads";
|
||||
cfg["SESSION_PATH"] = "/tmp/uce/sessions";
|
||||
cfg["COMPILER_SYS_PATH"] = ".";
|
||||
|
||||
Reference in New Issue
Block a user