diff --git a/photon/libc/sys/horizon/init.c b/photon/libc/sys/horizon/init.c index 3831f4a..515ccd7 100644 --- a/photon/libc/sys/horizon/init.c +++ b/photon/libc/sys/horizon/init.c @@ -10,11 +10,18 @@ #include #include #include +#include #include #include "__init.h" #include "__heap.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 #define dbg_log(...) #else @@ -33,6 +40,7 @@ static void dbg_log(const char *format, ...) #endif static const char **environ = NULL; +static char arg_msg_buf[MAX_MSG_SIZE]; const char **__crt_environ() { @@ -42,9 +50,19 @@ const char **__crt_environ() extern int main(int, const char **); extern void __crt_run_atexit(); -static void parse_args( - mx_bootstrap_msg_t *args, mx_handle_t *handles, - const char **argv, const char **envp, int hndc, mx_bootstrap_handle_t *handles_out) +static void extract_arg_handles(mx_bootstrap_msg_t *args, + mx_handle_t *handles, int hndc, mx_bootstrap_handle_t *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) { char *arg_buf = (char *)args + args->args_off; @@ -63,7 +81,6 @@ static void parse_args( } } -#if 0 if (args->environ_num > 0) { char *env_buf = (char *)args + args->environ_off; 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++) { - handles_out[i].info = hent[i]; - handles_out[i].handle = handles[i]; + for (int i = 0; ; i++) { + if (name_buf[i] == '\0') { + 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); if (!(sig & MX_TUNNEL_READABLE)) { dbg_log("no bootstrap message!\n"); + return -1; } size_t msg_size = 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) { - /* TODO replace with a better error handler */ + mx_handle_t handles[MAX_HANDLE_ARGS + 1]; + + 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", - bootstrap, status); - hang(); + bootstrap, err); + return -1; } - unsigned char msg_buf[msg_size]; - 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 *)arg_msg_buf; - 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]; - const char *envp[msg->environ_num + 1]; -#ifdef LIBSYSTEM_STATIC - mx_bootstrap_handle_t start_handles[nr_handles + 1]; - start_handles[nr_handles].handle = bootstrap; - start_handles[nr_handles].info = MX_B_HND(MX_B_TUNNEL_BTSTP, 0); -#else - mx_bootstrap_handle_t start_handles[nr_handles]; - mx_handle_close(bootstrap); -#endif + mx_bootstrap_handle_init(handle_info, nr_handles); + + const char **argv = NULL, **envp = NULL, **namep = NULL; + + dbg_log("allocating buffers (%u, %u, %u)\n", msg->args_num, msg->environ_num, msg->names_num); + + argv = calloc(sizeof *argv, msg->args_num + 1); + envp = calloc(sizeof *envp, msg->environ_num + 1); + namep = calloc(sizeof *namep, msg->names_num + 1); - argv[msg->args_num] = NULL; - envp[msg->environ_num] = NULL; environ = envp; - parse_args(msg, handles, argv, envp, nr_handles, start_handles); -#ifdef LIBSYSTEM_STATIC - mx_bootstrap_handle_init(start_handles, nr_handles + 1); -#else - mx_bootstrap_handle_init(start_handles, nr_handles); -#endif + parse_args(msg, argv, envp, namep); - init_stdio(start_handles, nr_handles); + init_stdio(handle_info, nr_handles); dbg_log("calling main\n"); int ret = main(msg->args_num, argv);