Horizon init now initialises MIO using bootstrap handles
This commit is contained in:
@@ -2,12 +2,19 @@
|
||||
#include <magenta/tunnel.h>
|
||||
#include <magenta/bootstrap.h>
|
||||
#include <magenta/errors.h>
|
||||
#include <magenta/handle.h>
|
||||
#include <magenta/misc.h>
|
||||
#include <magenta/object.h>
|
||||
#include <mio/object.h>
|
||||
#include <mio/fd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "__init.h"
|
||||
#include "__heap.h"
|
||||
#include "__fio.h"
|
||||
|
||||
#define dbg_log(...)
|
||||
|
||||
static const char **environ = NULL;
|
||||
|
||||
const char **__crt_environ()
|
||||
@@ -73,6 +80,92 @@ static void hang()
|
||||
}
|
||||
}
|
||||
|
||||
static void init_stdio_fd(int fd, mx_handle_t *handles, size_t nhandles)
|
||||
{
|
||||
if (handles[0] == MX_NULL_HANDLE) {
|
||||
dbg_log("** photon: FD %d is closed\n", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
mx_info_basic_t handle0_info;
|
||||
mx_status_t err = mx_object_get_info(handles[0], MX_INFO_HANDLE_BASIC, &handle0_info, sizeof(handle0_info));
|
||||
if (err != MX_OK) {
|
||||
/* bad handle. TODO report error somehow */
|
||||
return;
|
||||
}
|
||||
|
||||
mio_object *obj = NULL;
|
||||
|
||||
if (handle0_info.type == MX_OBJECT_PIPE) {
|
||||
obj = mio_pipe_create(handles[0]);
|
||||
dbg_log("** photon: FD %d is a pipe\n", fd);
|
||||
} else {
|
||||
/* just assume all other stdio handles implement the file protocol over a tunnel */
|
||||
obj = mio_file_create(handles[0]);
|
||||
dbg_log("** photon: FD %d is a file\n", fd);
|
||||
}
|
||||
|
||||
mio_fd_list_alloc_at(mio_global_fd_list(), obj, fd);
|
||||
}
|
||||
|
||||
static void init_stdio(mx_bootstrap_handle_t *handles, size_t nhandles)
|
||||
{
|
||||
dbg_log("** photon: initialising stdio\n");
|
||||
bool no_fds = true;
|
||||
int max_fd = 0;
|
||||
for (size_t i = 0; i < nhandles; i++) {
|
||||
uint32_t info = handles[i].info;
|
||||
if (MX_B_HND_TYPE(info) != MX_B_FD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
no_fds = false;
|
||||
int fd = MX_B_HND_ARG(info);
|
||||
if (fd > max_fd) {
|
||||
max_fd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
if (no_fds) {
|
||||
dbg_log("** photon: we've been given no FDs\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int nfds = max_fd + 1;
|
||||
dbg_log("** photon: we've been given up to %d FDs\n", nfds);
|
||||
|
||||
/* Supports up to two handles per FD */
|
||||
mx_handle_t fd_handles[nfds][2];
|
||||
memset(fd_handles, 0x0, sizeof(mx_handle_t) * 2 * nfds);
|
||||
|
||||
for (size_t i = 0; i < nhandles; i++) {
|
||||
uint32_t info = handles[i].info;
|
||||
if (MX_B_HND_TYPE(info) != MX_B_FD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int fd = MX_B_HND_ARG(info);
|
||||
mx_handle_t *this_fd_handles = fd_handles[fd];
|
||||
|
||||
if (this_fd_handles[0] != MX_NULL_HANDLE) {
|
||||
this_fd_handles[1] = handles[i].handle;
|
||||
} else {
|
||||
this_fd_handles[0] = handles[i].handle;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < nfds; i++) {
|
||||
size_t n = 1;
|
||||
if (fd_handles[i][1] != MX_NULL_HANDLE) {
|
||||
n++;
|
||||
}
|
||||
|
||||
//dbg_log("** photon: handles for FD %d = { %x, %x }\n", i, fd_handles[i][0], fd_handles[i][1]);
|
||||
|
||||
init_stdio_fd(i, fd_handles[i], n);
|
||||
}
|
||||
}
|
||||
|
||||
int __crt_init(mx_handle_t bootstrap)
|
||||
{
|
||||
size_t msg_size = 0;
|
||||
@@ -81,7 +174,7 @@ int __crt_init(mx_handle_t bootstrap)
|
||||
|
||||
if (status != MX_OK) {
|
||||
/* TODO replace with a better error handler */
|
||||
printf("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);
|
||||
hang();
|
||||
}
|
||||
@@ -94,20 +187,31 @@ int __crt_init(mx_handle_t bootstrap)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
init_stdio(start_handles, nr_handles);
|
||||
int ret = main(msg->args_num, argv);
|
||||
|
||||
__crt_run_atexit();
|
||||
mio_destroy_global_fd_list();
|
||||
mx_task_kill(mx_bootstrap_handle_get(MX_B_TASK_SELF), ret);
|
||||
|
||||
/* unreachable */
|
||||
|
||||
@@ -1,22 +1,47 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <mio/fs.h>
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
return mio_read(fd, buf, count);
|
||||
ssize_t ret = mio_read(fd, buf, count);
|
||||
if (ret < 0) {
|
||||
__set_errno(-(int)ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
return mio_write(fd, buf, count);
|
||||
ssize_t ret = mio_write(fd, buf, count);
|
||||
if (ret < 0) {
|
||||
__set_errno(-(int)ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int open(const char *pathname, int flags)
|
||||
{
|
||||
return mio_open(pathname, flags);
|
||||
int ret = mio_open(pathname, flags);
|
||||
if (ret < 0) {
|
||||
__set_errno(-ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
return mio_close(fd);
|
||||
int ret = mio_close(fd);
|
||||
if (ret < 0) {
|
||||
__set_errno(-ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user