From 59cbb9a659cea3dc4746fdfb441a7b845a58c933 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Mon, 10 Feb 2020 15:56:33 +0100
Subject: [PATCH] I/O [NT]: Fixed multiple isses with debug_fd_openpty().

* The ptys were closed again immediately after creation.
  This was due to a missing return statement.

* The fds were not released from the locks from allocate_fd().
  This caused the fd_close() above to hang.

* The return value was not set properly.

* The errno was not set properly on win32-api failure.
---
 src/fdlib.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/fdlib.c b/src/fdlib.c
index 26d6d16c04..87f7e413fc 100644
--- a/src/fdlib.c
+++ b/src/fdlib.c
@@ -2812,10 +2812,10 @@ PMOD_EXPORT int debug_fd_openpty(int *master, int *slave,
   if (slave_fd < 0) goto fail;
 
   if (!CreatePipe(&master_pty->write_pipe, &slave_pty->read_pipe, NULL, 0)) {
-    goto fail;
+    goto win32_fail;
   }
   if (!CreatePipe(&slave_pty->write_pipe, &master_pty->read_pipe, NULL, 0)) {
-    goto fail;
+    goto win32_fail;
   }
 
   /* Some reasonable defaults. */
@@ -2830,19 +2830,37 @@ PMOD_EXPORT int debug_fd_openpty(int *master, int *slave,
   if (FAILED(Pike_NT_CreatePseudoConsole(sz, slave_pty->write_pipe,
 					 slave_pty->read_pipe,
 					 0, &master_pty->conpty))) {
-    goto fail;
+    goto win32_fail;
   }
 
+  release_fd(master_fd);
+  release_fd(slave_fd);
+
+  return 0;
+
+ win32_fail:
+    set_errno_from_win32_error(GetLastError());
+
  fail:
   /* NB: Order significant!
    *
    * In the case where master_fd >= 0 and slave_fd < 0, the
    * slave_pty must not have been freed when master_fd is closed.
    */
-  if (master_fd >= 0) fd_close(master_fd);
-  else if (master_pty) free(master_pty);
-  if (slave_fd >= 0) fd_close(slave_fd);
-  else if (slave_pty) free(slave_pty);
+  if (master_fd >= 0) {
+    release_fd(master_fd);
+    fd_close(master_fd);
+  } else if (master_pty) {
+    free(master_pty);
+  }
+  if (slave_fd >= 0) {
+    release_fd(slave_fd);
+    fd_close(slave_fd);
+  } else if (slave_pty) {
+    free(slave_pty);
+  }
+
+  return -1;
 }
 
 #ifdef EMULATE_DIRECT
-- 
GitLab