[fdio] Export fdio_service_connect_by_name

Also update to take a request instead of returning the client end.

Change-Id: I18cee60d81a77451f3d76f457fffc43c846b817c
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/481033
Commit-Queue: Theodore Dubois <tbodt@google.com>
Reviewed-by: Adam Barth <abarth@google.com>
API-Review: Adam Barth <abarth@google.com>
diff --git a/sdk/lib/fdio/bsdsocket.cc b/sdk/lib/fdio/bsdsocket.cc
index 2d8df11..8e6e110 100644
--- a/sdk/lib/fdio/bsdsocket.cc
+++ b/sdk/lib/fdio/bsdsocket.cc
@@ -5,6 +5,7 @@
 #include <fcntl.h>
 #include <fuchsia/net/llcpp/fidl.h>
 #include <ifaddrs.h>
+#include <lib/fdio/directory.h>
 #include <lib/fdio/fdio.h>
 #include <lib/fdio/io.h>
 #include <net/if.h>
@@ -30,25 +31,29 @@
 namespace fnet = ::llcpp::fuchsia::net;
 namespace fsocket = ::llcpp::fuchsia::posix::socket;
 
-#define MAKE_GET_SERVICE(fn_name, symbol)                        \
-  zx_status_t fn_name(symbol::SyncClient** out) {                \
-    static symbol::SyncClient* saved;                            \
-    static std::once_flag once;                                  \
-    static zx_status_t status;                                   \
-    std::call_once(once, [&]() {                                 \
-      zx::channel out;                                           \
-      status = fdio_service_connect_by_name(symbol::Name, &out); \
-      if (status != ZX_OK) {                                     \
-        return;                                                  \
-      }                                                          \
-      static symbol::SyncClient client(std::move(out));          \
-      saved = &client;                                           \
-    });                                                          \
-    if (status != ZX_OK) {                                       \
-      return status;                                             \
-    }                                                            \
-    *out = saved;                                                \
-    return ZX_OK;                                                \
+#define MAKE_GET_SERVICE(fn_name, symbol)                                     \
+  zx_status_t fn_name(symbol::SyncClient** out) {                             \
+    static symbol::SyncClient* saved;                                         \
+    static std::once_flag once;                                               \
+    static zx_status_t status;                                                \
+    std::call_once(once, [&]() {                                              \
+      zx::channel out, request;                                               \
+      status = zx::channel::create(0, &out, &request);                        \
+      if (status != ZX_OK) {                                                  \
+        return;                                                               \
+      }                                                                       \
+      status = fdio_service_connect_by_name(symbol::Name, request.release()); \
+      if (status != ZX_OK) {                                                  \
+        return;                                                               \
+      }                                                                       \
+      static symbol::SyncClient client(std::move(out));                       \
+      saved = &client;                                                        \
+    });                                                                       \
+    if (status != ZX_OK) {                                                    \
+      return status;                                                          \
+    }                                                                         \
+    *out = saved;                                                             \
+    return ZX_OK;                                                             \
   }
 
 namespace {
diff --git a/sdk/lib/fdio/fdio.api b/sdk/lib/fdio/fdio.api
index 5b6d7b5..122d82f 100644
--- a/sdk/lib/fdio/fdio.api
+++ b/sdk/lib/fdio/fdio.api
@@ -1,5 +1,5 @@
 {
-  "pkg/fdio/include/lib/fdio/directory.h": "a61ed177ebed578f0f44b44efe9e1e10",
+  "pkg/fdio/include/lib/fdio/directory.h": "033553508b789cc99c151680ecbcd745",
   "pkg/fdio/include/lib/fdio/fd.h": "540c21ac2bf08837e470fcf68ca23f70",
   "pkg/fdio/include/lib/fdio/fdio.h": "84df024533560efcb67e3c3e336f8688",
   "pkg/fdio/include/lib/fdio/io.h": "d73c16f16c2e2119441bf3c239842882",
diff --git a/sdk/lib/fdio/fdio.symbols.api b/sdk/lib/fdio/fdio.symbols.api
index 991a5b6..0c585fa 100644
--- a/sdk/lib/fdio/fdio.symbols.api
+++ b/sdk/lib/fdio/fdio.symbols.api
@@ -64,6 +64,7 @@
 fdio_service_clone_to
 fdio_service_connect
 fdio_service_connect_at
+fdio_service_connect_by_name
 fdio_spawn
 fdio_spawn_etc
 fdio_spawn_vmo
diff --git a/sdk/lib/fdio/include/lib/fdio/directory.h b/sdk/lib/fdio/include/lib/fdio/directory.h
index 5fe566b..f63e24c 100644
--- a/sdk/lib/fdio/include/lib/fdio/directory.h
+++ b/sdk/lib/fdio/include/lib/fdio/directory.h
@@ -66,6 +66,9 @@
 zx_status_t fdio_service_connect_at(zx_handle_t directory, const char* path,
                                     ZX_HANDLE_RELEASE zx_handle_t request);
 
+// Connect to a service named |name| in /svc.
+zx_status_t fdio_service_connect_by_name(const char* name, ZX_HANDLE_RELEASE zx_handle_t request);
+
 // Opens the remote object at the given |path| relative to the root of the namespace with the given
 // |flags| asynchronously.
 //
diff --git a/sdk/lib/fdio/internal.h b/sdk/lib/fdio/internal.h
index 4def34e..ece614d 100644
--- a/sdk/lib/fdio/internal.h
+++ b/sdk/lib/fdio/internal.h
@@ -436,7 +436,4 @@
 // then -1 is returned and errno is set to EINVAL, otherwise |fd| is returned.
 int fdio_release_reserved(int fd);
 
-// Connect to a service named |name| in /svc.
-zx_status_t fdio_service_connect_by_name(const char name[], zx::channel* out);
-
 #endif  // LIB_FDIO_INTERNAL_H_
diff --git a/sdk/lib/fdio/remoteio.cc b/sdk/lib/fdio/remoteio.cc
index 4e9a0f7..82301a44 100644
--- a/sdk/lib/fdio/remoteio.cc
+++ b/sdk/lib/fdio/remoteio.cc
@@ -71,7 +71,8 @@
       .status();
 }
 
-zx_status_t fdio_service_connect_by_name(const char name[], zx::channel* out) {
+__EXPORT
+zx_status_t fdio_service_connect_by_name(const char name[], zx_handle_t request) {
   static zx_handle_t service_root;
 
   {
@@ -95,17 +96,10 @@
     }
   }
 
-  zx::channel c0, c1;
-  zx_status_t status = zx::channel::create(0, &c0, &c1);
+  zx_status_t status = fdio_service_connect_at(service_root, name, request);
   if (status != ZX_OK) {
     return status;
   }
-
-  status = fdio_service_connect_at(service_root, name, c0.release());
-  if (status != ZX_OK) {
-    return status;
-  }
-  *out = std::move(c1);
   return ZX_OK;
 }
 
diff --git a/sdk/lib/fdio/spawn.cc b/sdk/lib/fdio/spawn.cc
index b8304bc..d893027 100644
--- a/sdk/lib/fdio/spawn.cc
+++ b/sdk/lib/fdio/spawn.cc
@@ -136,8 +136,13 @@
 static zx_status_t resolve_name(const char* name, size_t name_len, zx::vmo* out_executable,
                                 zx::channel* out_ldsvc, char* err_msg) {
   fprocess::Resolver::SyncClient resolver;
-  zx_status_t status =
-      fdio_service_connect_by_name(fprocess::Resolver::Name, resolver.mutable_channel());
+  zx::channel request;
+  zx_status_t status = zx::channel::create(0, &request, resolver.mutable_channel());
+  if (status != ZX_OK) {
+    report_error(err_msg, "failed to create channel for resolver service: %d", status);
+    return ZX_ERR_INTERNAL;
+  }
+  status = fdio_service_connect_by_name(fprocess::Resolver::Name, request.release());
   if (status != ZX_OK) {
     report_error(err_msg, "failed to connect to resolver service: %d", status);
     return ZX_ERR_INTERNAL;
@@ -609,6 +614,7 @@
   size_t handle_capacity = 0;
   std::vector<std::string_view> shared_dirs;
   fprocess::Launcher::SyncClient launcher;
+  zx::channel request;
   zx::channel ldsvc;
   const char* process_name = nullptr;
   size_t process_name_size = 0;
@@ -744,7 +750,12 @@
     ++handle_capacity;
   }
 
-  status = fdio_service_connect_by_name(fprocess::Launcher::Name, launcher.mutable_channel());
+  status = zx::channel::create(0, &request, launcher.mutable_channel());
+  if (status != ZX_OK) {
+    report_error(err_msg, "failed to create channel for launcher service: %d", status);
+    goto cleanup;
+  }
+  status = fdio_service_connect_by_name(fprocess::Launcher::Name, request.release());
   if (status != ZX_OK) {
     report_error(err_msg, "failed to connect to launcher service: %d", status);
     goto cleanup;
diff --git a/sdk/lib/fdio/uname.cc b/sdk/lib/fdio/uname.cc
index 1b4c22a..02654b0 100644
--- a/sdk/lib/fdio/uname.cc
+++ b/sdk/lib/fdio/uname.cc
@@ -4,6 +4,7 @@
 
 #include <errno.h>
 #include <fuchsia/device/llcpp/fidl.h>
+#include <lib/fdio/directory.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/utsname.h>
@@ -25,8 +26,13 @@
     static std::once_flag once;
     static zx_status_t status;
     std::call_once(once, [&]() {
-      zx::channel out;
-      status = fdio_service_connect_by_name(llcpp::fuchsia::device::NameProvider::Name, &out);
+      zx::channel out, request;
+      status = zx::channel::create(0, &out, &request);
+      if (status != ZX_OK) {
+        return;
+      }
+      status = fdio_service_connect_by_name(llcpp::fuchsia::device::NameProvider::Name,
+                                            request.release());
       if (status != ZX_OK) {
         return;
       }