Added some questionable support for running everything in one process, because iOS.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4520 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
8bd0027e71
commit
a69e551968
@ -320,6 +320,7 @@ typedef struct tf_run_args_t {
|
|||||||
int count;
|
int count;
|
||||||
const char* args;
|
const char* args;
|
||||||
const char* zip;
|
const char* zip;
|
||||||
|
bool one_proc;
|
||||||
bool help;
|
bool help;
|
||||||
} tf_run_args_t;
|
} tf_run_args_t;
|
||||||
|
|
||||||
@ -341,6 +342,7 @@ static int _tf_run_task(const tf_run_args_t* args, int index)
|
|||||||
tf_task_set_http_port(task, args->http_port ? args->http_port + index : 0);
|
tf_task_set_http_port(task, args->http_port ? args->http_port + index : 0);
|
||||||
tf_task_set_https_port(task, args->https_port ? args->https_port + index : 0);
|
tf_task_set_https_port(task, args->https_port ? args->https_port + index : 0);
|
||||||
tf_task_set_args(task, args->args);
|
tf_task_set_args(task, args->args);
|
||||||
|
tf_task_set_one_proc(task, args->one_proc);
|
||||||
const char* db_path = args->db_path;
|
const char* db_path = args->db_path;
|
||||||
char db_path_buffer[256];
|
char db_path_buffer[256];
|
||||||
if (index)
|
if (index)
|
||||||
@ -385,6 +387,7 @@ static int _tf_command_run(const char* file, int argc, char* argv[])
|
|||||||
{ "db-path", 'd', offsetof(tf_run_args_t, db_path), NULL, XOPT_TYPE_STRING, NULL, "Sqlite database path (default: db.sqlite)." },
|
{ "db-path", 'd', offsetof(tf_run_args_t, db_path), NULL, XOPT_TYPE_STRING, NULL, "Sqlite database path (default: db.sqlite)." },
|
||||||
{ "count", 'n', offsetof(tf_run_args_t, count), NULL, XOPT_TYPE_INT, NULL, "Number of instances to run." },
|
{ "count", 'n', offsetof(tf_run_args_t, count), NULL, XOPT_TYPE_INT, NULL, "Number of instances to run." },
|
||||||
{ "args", 'a', offsetof(tf_run_args_t, args), NULL, XOPT_TYPE_STRING, NULL, "Arguments of the form key=value,foo=bar,verbose=true." },
|
{ "args", 'a', offsetof(tf_run_args_t, args), NULL, XOPT_TYPE_STRING, NULL, "Arguments of the form key=value,foo=bar,verbose=true." },
|
||||||
|
{ "one-proc", 'o', offsetof(tf_run_args_t, one_proc), NULL, XOPT_TYPE_BOOL, NULL, "Run everything in one process (unsafely!)." },
|
||||||
{ "zip", 'z', offsetof(tf_run_args_t, zip), NULL, XOPT_TYPE_STRING, NULL, "Zip archive from which to load files." },
|
{ "zip", 'z', offsetof(tf_run_args_t, zip), NULL, XOPT_TYPE_STRING, NULL, "Zip archive from which to load files." },
|
||||||
{ "help", 'h', offsetof(tf_run_args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
{ "help", 'h', offsetof(tf_run_args_t, help), NULL, XOPT_TYPE_BOOL, NULL, "Shows this help message." },
|
||||||
XOPT_NULLOPTION,
|
XOPT_NULLOPTION,
|
||||||
@ -485,7 +488,7 @@ static int _tf_command_sandbox(const char* file, int argc, char* argv[])
|
|||||||
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
prctl(PR_SET_PDEATHSIG, SIGHUP);
|
||||||
#endif
|
#endif
|
||||||
tf_task_t* task = tf_task_create();
|
tf_task_t* task = tf_task_create();
|
||||||
tf_task_configure_from_stdin(task);
|
tf_task_configure_from_fd(task, STDIN_FILENO);
|
||||||
shedPrivileges();
|
shedPrivileges();
|
||||||
/* The caller will trigger tf_task_activate with a message. */
|
/* The caller will trigger tf_task_activate with a message. */
|
||||||
tf_task_run(task);
|
tf_task_run(task);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "packetstream.h"
|
#include "packetstream.h"
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
@ -116,7 +117,11 @@ static void _packetstream_on_read(uv_stream_t* handle, ssize_t count, const uv_b
|
|||||||
void tf_packetstream_start(tf_packetstream_t* stream)
|
void tf_packetstream_start(tf_packetstream_t* stream)
|
||||||
{
|
{
|
||||||
stream->stream.data = stream;
|
stream->stream.data = stream;
|
||||||
uv_read_start((uv_stream_t*)&stream->stream, _packetstream_allocate, _packetstream_on_read);
|
int result = uv_read_start((uv_stream_t*)&stream->stream, _packetstream_allocate, _packetstream_on_read);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
tf_printf("uv_read_start: %s\n", uv_strerror(result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _packetstream_on_write(uv_write_t* request, int status)
|
static void _packetstream_on_write(uv_write_t* request, int status)
|
||||||
|
15
src/task.c
15
src/task.c
@ -94,6 +94,7 @@ typedef struct _tf_task_t
|
|||||||
|
|
||||||
bool _activated;
|
bool _activated;
|
||||||
bool _trusted;
|
bool _trusted;
|
||||||
|
bool _one_proc;
|
||||||
bool _killed;
|
bool _killed;
|
||||||
int32_t _exitCode;
|
int32_t _exitCode;
|
||||||
char _scriptName[256];
|
char _scriptName[256];
|
||||||
@ -1620,9 +1621,9 @@ tf_task_t* tf_task_create()
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tf_task_configure_from_stdin(tf_task_t* task)
|
void tf_task_configure_from_fd(tf_task_t* task, int fd)
|
||||||
{
|
{
|
||||||
task->_parent = tf_taskstub_create_parent(task, STDIN_FILENO);
|
task->_parent = tf_taskstub_create_parent(task, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _tf_task_trace_to_parent(tf_trace_t* trace, const char* buffer, size_t size, void* user_data)
|
static void _tf_task_trace_to_parent(tf_trace_t* trace, const char* buffer, size_t size, void* user_data)
|
||||||
@ -1754,6 +1755,16 @@ void tf_task_run(tf_task_t* task)
|
|||||||
} while (_tf_task_run_jobs(task));
|
} while (_tf_task_run_jobs(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tf_task_get_one_proc(tf_task_t* task)
|
||||||
|
{
|
||||||
|
return task->_one_proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tf_task_set_one_proc(tf_task_t* task, bool one_proc)
|
||||||
|
{
|
||||||
|
task->_one_proc = one_proc;
|
||||||
|
}
|
||||||
|
|
||||||
void tf_task_set_trusted(tf_task_t* task, bool trusted)
|
void tf_task_set_trusted(tf_task_t* task, bool trusted)
|
||||||
{
|
{
|
||||||
task->_trusted = trusted;
|
task->_trusted = trusted;
|
||||||
|
@ -35,7 +35,7 @@ typedef enum _tf_task_message_t {
|
|||||||
} tf_task_message_t;
|
} tf_task_message_t;
|
||||||
|
|
||||||
tf_task_t* tf_task_create();
|
tf_task_t* tf_task_create();
|
||||||
void tf_task_configure_from_stdin(tf_task_t* task);
|
void tf_task_configure_from_fd(tf_task_t* task, int fd);
|
||||||
void tf_task_set_ssb_port(tf_task_t* task, int port);
|
void tf_task_set_ssb_port(tf_task_t* task, int port);
|
||||||
void tf_task_set_http_port(tf_task_t* task, int port);
|
void tf_task_set_http_port(tf_task_t* task, int port);
|
||||||
void tf_task_set_https_port(tf_task_t* task, int port);
|
void tf_task_set_https_port(tf_task_t* task, int port);
|
||||||
@ -43,6 +43,8 @@ void tf_task_set_db_path(tf_task_t* task, const char* path);
|
|||||||
void tf_task_set_zip_path(tf_task_t* task, const char* path);
|
void tf_task_set_zip_path(tf_task_t* task, const char* path);
|
||||||
const char* tf_task_get_zip_path(tf_task_t* task);
|
const char* tf_task_get_zip_path(tf_task_t* task);
|
||||||
void tf_task_set_args(tf_task_t* task, const char* args);
|
void tf_task_set_args(tf_task_t* task, const char* args);
|
||||||
|
bool tf_task_get_one_proc(tf_task_t* task);
|
||||||
|
void tf_task_set_one_proc(tf_task_t* task, bool one_proc);
|
||||||
void tf_task_activate(tf_task_t* task);
|
void tf_task_activate(tf_task_t* task);
|
||||||
void tf_task_run(tf_task_t* task);
|
void tf_task_run(tf_task_t* task);
|
||||||
int tf_task_execute(tf_task_t* task, const char* file);
|
int tf_task_execute(tf_task_t* task, const char* file);
|
||||||
|
@ -63,6 +63,16 @@ static JSValue _taskstub_loadFile(JSContext* context, JSValueConst this_val, int
|
|||||||
static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal);
|
static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int terminationSignal);
|
||||||
static void _taskstub_finalizer(JSRuntime *runtime, JSValue value);
|
static void _taskstub_finalizer(JSRuntime *runtime, JSValue value);
|
||||||
|
|
||||||
|
static void _tf_taskstub_run_sandbox_thread(void* data)
|
||||||
|
{
|
||||||
|
uv_file fd = (uv_file)(intptr_t)data;
|
||||||
|
tf_task_t* task = tf_task_create();
|
||||||
|
tf_task_configure_from_fd(task, fd);
|
||||||
|
/* The caller will trigger tf_task_activate with a message. */
|
||||||
|
tf_task_run(task);
|
||||||
|
tf_task_destroy(task);
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
{
|
{
|
||||||
tf_task_t* parent = tf_task_get(context);
|
tf_task_t* parent = tf_task_get(context);
|
||||||
@ -125,6 +135,38 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a
|
|||||||
char arg1[] = "sandbox";
|
char arg1[] = "sandbox";
|
||||||
char* command_argv[] = { _executable, arg1, 0 };
|
char* command_argv[] = { _executable, arg1, 0 };
|
||||||
|
|
||||||
|
JSValue result = JS_NULL;
|
||||||
|
if (tf_task_get_one_proc(parent))
|
||||||
|
{
|
||||||
|
uv_os_sock_t fds[2];
|
||||||
|
int pipe_result = uv_socketpair(SOCK_STREAM, AF_UNIX, fds, 0, 0);
|
||||||
|
if (pipe_result)
|
||||||
|
{
|
||||||
|
tf_printf("uv_socketpair failed: %s\n", uv_strerror(pipe_result));
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream);
|
||||||
|
memset(pipe, 0, sizeof(*pipe));
|
||||||
|
pipe_result = uv_pipe_init(tf_task_get_loop(parent), pipe, 1);
|
||||||
|
if (pipe_result != 0)
|
||||||
|
{
|
||||||
|
tf_printf("uv_pipe_init failed: %s\n", uv_strerror(pipe_result));
|
||||||
|
}
|
||||||
|
pipe_result = uv_pipe_open(pipe, fds[0]);
|
||||||
|
if (pipe_result != 0)
|
||||||
|
{
|
||||||
|
tf_printf("uv_pipe_open failed: %s\n", uv_strerror(pipe_result));
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_thread_t* thread = tf_malloc(sizeof(uv_thread_t));
|
||||||
|
uv_thread_create(thread, _tf_taskstub_run_sandbox_thread, (void*)(intptr_t)fds[1]);
|
||||||
|
|
||||||
|
tf_packetstream_set_on_receive(stub->_stream, tf_task_on_receive_packet, stub);
|
||||||
|
tf_packetstream_start(stub->_stream);
|
||||||
|
result = taskObject;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream);
|
uv_pipe_t* pipe = tf_packetstream_get_pipe(stub->_stream);
|
||||||
memset(pipe, 0, sizeof(*pipe));
|
memset(pipe, 0, sizeof(*pipe));
|
||||||
if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0)
|
if (uv_pipe_init(tf_task_get_loop(parent), pipe, 1) != 0)
|
||||||
@ -147,7 +189,6 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a
|
|||||||
options.stdio_count = sizeof(io) / sizeof(*io);
|
options.stdio_count = sizeof(io) / sizeof(*io);
|
||||||
options.file = command_argv[0];
|
options.file = command_argv[0];
|
||||||
|
|
||||||
JSValue result = JS_NULL;
|
|
||||||
stub->_process.data = stub;
|
stub->_process.data = stub;
|
||||||
int spawn_result = uv_spawn(tf_task_get_loop(parent), &stub->_process, &options);
|
int spawn_result = uv_spawn(tf_task_get_loop(parent), &stub->_process, &options);
|
||||||
if (spawn_result == 0)
|
if (spawn_result == 0)
|
||||||
@ -161,6 +202,7 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a
|
|||||||
tf_printf("uv_spawn failed: %s\n", uv_strerror(spawn_result));
|
tf_printf("uv_spawn failed: %s\n", uv_strerror(spawn_result));
|
||||||
JS_FreeValue(context, taskObject);
|
JS_FreeValue(context, taskObject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,9 +272,10 @@ tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file)
|
|||||||
tf_printf("uv_pipe_init failed\n");
|
tf_printf("uv_pipe_init failed\n");
|
||||||
}
|
}
|
||||||
tf_packetstream_set_on_receive(parentStub->_stream, tf_task_on_receive_packet, parentStub);
|
tf_packetstream_set_on_receive(parentStub->_stream, tf_task_on_receive_packet, parentStub);
|
||||||
if (uv_pipe_open(tf_packetstream_get_pipe(parentStub->_stream), file) != 0)
|
int result = uv_pipe_open(tf_packetstream_get_pipe(parentStub->_stream), file);
|
||||||
|
if (result != 0)
|
||||||
{
|
{
|
||||||
tf_printf("uv_pipe_open failed\n");
|
tf_printf("uv_pipe_open failed: %s\n", uv_strerror(result));
|
||||||
}
|
}
|
||||||
tf_packetstream_start(parentStub->_stream);
|
tf_packetstream_start(parentStub->_stream);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user