[pty] Use ptysvc to get new pty servers
Bug: 33204
Change-Id: I4e915e4003b92fab1530c13b2e2ab9e571d4cb1e
diff --git a/sshpty.c b/sshpty.c
index 4a40a4a..aa84a6e 100644
--- a/sshpty.c
+++ b/sshpty.c
@@ -57,7 +57,52 @@
#ifdef __Fuchsia__
#include <fuchsia/hardware/pty/c/fidl.h>
+#include <lib/fdio/directory.h>
+#include <lib/fdio/fd.h>
#include <lib/fdio/unsafe.h>
+#include <zircon/status.h>
+#include <zircon/syscalls.h>
+#endif // __Fuchsia__
+
+#ifdef __Fuchsia__
+static int fuchsia_get_new_pty_server(void) {
+ zx_handle_t local, remote;
+ zx_status_t status = zx_channel_create(0, &local, &remote);
+ int fd = -1;
+ if (status != ZX_OK) {
+ error("channel create failed: %s", zx_status_get_string(status));
+ goto bail;
+ }
+ status = fdio_service_connect("/svc/fuchsia.hardware.pty.Device", remote);
+ remote = ZX_HANDLE_INVALID;
+ if (status != ZX_OK) {
+ error("fdio_service_connect failed: %s", zx_status_get_string(status));
+ goto bail;
+ }
+
+ status = fdio_fd_create(local, &fd);
+ local = ZX_HANDLE_INVALID;
+ if (status != ZX_OK) {
+ error("fdio_service_connect failed: %s", zx_status_get_string(status));
+ goto bail;
+ }
+ int flags = fcntl(fd, F_GETFL);
+ if (flags < 0) {
+ error("fcntl(F_GETFL): %s", strerror(errno));
+ goto bail;
+ }
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ error("fcntl(F_SETFL): %s", strerror(errno));
+ goto bail;
+ }
+ return fd;
+
+bail:
+ zx_handle_close(local);
+ zx_handle_close(remote);
+ close(fd);
+ return -1;
+}
#endif // __Fuchsia__
/*
@@ -71,9 +116,8 @@
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
#ifdef __Fuchsia__
- *ptyfd = open("/dev/misc/ptmx", O_RDWR | O_NONBLOCK);
+ *ptyfd = fuchsia_get_new_pty_server();
if (*ptyfd < 0) {
- error("open /dev/misc/ptmx: %s", strerror(errno));
return 0;
}
*ttyfd = fuchsia_open_pty_client(*ptyfd, 0);