[ulib][fdio] fdio_spawn_vmo: Fill in err_msg for more errors
Tested: Verified error message now gets returned for inability
to connect to fuchsia.process.Resolver. Plus CQ.
Change-Id: I79c824a73ea280c948aeb431aa76c9f033c535c6
diff --git a/system/ulib/fdio/spawn.c b/system/ulib/fdio/spawn.c
index 3e4e955..0b06bf9 100644
--- a/system/ulib/fdio/spawn.c
+++ b/system/ulib/fdio/spawn.c
@@ -70,36 +70,6 @@
static_assert(offsetof(fdio_spawn_action_t, name.data) == 8,
"fdio_spawn_action_t must have a stable ABI");
-// resolve_name makes a call to the fuchsia.process.Resolver service and may
-// return a vmo and associated loader service, if the name resolves within the
-// current realm.
-static zx_status_t resolve_name(const char* name, size_t name_len, zx_handle_t* vmo, zx_handle_t* ldsvc) {
- zx_handle_t resolver, resolver_request;
- zx_status_t status = zx_channel_create(0, &resolver, &resolver_request);
- if (status != ZX_OK) {
- LOG(1, "failed to create channel: %s\n", zx_status_get_string(status));
- return ZX_ERR_INTERNAL;
- }
-
- status = fdio_service_connect("/svc/fuchsia.process.Resolver", resolver_request);
- resolver_request = ZX_HANDLE_INVALID;
- if (status != ZX_OK) {
- zx_handle_close(resolver);
- LOG(1, "failed to connect to resolver service: %s\n", zx_status_get_string(status));
- return ZX_ERR_INTERNAL;
- }
-
- zx_status_t io_status = fuchsia_process_ResolverResolve(
- resolver, name, name_len, &status, vmo, ldsvc);
- zx_handle_close(resolver);
- if (io_status != ZX_OK) {
- LOG(1, "failed to send resolver request: %s\n", zx_status_get_string(io_status));
- return ZX_ERR_INTERNAL;
- }
-
- return status;
-}
-
static zx_status_t load_path(const char* path, zx_handle_t* vmo) {
int fd = open(path, O_RDONLY);
if (fd < 0)
@@ -142,6 +112,38 @@
va_end(args);
}
+// resolve_name makes a call to the fuchsia.process.Resolver service and may
+// return a vmo and associated loader service, if the name resolves within the
+// current realm.
+static zx_status_t resolve_name(const char* name, size_t name_len,
+ zx_handle_t* vmo, zx_handle_t* ldsvc,
+ char* err_msg) {
+ zx_handle_t resolver, resolver_request;
+ zx_status_t status = zx_channel_create(0, &resolver, &resolver_request);
+ if (status != ZX_OK) {
+ report_error(err_msg, "failed to create channel: %d", status);
+ return ZX_ERR_INTERNAL;
+ }
+
+ status = fdio_service_connect("/svc/fuchsia.process.Resolver", resolver_request);
+ resolver_request = ZX_HANDLE_INVALID;
+ if (status != ZX_OK) {
+ zx_handle_close(resolver);
+ report_error(err_msg, "failed to connect to resolver service: %d", status);
+ return ZX_ERR_INTERNAL;
+ }
+
+ zx_status_t io_status = fuchsia_process_ResolverResolve(
+ resolver, name, name_len, &status, vmo, ldsvc);
+ zx_handle_close(resolver);
+ if (io_status != ZX_OK) {
+ report_error(err_msg, "failed to send resolver request: %d", io_status);
+ return ZX_ERR_INTERNAL;
+ }
+
+ return status;
+}
+
static zx_status_t send_string_array(zx_handle_t launcher, int ordinal, const char* const* array) {
size_t count = 0;
size_t len = 0;
@@ -451,6 +453,8 @@
if (err_msg)
err_msg[0] = '\0';
+ // We intentionally don't fill in |err_msg| for invalid args.
+
if (executable_vmo == ZX_HANDLE_INVALID || !argv || (action_count != 0 && !actions)) {
status = ZX_ERR_INVALID_ARGS;
goto cleanup;
@@ -522,7 +526,8 @@
ZX_ASSERT(sizeof(head) < PAGE_SIZE);
memset(head, 0, sizeof(head));
status = zx_vmo_read(executable_vmo, head, 0, sizeof(head));
- if (status != ZX_OK) {
+ if (status != ZX_OK) {
+ report_error(err_msg, "error reading executable vmo: %d", status);
goto cleanup;
}
if (memcmp(FDIO_RESOLVE_PREFIX, head, FDIO_RESOLVE_PREFIX_LEN) != 0) {
@@ -532,6 +537,7 @@
// resolves are not allowed to carry on forever.
if (i == FDIO_SPAWN_MAX_RESOLVE_DEPTH) {
status = ZX_ERR_IO_INVALID;
+ report_error(err_msg, "hit recursion limit resolving name");
goto cleanup;
}
@@ -542,7 +548,7 @@
len = end - name;
}
- status = resolve_name(name, len, &executable_vmo, &ldsvc);
+ status = resolve_name(name, len, &executable_vmo, &ldsvc, err_msg);
if (status != ZX_OK) {
goto cleanup;
}