1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <launchpad/launchpad.h>
6 #include <launchpad/vmo.h>
7
8 #include <zircon/process.h>
9 #include <zircon/processargs.h>
10 #include <zircon/syscalls.h>
11 #include <lib/fdio/io.h>
12 #include <lib/fdio/namespace.h>
13 #include <lib/fdio/util.h>
14
15 #include <stdlib.h>
16 #include <unistd.h>
17
add_fdio(launchpad_t * lp,zx_handle_t handles[FDIO_MAX_HANDLES],uint32_t types[FDIO_MAX_HANDLES],zx_status_t status)18 static zx_status_t add_fdio(launchpad_t* lp,
19 zx_handle_t handles[FDIO_MAX_HANDLES],
20 uint32_t types[FDIO_MAX_HANDLES],
21 zx_status_t status) {
22 if (status == ZX_ERR_BAD_HANDLE)
23 return ZX_OK;
24 if (status == ZX_ERR_NOT_SUPPORTED)
25 return ZX_OK;
26 if (status > 0) {
27 return launchpad_add_handles(lp, status, handles, types);
28 } else {
29 launchpad_abort(lp, status, "add_fdio: failed");
30 return status;
31 }
32 }
33
launchpad_clone(launchpad_t * lp,uint32_t what)34 zx_status_t launchpad_clone(launchpad_t* lp, uint32_t what) {
35 zx_handle_t handles[FDIO_MAX_HANDLES];
36 uint32_t types[FDIO_MAX_HANDLES];
37 zx_status_t status;
38
39 if (what & LP_CLONE_FDIO_NAMESPACE) {
40 fdio_flat_namespace_t* flat;
41 status = fdio_ns_export_root(&flat);
42 if (status == ZX_OK) {
43 launchpad_set_nametable(lp, flat->count, flat->path);
44 launchpad_add_handles(lp, flat->count, flat->handle, flat->type);
45 free(flat);
46 } else if (status != ZX_ERR_NOT_FOUND) {
47 launchpad_abort(lp, status, "clone: error cloning namespace");
48 return status;
49 }
50 }
51 if (what & LP_CLONE_FDIO_STDIO) {
52 for (int fd = 0; fd < 3; fd++) {
53 add_fdio(lp, handles, types, fdio_clone_fd(fd, fd, handles, types));
54 }
55 }
56 if (what & LP_CLONE_ENVIRON) {
57 launchpad_set_environ(lp, (const char* const*)environ);
58 }
59 if (what & LP_CLONE_DEFAULT_JOB) {
60 zx_handle_t job;
61 if (zx_handle_duplicate(zx_job_default(), ZX_RIGHT_SAME_RIGHTS, &job) == ZX_OK) {
62 launchpad_add_handle(lp, job, PA_HND(PA_JOB_DEFAULT, 0));
63 }
64 }
65 return launchpad_get_status(lp);
66 }
67
launchpad_clone_fd(launchpad_t * lp,int fd,int target_fd)68 zx_status_t launchpad_clone_fd(launchpad_t* lp, int fd, int target_fd) {
69 zx_handle_t handles[FDIO_MAX_HANDLES];
70 uint32_t types[FDIO_MAX_HANDLES];
71 return add_fdio(lp, handles, types,
72 fdio_clone_fd(fd, target_fd, handles, types));
73 }
74
launchpad_transfer_fd(launchpad_t * lp,int fd,int target_fd)75 zx_status_t launchpad_transfer_fd(launchpad_t* lp, int fd, int target_fd) {
76 zx_handle_t handles[FDIO_MAX_HANDLES];
77 uint32_t types[FDIO_MAX_HANDLES];
78 return add_fdio(lp, handles, types,
79 fdio_transfer_fd(fd, target_fd, handles, types));
80 }
81