[fidl] Use fuchsia-io LLCPP bindings in fdio utests

Bug: 38504
Change-Id: Id7972af0aa9005e18fd407ad46c9634ba16b5463
diff --git a/zircon/system/utest/fdio/BUILD.gn b/zircon/system/utest/fdio/BUILD.gn
index 3687f46..49d978d 100644
--- a/zircon/system/utest/fdio/BUILD.gn
+++ b/zircon/system/utest/fdio/BUILD.gn
@@ -22,7 +22,7 @@
     "fdio_watcher.cc",
   ]
   deps = [
-    "$zx/system/fidl/fuchsia-io:c",
+    "$zx/system/fidl/fuchsia-io:llcpp",
     "$zx/system/fidl/fuchsia-posix-socket:llcpp",
     "$zx/system/fidl/fuchsia-process:c",
     "$zx/system/ulib/async-loop:async-loop-cpp",
diff --git a/zircon/system/utest/fdio/fdio_directory.cc b/zircon/system/utest/fdio/fdio_directory.cc
index b260caa..47978fe 100644
--- a/zircon/system/utest/fdio/fdio_directory.cc
+++ b/zircon/system/utest/fdio/fdio_directory.cc
@@ -2,13 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <fuchsia/io/c/fidl.h>
+#include <fuchsia/io/llcpp/fidl.h>
 #include <fuchsia/process/c/fidl.h>
 #include <lib/fdio/directory.h>
 #include <lib/zx/channel.h>
 
 #include <zxtest/zxtest.h>
 
+namespace {
+
+namespace fuchsia_io = ::llcpp::fuchsia::io;
+
 TEST(DirectoryTest, ServiceConnect) {
   ASSERT_EQ(ZX_ERR_INVALID_ARGS, fdio_service_connect(nullptr, ZX_HANDLE_INVALID));
 
@@ -26,16 +30,16 @@
 
   zx::channel h1, h2;
   ASSERT_OK(zx::channel::create(0, &h1, &h2));
-  ASSERT_EQ(ZX_ERR_NOT_FOUND, fdio_open("/x/y/z", fuchsia_io_OPEN_RIGHT_READABLE, h1.release()));
-  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, fdio_open("/", fuchsia_io_OPEN_RIGHT_READABLE, h2.release()));
+  ASSERT_EQ(ZX_ERR_NOT_FOUND, fdio_open("/x/y/z", fuchsia_io::OPEN_RIGHT_READABLE, h1.release()));
+  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, fdio_open("/", fuchsia_io::OPEN_RIGHT_READABLE, h2.release()));
 
   ASSERT_OK(zx::channel::create(0, &h1, &h2));
-  ASSERT_OK(fdio_open("/svc", fuchsia_io_OPEN_RIGHT_READABLE, h1.release()));
+  ASSERT_OK(fdio_open("/svc", fuchsia_io::OPEN_RIGHT_READABLE, h1.release()));
 
   zx::channel h3, h4;
   ASSERT_OK(zx::channel::create(0, &h3, &h4));
   ASSERT_OK(fdio_service_connect_at(h2.get(), fuchsia_process_Launcher_Name, h3.release()));
-  ASSERT_OK(fdio_open_at(h2.get(), fuchsia_process_Launcher_Name, fuchsia_io_OPEN_RIGHT_READABLE,
+  ASSERT_OK(fdio_open_at(h2.get(), fuchsia_process_Launcher_Name, fuchsia_io::OPEN_RIGHT_READABLE,
                          h4.release()));
 
   h3.reset(fdio_service_clone(h2.get()));
@@ -56,28 +60,28 @@
 
 TEST(DirectoryTest, OpenFD) {
   int fd = -1;
-  ASSERT_EQ(ZX_ERR_INVALID_ARGS, fdio_open_fd(nullptr, fuchsia_io_OPEN_RIGHT_READABLE, &fd));
-  ASSERT_EQ(ZX_ERR_NOT_FOUND, fdio_open_fd("/x/y/z", fuchsia_io_OPEN_RIGHT_READABLE, &fd));
+  ASSERT_EQ(ZX_ERR_INVALID_ARGS, fdio_open_fd(nullptr, fuchsia_io::OPEN_RIGHT_READABLE, &fd));
+  ASSERT_EQ(ZX_ERR_NOT_FOUND, fdio_open_fd("/x/y/z", fuchsia_io::OPEN_RIGHT_READABLE, &fd));
 
   // Opening local directories, like the root of the namespace, should be supported.
-  ASSERT_OK(fdio_open_fd("/", fuchsia_io_OPEN_RIGHT_READABLE, &fd));
+  ASSERT_OK(fdio_open_fd("/", fuchsia_io::OPEN_RIGHT_READABLE, &fd));
   // But empty path segments don't need to be supported.
-  ASSERT_EQ(ZX_ERR_BAD_PATH, fdio_open_fd("//", fuchsia_io_OPEN_RIGHT_READABLE, &fd));
+  ASSERT_EQ(ZX_ERR_BAD_PATH, fdio_open_fd("//", fuchsia_io::OPEN_RIGHT_READABLE, &fd));
 
   std::string test_sys_path = new_path("test/sys");
-  ASSERT_OK(fdio_open_fd(test_sys_path.c_str(), fuchsia_io_OPEN_RIGHT_READABLE, &fd));
+  ASSERT_OK(fdio_open_fd(test_sys_path.c_str(), fuchsia_io::OPEN_RIGHT_READABLE, &fd));
   ASSERT_TRUE(fd >= 0);
 
   int fd2 = -1;
   ASSERT_EQ(ZX_ERR_INVALID_ARGS,
-            fdio_open_fd_at(fd, nullptr, fuchsia_io_OPEN_RIGHT_READABLE, &fd2));
+            fdio_open_fd_at(fd, nullptr, fuchsia_io::OPEN_RIGHT_READABLE, &fd2));
   ASSERT_EQ(fd2, -1);
   ASSERT_EQ(ZX_ERR_NOT_FOUND,
-            fdio_open_fd_at(fd, "some-nonexistent-file", fuchsia_io_OPEN_RIGHT_READABLE, &fd2));
+            fdio_open_fd_at(fd, "some-nonexistent-file", fuchsia_io::OPEN_RIGHT_READABLE, &fd2));
   ASSERT_EQ(fd2, -1);
 
   // We expect the binary that this file is compiled into to exist
-  ASSERT_OK(fdio_open_fd_at(fd, "fdio-test", fuchsia_io_OPEN_RIGHT_READABLE, &fd2));
+  ASSERT_OK(fdio_open_fd_at(fd, "fdio-test", fuchsia_io::OPEN_RIGHT_READABLE, &fd2));
   ASSERT_TRUE(fd >= 0);
 
   // Verify that we can actually read from that file.
@@ -85,3 +89,5 @@
   ssize_t bytes_read = read(fd2, buf, 256);
   ASSERT_EQ(bytes_read, 256);
 }
+
+}  // namespace
diff --git a/zircon/system/utest/fdio/fdio_get_vmo.cc b/zircon/system/utest/fdio/fdio_get_vmo.cc
index ed0681c..03756ad 100644
--- a/zircon/system/utest/fdio/fdio_get_vmo.cc
+++ b/zircon/system/utest/fdio/fdio_get_vmo.cc
@@ -2,15 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <fuchsia/io/c/fidl.h>
+#include <fuchsia/io/llcpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/async-loop/default.h>
 #include <lib/fdio/fd.h>
 #include <lib/fdio/io.h>
-#include <lib/fidl-async/bind.h>
+#include <lib/fidl-async/cpp/bind.h>
+#include <lib/fidl/llcpp/vector_view.h>
 #include <lib/zx/channel.h>
 #include <lib/zx/vmo.h>
 #include <sys/mman.h>
+#include <zircon/errors.h>
 #include <zircon/limits.h>
 #include <zircon/rights.h>
 #include <zircon/syscalls/object.h>
@@ -34,6 +36,8 @@
 
 namespace {
 
+namespace fuchsia_io = ::llcpp::fuchsia::io;
+
 struct Context {
   zx::vmo vmo;
   bool is_vmofile;
@@ -43,162 +47,130 @@
   size_t content_size;  // Must be <= ZX_PAGE_SIZE.
   uint32_t last_flags;
 };
+class TestServer final : public fuchsia_io::File::Interface {
+ public:
+  TestServer(Context* context) : context(context) {}
 
-zx_status_t FileClone(void* ctx, uint32_t flags, zx_handle_t object) {
-  return ZX_ERR_NOT_SUPPORTED;
-}
+  void Clone(uint32_t flags, zx::channel object, CloneCompleter::Sync completer) override {}
 
-zx_status_t FileClose(void* ctx, fidl_txn_t* txn) { return fuchsia_io_NodeClose_reply(txn, ZX_OK); }
+  void Close(CloseCompleter::Sync completer) override { completer.Reply(ZX_OK); }
 
-zx_status_t FileDescribe(void* ctx, fidl_txn_t* txn) {
-  Context* context = reinterpret_cast<Context*>(ctx);
-  fuchsia_io_NodeInfo info;
-  memset(&info, 0, sizeof(info));
-  if (context->is_vmofile) {
-    zx::vmo vmo;
-    zx_status_t status = context->vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
+  void Describe(DescribeCompleter::Sync completer) override {
+    if (context->is_vmofile) {
+      zx::vmo vmo;
+      zx_status_t status = context->vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
+      if (status != ZX_OK) {
+        return;
+      }
+
+      fuchsia_io::Vmofile vmofile;
+      vmofile.vmo = std::move(vmo);
+      vmofile.offset = 0;
+      vmofile.length = context->content_size;
+      completer.Reply(fuchsia_io::NodeInfo::WithVmofile(std::move(vmofile)));
+    } else {
+      fuchsia_io::FileObject fo;
+      completer.Reply(fuchsia_io::NodeInfo::WithFile(std::move(fo)));
+    }
+  }
+
+  void Sync(SyncCompleter::Sync completer) override {}
+
+  void GetAttr(GetAttrCompleter::Sync completer) override {
+    fuchsia_io::NodeAttributes attributes;
+    attributes.id = 5;
+    attributes.content_size = context->content_size;
+    attributes.storage_size = ZX_PAGE_SIZE;
+    attributes.link_count = 1;
+    completer.Reply(ZX_OK, std::move(attributes));
+  }
+
+  void SetAttr(uint32_t flags, fuchsia_io::NodeAttributes attribute,
+               SetAttrCompleter::Sync completer) override {}
+
+  void Read(uint64_t count, ReadCompleter::Sync completer) override {}
+
+  void ReadAt(uint64_t count, uint64_t offset, ReadAtCompleter::Sync completer) override {
+    if (!context->supports_read_at) {
+      return completer.Reply(ZX_ERR_NOT_SUPPORTED, fidl::VectorView<uint8_t>());
+    }
+    if (offset >= context->content_size) {
+      return completer.Reply(ZX_OK, fidl::VectorView<uint8_t>());
+    }
+    size_t actual = std::min(count, context->content_size - offset);
+    uint8_t buffer[ZX_PAGE_SIZE];
+    zx_status_t status = context->vmo.read(buffer, offset, actual);
     if (status != ZX_OK) {
-      return status;
+      return completer.Reply(status, fidl::VectorView<uint8_t>());
+    }
+    completer.Reply(ZX_OK, fidl::VectorView(buffer, actual));
+  }
+
+  void Write(fidl::VectorView<uint8_t> data, WriteCompleter::Sync completer) override {}
+
+  void WriteAt(fidl::VectorView<uint8_t> data, uint64_t offset,
+               WriteAtCompleter::Sync completer) override {}
+
+  void Seek(int64_t offset, fuchsia_io::SeekOrigin start, SeekCompleter::Sync completer) override {
+    if (!context->supports_seek) {
+      completer.Reply(ZX_ERR_NOT_SUPPORTED, 0);
+    }
+    completer.Reply(ZX_OK, 0);
+  }
+
+  void Truncate(uint64_t length, TruncateCompleter::Sync completer) override {}
+
+  void GetFlags(GetFlagsCompleter::Sync completer) override {}
+
+  void SetFlags(uint32_t flags, SetFlagsCompleter::Sync completer) override {}
+
+  void GetBuffer(uint32_t flags, GetBufferCompleter::Sync completer) override {
+    context->last_flags = flags;
+
+    if (!context->supports_get_buffer) {
+      return completer.Reply(ZX_ERR_NOT_SUPPORTED, nullptr);
     }
 
-    info.tag = fuchsia_io_NodeInfoTag_vmofile;
-    info.vmofile.vmo = vmo.release();
-    info.vmofile.offset = 0;
-    info.vmofile.length = context->content_size;
-  } else {
-    info.tag = fuchsia_io_NodeInfoTag_file;
-  }
-  return fuchsia_io_NodeDescribe_reply(txn, &info);
-}
+    llcpp::fuchsia::mem::Buffer buffer = {};
+    buffer.size = context->content_size;
 
-zx_status_t FileSync(void* ctx, fidl_txn_t* txn) { return ZX_ERR_NOT_SUPPORTED; }
+    // TODO(fxb/37091): This should just have GET_PROPERTY, not SET_PROPERTY, but currently this
+    // mimics what most filesystems do.
+    zx_rights_t rights = ZX_RIGHTS_BASIC | ZX_RIGHT_MAP | ZX_RIGHTS_PROPERTY;
+    rights |= (flags & fuchsia_io::VMO_FLAG_READ) ? ZX_RIGHT_READ : 0;
+    rights |= (flags & fuchsia_io::VMO_FLAG_WRITE) ? ZX_RIGHT_WRITE : 0;
+    rights |= (flags & fuchsia_io::VMO_FLAG_EXEC) ? ZX_RIGHT_EXECUTE : 0;
 
-zx_status_t FileGetAttr(void* ctx, fidl_txn_t* txn) {
-  Context* context = reinterpret_cast<Context*>(ctx);
-  fuchsia_io_NodeAttributes attributes = {};
-  attributes.id = 5;
-  attributes.content_size = context->content_size;
-  attributes.storage_size = ZX_PAGE_SIZE;
-  attributes.link_count = 1;
-  return fuchsia_io_NodeGetAttr_reply(txn, ZX_OK, &attributes);
-}
+    zx_status_t status = ZX_OK;
+    zx::vmo result;
+    if (flags & fuchsia_io::VMO_FLAG_PRIVATE) {
+      uint32_t options = ZX_VMO_CHILD_COPY_ON_WRITE;
+      if (flags & fuchsia_io::VMO_FLAG_EXEC) {
+        // Creating a COPY_ON_WRITE child removes ZX_RIGHT_EXECUTE even if the parent VMO has it,
+        // but NO_WRITE changes this behavior so that the new handle doesn't have WRITE and
+        // preserves EXECUTE.
+        options |= ZX_VMO_CHILD_NO_WRITE;
+      }
+      status = context->vmo.create_child(options, 0, ZX_PAGE_SIZE, &result);
+      if (status != ZX_OK) {
+        return completer.Reply(status, nullptr);
+      }
 
-zx_status_t FileSetAttr(void* ctx, uint32_t flags, const fuchsia_io_NodeAttributes* attributes,
-                        fidl_txn_t* txn) {
-  return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t FileRead(void* ctx, uint64_t count, fidl_txn_t* txn) { return ZX_ERR_NOT_SUPPORTED; }
-
-zx_status_t FileReadAt(void* ctx, uint64_t count, uint64_t offset, fidl_txn_t* txn) {
-  Context* context = reinterpret_cast<Context*>(ctx);
-  if (!context->supports_read_at) {
-    return ZX_ERR_NOT_SUPPORTED;
-  }
-  if (offset >= context->content_size) {
-    return fuchsia_io_FileRead_reply(txn, ZX_OK, nullptr, 0);
-  }
-  size_t actual = std::min(count, context->content_size - offset);
-  uint8_t buffer[ZX_PAGE_SIZE];
-  zx_status_t status = context->vmo.read(buffer, offset, actual);
-  if (status != ZX_OK) {
-    return fuchsia_io_FileRead_reply(txn, status, nullptr, 0);
-  }
-  return fuchsia_io_FileRead_reply(txn, ZX_OK, buffer, actual);
-}
-
-zx_status_t FileWrite(void* ctx, const uint8_t* data_data, size_t data_count, fidl_txn_t* txn) {
-  return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t FileWriteAt(void* ctx, const uint8_t* data_data, size_t data_count, uint64_t offset,
-                        fidl_txn_t* txn) {
-  return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t FileSeek(void* ctx, int64_t offset, fuchsia_io_SeekOrigin start, fidl_txn_t* txn) {
-  Context* context = reinterpret_cast<Context*>(ctx);
-  if (!context->supports_seek) {
-    return ZX_ERR_NOT_SUPPORTED;
-  }
-  return fuchsia_io_FileSeek_reply(txn, ZX_OK, 0);
-}
-
-zx_status_t FileTruncate(void* ctx, uint64_t length, fidl_txn_t* txn) {
-  return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t FileGetFlags(void* ctx, fidl_txn_t* txn) { return ZX_ERR_NOT_SUPPORTED; }
-
-zx_status_t FileSetFlags(void* ctx, uint32_t flags, fidl_txn_t* txn) {
-  return ZX_ERR_NOT_SUPPORTED;
-}
-
-zx_status_t FileGetBuffer(void* ctx, uint32_t flags, fidl_txn_t* txn) {
-  Context* context = reinterpret_cast<Context*>(ctx);
-  context->last_flags = flags;
-
-  if (!context->supports_get_buffer) {
-    return fuchsia_io_FileGetBuffer_reply(txn, ZX_ERR_NOT_SUPPORTED, nullptr);
-  }
-
-  fuchsia_mem_Buffer buffer;
-  memset(&buffer, 0, sizeof(buffer));
-  buffer.size = context->content_size;
-
-  // TODO(fxb/37091): This should just have GET_PROPERTY, not SET_PROPERTY, but currently this
-  // mimics what most filesystems do.
-  zx_rights_t rights = ZX_RIGHTS_BASIC | ZX_RIGHT_MAP | ZX_RIGHTS_PROPERTY;
-  rights |= (flags & fuchsia_io_VMO_FLAG_READ) ? ZX_RIGHT_READ : 0;
-  rights |= (flags & fuchsia_io_VMO_FLAG_WRITE) ? ZX_RIGHT_WRITE : 0;
-  rights |= (flags & fuchsia_io_VMO_FLAG_EXEC) ? ZX_RIGHT_EXECUTE : 0;
-
-  zx_status_t status = ZX_OK;
-  zx::vmo result;
-  if (flags & fuchsia_io_VMO_FLAG_PRIVATE) {
-    uint32_t options = ZX_VMO_CHILD_COPY_ON_WRITE;
-    if (flags & fuchsia_io_VMO_FLAG_EXEC) {
-      // Creating a COPY_ON_WRITE child removes ZX_RIGHT_EXECUTE even if the parent VMO has it, but
-      // NO_WRITE changes this behavior so that the new handle doesn't have WRITE and preserves
-      // EXECUTE.
-      options |= ZX_VMO_CHILD_NO_WRITE;
+      status = result.replace(rights, &result);
+    } else {
+      status = context->vmo.duplicate(rights, &result);
     }
-    status = context->vmo.create_child(options, 0, ZX_PAGE_SIZE, &result);
     if (status != ZX_OK) {
-      return fuchsia_io_FileGetBuffer_reply(txn, status, nullptr);
+      return completer.Reply(status, nullptr);
     }
 
-    status = result.replace(rights, &result);
-  } else {
-    status = context->vmo.duplicate(rights, &result);
-  }
-  if (status != ZX_OK) {
-    return fuchsia_io_FileGetBuffer_reply(txn, status, nullptr);
+    buffer.vmo = std::move(result);
+    return completer.Reply(ZX_OK, &buffer);
   }
 
-  buffer.vmo = result.release();
-  return fuchsia_io_FileGetBuffer_reply(txn, ZX_OK, &buffer);
-}
-
-constexpr fuchsia_io_File_ops_t kFileOps = [] {
-  fuchsia_io_File_ops_t ops = {};
-  ops.Clone = FileClone;
-  ops.Close = FileClose;
-  ops.Describe = FileDescribe;
-  ops.Sync = FileSync;
-  ops.GetAttr = FileGetAttr;
-  ops.SetAttr = FileSetAttr;
-  ops.Read = FileRead;
-  ops.ReadAt = FileReadAt;
-  ops.Write = FileWrite;
-  ops.WriteAt = FileWriteAt;
-  ops.Seek = FileSeek;
-  ops.Truncate = FileTruncate;
-  ops.GetFlags = FileGetFlags;
-  ops.SetFlags = FileSetFlags;
-  ops.GetBuffer = FileGetBuffer;
-  return ops;
-}();
+ private:
+  Context* context;
+};
 
 zx_koid_t get_koid(const zx::object_base& handle) {
   zx_info_handle_basic_t info;
@@ -249,9 +221,7 @@
   create_context_vmo(ZX_PAGE_SIZE, &context.vmo);
   ASSERT_OK(context.vmo.write("abcd", 0, 4));
 
-  ASSERT_OK(fidl_bind(dispatcher, server.release(),
-                      reinterpret_cast<fidl_dispatch_t*>(fuchsia_io_File_dispatch), &context,
-                      &kFileOps));
+  ASSERT_OK(fidl::Bind(dispatcher, std::move(server), std::make_unique<TestServer>(&context)));
 
   int raw_fd = -1;
   ASSERT_OK(fdio_fd_create(client.release(), &raw_fd));
@@ -265,7 +235,7 @@
   EXPECT_OK(fdio_get_vmo_exact(fd.get(), received.reset_and_get_address()));
   EXPECT_EQ(get_koid(context.vmo), get_koid(received));
   EXPECT_EQ(get_rights(received), expected_rights);
-  EXPECT_EQ(fuchsia_io_VMO_FLAG_READ | fuchsia_io_VMO_FLAG_EXACT, context.last_flags);
+  EXPECT_EQ(fuchsia_io::VMO_FLAG_READ | fuchsia_io::VMO_FLAG_EXACT, context.last_flags);
   context.last_flags = 0;
 
   // The rest of these tests exercise methods which use VMO_FLAG_PRIVATE, in which case the returned
@@ -275,21 +245,21 @@
   EXPECT_OK(fdio_get_vmo_clone(fd.get(), received.reset_and_get_address()));
   EXPECT_NE(get_koid(context.vmo), get_koid(received));
   EXPECT_EQ(get_rights(received), expected_rights);
-  EXPECT_EQ(fuchsia_io_VMO_FLAG_READ | fuchsia_io_VMO_FLAG_PRIVATE, context.last_flags);
+  EXPECT_EQ(fuchsia_io::VMO_FLAG_READ | fuchsia_io::VMO_FLAG_PRIVATE, context.last_flags);
   EXPECT_TRUE(vmo_starts_with(received, "abcd"));
   context.last_flags = 0;
 
   EXPECT_OK(fdio_get_vmo_copy(fd.get(), received.reset_and_get_address()));
   EXPECT_NE(get_koid(context.vmo), get_koid(received));
   EXPECT_EQ(get_rights(received), expected_rights);
-  EXPECT_EQ(fuchsia_io_VMO_FLAG_READ | fuchsia_io_VMO_FLAG_PRIVATE, context.last_flags);
+  EXPECT_EQ(fuchsia_io::VMO_FLAG_READ | fuchsia_io::VMO_FLAG_PRIVATE, context.last_flags);
   EXPECT_TRUE(vmo_starts_with(received, "abcd"));
   context.last_flags = 0;
 
   EXPECT_OK(fdio_get_vmo_exec(fd.get(), received.reset_and_get_address()));
   EXPECT_NE(get_koid(context.vmo), get_koid(received));
   EXPECT_EQ(get_rights(received), expected_rights | ZX_RIGHT_EXECUTE);
-  EXPECT_EQ(fuchsia_io_VMO_FLAG_READ | fuchsia_io_VMO_FLAG_EXEC | fuchsia_io_VMO_FLAG_PRIVATE,
+  EXPECT_EQ(fuchsia_io::VMO_FLAG_READ | fuchsia_io::VMO_FLAG_EXEC | fuchsia_io::VMO_FLAG_PRIVATE,
             context.last_flags);
   EXPECT_TRUE(vmo_starts_with(received, "abcd"));
   context.last_flags = 0;
@@ -299,7 +269,7 @@
   EXPECT_OK(fdio_get_vmo_copy(fd.get(), received.reset_and_get_address()));
   EXPECT_NE(get_koid(context.vmo), get_koid(received));
   EXPECT_EQ(get_rights(received), expected_rights);
-  EXPECT_EQ(fuchsia_io_VMO_FLAG_READ | fuchsia_io_VMO_FLAG_PRIVATE, context.last_flags);
+  EXPECT_EQ(fuchsia_io::VMO_FLAG_READ | fuchsia_io::VMO_FLAG_PRIVATE, context.last_flags);
   EXPECT_TRUE(vmo_starts_with(received, "abcd"));
   context.last_flags = 0;
 }
@@ -319,9 +289,7 @@
   create_context_vmo(ZX_PAGE_SIZE, &context.vmo);
   ASSERT_OK(context.vmo.write("abcd", 0, 4));
 
-  ASSERT_OK(fidl_bind(dispatcher, server.release(),
-                      reinterpret_cast<fidl_dispatch_t*>(fuchsia_io_File_dispatch), &context,
-                      &kFileOps));
+  ASSERT_OK(fidl::Bind(dispatcher, std::move(server), std::make_unique<TestServer>(&context)));
 
   int raw_fd = -1;
   ASSERT_OK(fdio_fd_create(client.release(), &raw_fd));
@@ -373,9 +341,7 @@
   create_context_vmo(ZX_PAGE_SIZE, &context.vmo);
   ASSERT_OK(context.vmo.write("abcd", 0, 4));
 
-  ASSERT_OK(fidl_bind(dispatcher, server.release(),
-                      reinterpret_cast<fidl_dispatch_t*>(fuchsia_io_File_dispatch), &context,
-                      &kFileOps));
+  ASSERT_OK(fidl::Bind(dispatcher, std::move(server), std::make_unique<TestServer>(&context)));
 
   int raw_fd = -1;
   ASSERT_OK(fdio_fd_create(client.release(), &raw_fd));
@@ -387,7 +353,7 @@
   zx_vm_option_t zx_options = PROT_READ | PROT_EXEC;
   uintptr_t ptr;
   ASSERT_OK(_mmap_file(offset, len, zx_options, MAP_SHARED, fd.get(), fd_off, &ptr));
-  EXPECT_EQ(context.last_flags, fuchsia_io_VMO_FLAG_READ | fuchsia_io_VMO_FLAG_EXEC);
+  EXPECT_EQ(context.last_flags, fuchsia_io::VMO_FLAG_READ | fuchsia_io::VMO_FLAG_EXEC);
 }
 
 }  // namespace
diff --git a/zircon/system/utest/fdio/fdio_unsafe.cc b/zircon/system/utest/fdio/fdio_unsafe.cc
index 5c9f28a..910fa04 100644
--- a/zircon/system/utest/fdio/fdio_unsafe.cc
+++ b/zircon/system/utest/fdio/fdio_unsafe.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <fbl/unique_fd.h>
 #include <fcntl.h>
-#include <fuchsia/io/c/fidl.h>
+#include <fuchsia/io/llcpp/fidl.h>
 #include <lib/fdio/directory.h>
 #include <lib/fdio/unsafe.h>
 #include <lib/zx/channel.h>
 #include <unistd.h>
 
+#include <fbl/unique_fd.h>
 #include <zxtest/zxtest.h>
 
 TEST(UnsafeTest, BorrowChannel) {
@@ -24,7 +24,9 @@
 
   zx::channel h1, h2;
   ASSERT_OK(zx::channel::create(0, &h1, &h2));
-  ASSERT_OK(fuchsia_io_NodeClone(dir->get(), fuchsia_io_CLONE_FLAG_SAME_RIGHTS, h1.release()));
+  auto result = ::llcpp::fuchsia::io::Node::Call::Clone(
+      std::move(dir), ::llcpp::fuchsia::io::CLONE_FLAG_SAME_RIGHTS, std::move(h1));
+  ASSERT_OK(result.status());
 
   fdio_unsafe_release(io);
   fd.reset();