Horizon init now initialises MIO using bootstrap handles
This commit is contained in:
@@ -2,12 +2,19 @@
|
|||||||
#include <magenta/tunnel.h>
|
#include <magenta/tunnel.h>
|
||||||
#include <magenta/bootstrap.h>
|
#include <magenta/bootstrap.h>
|
||||||
#include <magenta/errors.h>
|
#include <magenta/errors.h>
|
||||||
|
#include <magenta/handle.h>
|
||||||
#include <magenta/misc.h>
|
#include <magenta/misc.h>
|
||||||
|
#include <magenta/object.h>
|
||||||
|
#include <mio/object.h>
|
||||||
|
#include <mio/fd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "__init.h"
|
#include "__init.h"
|
||||||
#include "__heap.h"
|
#include "__heap.h"
|
||||||
#include "__fio.h"
|
#include "__fio.h"
|
||||||
|
|
||||||
|
#define dbg_log(...)
|
||||||
|
|
||||||
static const char **environ = NULL;
|
static const char **environ = NULL;
|
||||||
|
|
||||||
const char **__crt_environ()
|
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)
|
int __crt_init(mx_handle_t bootstrap)
|
||||||
{
|
{
|
||||||
size_t msg_size = 0;
|
size_t msg_size = 0;
|
||||||
@@ -81,7 +174,7 @@ int __crt_init(mx_handle_t bootstrap)
|
|||||||
|
|
||||||
if (status != MX_OK) {
|
if (status != MX_OK) {
|
||||||
/* TODO replace with a better error handler */
|
/* 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);
|
bootstrap, status);
|
||||||
hang();
|
hang();
|
||||||
}
|
}
|
||||||
@@ -94,20 +187,31 @@ int __crt_init(mx_handle_t bootstrap)
|
|||||||
|
|
||||||
const char *argv[msg->args_num + 1];
|
const char *argv[msg->args_num + 1];
|
||||||
const char *envp[msg->environ_num + 1];
|
const char *envp[msg->environ_num + 1];
|
||||||
|
#ifdef LIBSYSTEM_STATIC
|
||||||
mx_bootstrap_handle_t start_handles[nr_handles + 1];
|
mx_bootstrap_handle_t start_handles[nr_handles + 1];
|
||||||
start_handles[nr_handles].handle = bootstrap;
|
start_handles[nr_handles].handle = bootstrap;
|
||||||
start_handles[nr_handles].info = MX_B_HND(MX_B_TUNNEL_BTSTP, 0);
|
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;
|
argv[msg->args_num] = NULL;
|
||||||
envp[msg->environ_num] = NULL;
|
envp[msg->environ_num] = NULL;
|
||||||
environ = envp;
|
environ = envp;
|
||||||
|
|
||||||
parse_args(msg, handles, argv, envp, nr_handles, start_handles);
|
parse_args(msg, handles, argv, envp, nr_handles, start_handles);
|
||||||
|
#ifdef LIBSYSTEM_STATIC
|
||||||
mx_bootstrap_handle_init(start_handles, nr_handles + 1);
|
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);
|
int ret = main(msg->args_num, argv);
|
||||||
|
|
||||||
__crt_run_atexit();
|
__crt_run_atexit();
|
||||||
|
mio_destroy_global_fd_list();
|
||||||
mx_task_kill(mx_bootstrap_handle_get(MX_B_TASK_SELF), ret);
|
mx_task_kill(mx_bootstrap_handle_get(MX_B_TASK_SELF), ret);
|
||||||
|
|
||||||
/* unreachable */
|
/* unreachable */
|
||||||
|
|||||||
@@ -1,22 +1,47 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <mio/fs.h>
|
#include <mio/fs.h>
|
||||||
|
|
||||||
ssize_t read(int fd, void *buf, size_t count)
|
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)
|
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)
|
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)
|
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