blob: 499fc10a290bfaefd45d828512bc0b15cd96bbb3 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fs-management/mount.h>
#include <launchpad/launchpad.h>
#include <launchpad/vmo.h>
#include <zircon/compiler.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <fdio/io.h>
#include <fdio/util.h>
zx_status_t launch_logs_async(int argc, const char** argv, zx_handle_t* handles,
uint32_t* types, size_t len) {
launchpad_t* lp;
launchpad_create(0, argv[0], &lp);
launchpad_clone(lp, LP_CLONE_ALL & (~LP_CLONE_FDIO_STDIO));
launchpad_load_from_file(lp, argv[0]);
launchpad_set_args(lp, argc, argv);
for (size_t i = 0; i < len; i++) {
launchpad_add_handle(lp, handles[i], types[i]);
}
zx_handle_t h;
zx_log_create(0, &h);
if (h != ZX_HANDLE_INVALID) {
launchpad_add_handle(lp, h, PA_HND(PA_FDIO_LOGGER,
0 | FDIO_FLAG_USE_FOR_STDIO));
}
zx_status_t status;
const char* errmsg;
if ((status = launchpad_go(lp, NULL, &errmsg)) != ZX_OK) {
fprintf(stderr, "fs-management: Cannot launch %s: %d: %s\n", argv[0], status, errmsg);
}
return status;
}
static void init_stdio(launchpad_t** lp, int argc, const char** argv,
zx_handle_t* handles, uint32_t* types, size_t len) {
launchpad_create(0, argv[0], lp);
launchpad_clone(*lp, LP_CLONE_ALL);
launchpad_load_from_file(*lp, argv[0]);
launchpad_set_args(*lp, argc, argv);
for (size_t i = 0; i < len; i++) {
launchpad_add_handle(*lp, handles[i], types[i]);
}
}
zx_status_t launch_stdio_sync(int argc, const char** argv, zx_handle_t* handles,
uint32_t* types, size_t len) {
launchpad_t* lp;
init_stdio(&lp, argc, argv, handles, types, len);
zx_status_t status;
zx_handle_t proc;
const char* errmsg;
if ((status = launchpad_go(lp, &proc, &errmsg)) != ZX_OK) {
fprintf(stderr, "fs-management: Cannot launch %s: %d: %s\n", argv[0], status, errmsg);
return status;
}
status = zx_object_wait_one(proc, ZX_PROCESS_TERMINATED, ZX_TIME_INFINITE, NULL);
if (status != ZX_OK) {
fprintf(stderr, "launch: Error waiting for process to terminate\n");
zx_handle_close(proc);
return status;
}
zx_info_process_t info;
if ((status = zx_object_get_info(proc, ZX_INFO_PROCESS, &info, sizeof(info), NULL, NULL)) < 0) {
fprintf(stderr, "launch: Failed to get process info\n");
zx_handle_close(proc);
return status;
}
zx_handle_close(proc);
if (!info.exited || info.return_code != 0) {
return ZX_ERR_BAD_STATE;
}
return ZX_OK;
}
zx_status_t launch_stdio_async(int argc, const char** argv, zx_handle_t* handles,
uint32_t* types, size_t len) {
launchpad_t* lp;
init_stdio(&lp, argc, argv, handles, types, len);
zx_status_t status;
const char* errmsg;
if ((status = launchpad_go(lp, NULL, &errmsg)) != ZX_OK) {
fprintf(stderr, "fs-management: Cannot launch %s: %d: %s\n", argv[0], status, errmsg);
return status;
}
return status;
}