| // Copyright 2016 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 <lib/fdio/directory.h> |
| #include <lib/fdio/fd.h> |
| #include <lib/fdio/fdio.h> |
| #include <lib/fdio/io.h> |
| #include <lib/fdio/namespace.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <zircon/process.h> |
| #include <zircon/processargs.h> |
| #include <zircon/syscalls.h> |
| |
| #include <launchpad/launchpad.h> |
| #include <launchpad/vmo.h> |
| |
| static zx_status_t add_fdio(launchpad_t* lp, zx_handle_t* handle, uint32_t type, |
| zx_status_t status) { |
| if (status == ZX_ERR_BAD_HANDLE) |
| return ZX_OK; |
| if (status == ZX_ERR_NOT_SUPPORTED) |
| return ZX_OK; |
| if (status == ZX_OK) { |
| return launchpad_add_handles(lp, 1, handle, &type); |
| } else { |
| launchpad_abort(lp, status, "add_fdio: failed"); |
| return status; |
| } |
| } |
| |
| __EXPORT |
| zx_status_t launchpad_clone(launchpad_t* lp, uint32_t what) { |
| if (what & LP_CLONE_FDIO_NAMESPACE) { |
| fdio_flat_namespace_t* flat; |
| zx_status_t status = fdio_ns_export_root(&flat); |
| if (status == ZX_OK) { |
| launchpad_set_nametable(lp, flat->count, flat->path); |
| launchpad_add_handles(lp, flat->count, flat->handle, flat->type); |
| free(flat); |
| } else if (status != ZX_ERR_NOT_FOUND) { |
| launchpad_abort(lp, status, "clone: error cloning namespace"); |
| return status; |
| } |
| } |
| if (what & LP_CLONE_FDIO_STDIO) { |
| for (int fd = 0; fd < 3; fd++) { |
| zx_handle_t handle = ZX_HANDLE_INVALID; |
| add_fdio(lp, &handle, PA_HND(PA_FD, fd), fdio_fd_clone(fd, &handle)); |
| } |
| } |
| if (what & LP_CLONE_ENVIRON) { |
| launchpad_set_environ(lp, (const char* const*)environ); |
| } |
| if (what & LP_CLONE_DEFAULT_JOB) { |
| zx_handle_t job; |
| if (zx_handle_duplicate(zx_job_default(), ZX_RIGHT_SAME_RIGHTS, &job) == ZX_OK) { |
| launchpad_add_handle(lp, job, PA_HND(PA_JOB_DEFAULT, 0)); |
| } |
| } |
| return launchpad_get_status(lp); |
| } |