Added namespace support to Horizon bootstrap msg parsing
This commit is contained in:
@@ -10,11 +10,18 @@
|
|||||||
#include <mio/fd.h>
|
#include <mio/fd.h>
|
||||||
#include <mio/fs.h>
|
#include <mio/fs.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "__init.h"
|
#include "__init.h"
|
||||||
#include "__heap.h"
|
#include "__heap.h"
|
||||||
#include "__fio.h"
|
#include "__fio.h"
|
||||||
|
|
||||||
|
/* maximum of 32 handles can be received sent as arguments */
|
||||||
|
#define MAX_HANDLE_ARGS 32
|
||||||
|
|
||||||
|
/* maximum size of bootstrap message that can be received */
|
||||||
|
#define MAX_MSG_SIZE 0x2000
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#define dbg_log(...)
|
#define dbg_log(...)
|
||||||
#else
|
#else
|
||||||
@@ -33,6 +40,7 @@ static void dbg_log(const char *format, ...)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char **environ = NULL;
|
static const char **environ = NULL;
|
||||||
|
static char arg_msg_buf[MAX_MSG_SIZE];
|
||||||
|
|
||||||
const char **__crt_environ()
|
const char **__crt_environ()
|
||||||
{
|
{
|
||||||
@@ -42,9 +50,19 @@ const char **__crt_environ()
|
|||||||
extern int main(int, const char **);
|
extern int main(int, const char **);
|
||||||
extern void __crt_run_atexit();
|
extern void __crt_run_atexit();
|
||||||
|
|
||||||
static void parse_args(
|
static void extract_arg_handles(mx_bootstrap_msg_t *args,
|
||||||
mx_bootstrap_msg_t *args, mx_handle_t *handles,
|
mx_handle_t *handles, int hndc, mx_bootstrap_handle_t *out)
|
||||||
const char **argv, const char **envp, int hndc, mx_bootstrap_handle_t *handles_out)
|
{
|
||||||
|
uint32_t *hent = (uint32_t *)((char *)args + args->handle_info_off);
|
||||||
|
|
||||||
|
for (int i = 0; i < hndc; i++) {
|
||||||
|
out[i].info = hent[i];
|
||||||
|
out[i].handle = handles[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_args(mx_bootstrap_msg_t *args,
|
||||||
|
const char **argv, const char **envp, const char **namep)
|
||||||
{
|
{
|
||||||
if (args->args_num > 0) {
|
if (args->args_num > 0) {
|
||||||
char *arg_buf = (char *)args + args->args_off;
|
char *arg_buf = (char *)args + args->args_off;
|
||||||
@@ -63,7 +81,6 @@ static void parse_args(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (args->environ_num > 0) {
|
if (args->environ_num > 0) {
|
||||||
char *env_buf = (char *)args + args->environ_off;
|
char *env_buf = (char *)args + args->environ_off;
|
||||||
int env_i = 0;
|
int env_i = 0;
|
||||||
@@ -80,13 +97,22 @@ static void parse_args(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
uint32_t *hent = (uint32_t *)((char *)args + args->handle_info_off);
|
if (args->names_num) {
|
||||||
|
char *name_buf = (char *)args + args->names_off;
|
||||||
|
int name_i = 0;
|
||||||
|
int name_off = 0;
|
||||||
|
|
||||||
for (int i = 0; i < hndc; i++) {
|
for (int i = 0; ; i++) {
|
||||||
handles_out[i].info = hent[i];
|
if (name_buf[i] == '\0') {
|
||||||
handles_out[i].handle = handles[i];
|
namep[name_i++] = name_buf + name_off;
|
||||||
|
name_off = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name_i == (int)args->names_num) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,49 +219,51 @@ int __crt_init(mx_handle_t bootstrap)
|
|||||||
mx_object_wait(bootstrap, MX_TUNNEL_READABLE, 0, &sig);
|
mx_object_wait(bootstrap, MX_TUNNEL_READABLE, 0, &sig);
|
||||||
if (!(sig & MX_TUNNEL_READABLE)) {
|
if (!(sig & MX_TUNNEL_READABLE)) {
|
||||||
dbg_log("no bootstrap message!\n");
|
dbg_log("no bootstrap message!\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t msg_size = 0;
|
size_t msg_size = 0;
|
||||||
size_t nr_handles = 0;
|
size_t nr_handles = 0;
|
||||||
mx_status_t status = mx_tunnel_read(bootstrap, NULL, 0, NULL, 0, &msg_size, &nr_handles);
|
|
||||||
dbg_log("read bootstrap message\n");
|
|
||||||
|
|
||||||
if (status != MX_OK) {
|
mx_handle_t handles[MAX_HANDLE_ARGS + 1];
|
||||||
/* TODO replace with a better error handler */
|
|
||||||
|
mx_bootstrap_handle_t handle_info[MAX_HANDLE_ARGS + 1];
|
||||||
|
|
||||||
|
dbg_log("receiving message from handle %lx\n", bootstrap);
|
||||||
|
mx_status_t err = mx_tunnel_read(bootstrap,
|
||||||
|
arg_msg_buf, MAX_MSG_SIZE,
|
||||||
|
handles, MAX_HANDLE_ARGS,
|
||||||
|
&msg_size, &nr_handles);
|
||||||
|
|
||||||
|
if (err != MX_OK) {
|
||||||
dbg_log("error: cannot read bootstrap message from handle %lx (error %d)\n",
|
dbg_log("error: cannot read bootstrap message from handle %lx (error %d)\n",
|
||||||
bootstrap, status);
|
bootstrap, err);
|
||||||
hang();
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char msg_buf[msg_size];
|
mx_bootstrap_msg_t *msg = (mx_bootstrap_msg_t *)arg_msg_buf;
|
||||||
mx_handle_t handles[nr_handles];
|
|
||||||
mx_tunnel_read(bootstrap, msg_buf, msg_size, handles, nr_handles, &msg_size, &nr_handles);
|
|
||||||
|
|
||||||
mx_bootstrap_msg_t *msg = (mx_bootstrap_msg_t *)msg_buf;
|
dbg_log("extracting handles\n");
|
||||||
|
extract_arg_handles(msg, handles, nr_handles, handle_info);
|
||||||
|
handle_info[nr_handles].handle = bootstrap;
|
||||||
|
handle_info[nr_handles].info = MX_B_HND(MX_B_TUNNEL_BTSTP, 0);
|
||||||
|
nr_handles++;
|
||||||
|
|
||||||
const char *argv[msg->args_num + 1];
|
mx_bootstrap_handle_init(handle_info, nr_handles);
|
||||||
const char *envp[msg->environ_num + 1];
|
|
||||||
#ifdef LIBSYSTEM_STATIC
|
const char **argv = NULL, **envp = NULL, **namep = NULL;
|
||||||
mx_bootstrap_handle_t start_handles[nr_handles + 1];
|
|
||||||
start_handles[nr_handles].handle = bootstrap;
|
dbg_log("allocating buffers (%u, %u, %u)\n", msg->args_num, msg->environ_num, msg->names_num);
|
||||||
start_handles[nr_handles].info = MX_B_HND(MX_B_TUNNEL_BTSTP, 0);
|
|
||||||
#else
|
argv = calloc(sizeof *argv, msg->args_num + 1);
|
||||||
mx_bootstrap_handle_t start_handles[nr_handles];
|
envp = calloc(sizeof *envp, msg->environ_num + 1);
|
||||||
mx_handle_close(bootstrap);
|
namep = calloc(sizeof *namep, msg->names_num + 1);
|
||||||
#endif
|
|
||||||
|
|
||||||
argv[msg->args_num] = NULL;
|
|
||||||
envp[msg->environ_num] = NULL;
|
|
||||||
environ = envp;
|
environ = envp;
|
||||||
|
|
||||||
parse_args(msg, handles, argv, envp, nr_handles, start_handles);
|
parse_args(msg, argv, envp, namep);
|
||||||
#ifdef LIBSYSTEM_STATIC
|
|
||||||
mx_bootstrap_handle_init(start_handles, nr_handles + 1);
|
|
||||||
#else
|
|
||||||
mx_bootstrap_handle_init(start_handles, nr_handles);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
init_stdio(start_handles, nr_handles);
|
init_stdio(handle_info, nr_handles);
|
||||||
|
|
||||||
dbg_log("calling main\n");
|
dbg_log("calling main\n");
|
||||||
int ret = main(msg->args_num, argv);
|
int ret = main(msg->args_num, argv);
|
||||||
|
|||||||
Reference in New Issue
Block a user