[term] Replace PTY open_at with FIDL interface

This change is due to open_at being deprecated. All PTY clients should
be opened via the new FIDL interface.

Change-Id: I6a8bded83e8fa3974ce2572926253402ceefb3e4
diff --git a/app/term/pty_server.cc b/app/term/pty_server.cc
index 475e8a0..e9d74f4 100644
--- a/app/term/pty_server.cc
+++ b/app/term/pty_server.cc
@@ -5,17 +5,17 @@
 #include "topaz/app/term/pty_server.h"
 
 #include <fcntl.h>
+
 #include <fuchsia/hardware/pty/c/fidl.h>
+#include <lib/async/default.h>
+#include <lib/fdio/fd.h>
 #include <lib/fdio/io.h>
 #include <lib/fdio/private.h>
 #include <lib/fdio/spawn.h>
-#include <lib/async/default.h>
-#include <poll.h>
-#include <unistd.h>
+#include <lib/zx/channel.h>
+#include <src/lib/fxl/logging.h>
 #include <zircon/status.h>
 
-#include "src/lib/fxl/logging.h"
-
 namespace term {
 namespace {
 
@@ -40,13 +40,14 @@
 
 void PTYServer::SetWindowSize(uint32_t width, uint32_t height) {
   fuchsia_hardware_pty_WindowSize window = {
-    .width = width,
-    .height = height,
+      .width = width,
+      .height = height,
   };
 
   fdio_t* io = fdio_unsafe_fd_to_io(pty_.get());
   zx_status_t status;
-  fuchsia_hardware_pty_DeviceSetWindowSize(fdio_unsafe_borrow_channel(io), &window, &status);
+  fuchsia_hardware_pty_DeviceSetWindowSize(fdio_unsafe_borrow_channel(io),
+                                           &window, &status);
   fdio_unsafe_release(io);
 }
 
@@ -55,12 +56,45 @@
                            TerminationCallback termination_callback) {
   FXL_DCHECK(!command.empty());
 
-  int client_fd = openat(pty_.get(), "0", O_RDWR | O_NONBLOCK);
-  if (client_fd < 0) {
-    FXL_LOG(ERROR) << "Failed to create client pty: " << strerror(errno);
-    return ZX_ERR_NOT_FOUND;
+  fdio_t* io = fdio_unsafe_fd_to_io(pty_.get());
+  if (!io) {
+    FXL_LOG(ERROR)
+        << "Failed to create client PTY: couldn't make PTMX fdio connection";
+    return ZX_ERR_INTERNAL;
   }
 
+  zx::channel device_channel, client_channel;
+  zx_status_t status = zx::channel::create(0, &device_channel, &client_channel);
+  if (status != ZX_OK) {
+    FXL_LOG(ERROR) << "Failed to create client PTY channels: "
+                   << zx_status_get_string(status);
+    return status;
+  }
+
+  zx_status_t fidl_status = fuchsia_hardware_pty_DeviceOpenClient(
+      fdio_unsafe_borrow_channel(io), 1 /* client id */,
+      device_channel.release(), &status);
+  fdio_unsafe_release(io);
+  if (fidl_status != ZX_OK) {
+    FXL_LOG(ERROR) << "Failed to create client PTY (FIDL error): "
+                   << zx_status_get_string(fidl_status);
+    return fidl_status;
+  }
+  if (status != ZX_OK) {
+    FXL_LOG(ERROR) << "Failed to create client PTY: "
+                   << zx_status_get_string(status);
+    return status;
+  }
+
+  int client_fd;
+  status = fdio_fd_create(client_channel.release(), &client_fd);
+  if (status != ZX_OK) {
+    FXL_LOG(ERROR) << "Failed to create client PTY FD: "
+                   << zx_status_get_string(status);
+    return status;
+  }
+  fcntl(client_fd, F_SETFL, O_NONBLOCK);
+
   fdio_spawn_action_t action;
   action.action = FDIO_SPAWN_ACTION_TRANSFER_FD;
   action.fd.local_fd = client_fd;
@@ -70,7 +104,7 @@
 
   zx_handle_t proc;
   char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
-  zx_status_t status = fdio_spawn_etc(
+  status = fdio_spawn_etc(
       ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO,
       argv[0], argv.data(), nullptr, 1, &action, &proc, err_msg);
   if (status != ZX_OK) {