From 4b784d72ecffe5293f10baee314ff892d5ddc59b Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Thu, 16 Sep 2021 23:15:17 +0900
Subject: [PATCH v2 2/3] Cygwin: pipe: Fix error handling in
 fhandler_pip::create().

- Currently, error handling in fhandler_pipe::create() is broken.
  This patch fixes that.
---
 winsup/cygwin/fhandler.h       |   1 -
 winsup/cygwin/fhandler_pipe.cc | 101 ++++++++++++++++-----------------
 2 files changed, 48 insertions(+), 54 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 919655012..eb312ccb6 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1206,7 +1206,6 @@ public:
   fhandler_pipe ();
 
   bool ispipe() const { return true; }
-  void set_read_mutex (HANDLE mtx) { read_mtx = mtx; }
   void set_pipe_buf_size ();
 
   void set_popen_pid (pid_t pid) {popen_pid = pid;}
diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
index c2f4353f6..582b4d564 100644
--- a/winsup/cygwin/fhandler_pipe.cc
+++ b/winsup/cygwin/fhandler_pipe.cc
@@ -803,61 +803,56 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
 
   int ret = nt_create (sa, r, w, psize, &unique_id);
   if (ret)
-    __seterrno_from_win_error (ret);
-  else if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL)
     {
-      NtClose (r);
-      NtClose (w);
-    }
-  else if ((fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev)) == NULL)
-    {
-      delete fhs[0];
-      NtClose (r);
-      NtClose (w);
-    }
-  else
-    {
-      mode |= mode & O_TEXT ?: O_BINARY;
-      fhs[0]->init (r, FILE_CREATE_PIPE_INSTANCE | GENERIC_READ, mode,
-		    unique_id);
-      fhs[1]->init (w, FILE_CREATE_PIPE_INSTANCE | GENERIC_WRITE, mode,
-		    unique_id);
-      /* For the read side of the pipe, add a mutex.  See raw_read for the
-	 usage. */
-      HANDLE mtx = CreateMutexW (sa, FALSE, NULL);
-      if (!mtx)
-	{
-	  delete fhs[0];
-	  NtClose (r);
-	  delete fhs[1];
-	  NtClose (w);
-	}
-      else
-	{
-	  fhs[0]->set_read_mutex (mtx);
-	  res = 0;
-	}
-      fhs[0]->select_sem = CreateSemaphore (sa, 0, INT32_MAX, NULL);
-      if (fhs[0]->select_sem)
-	DuplicateHandle (GetCurrentProcess (), fhs[0]->select_sem,
-			 GetCurrentProcess (), &fhs[1]->select_sem,
-			 0, sa->bInheritHandle, DUPLICATE_SAME_ACCESS);
-      if (!DuplicateHandle (GetCurrentProcess (), r,
-			    GetCurrentProcess (), &fhs[1]->query_hdl,
-			    FILE_READ_DATA, sa->bInheritHandle, 0))
-	{
-	  CloseHandle (fhs[0]->select_sem);
-	  delete fhs[0];
-	  CloseHandle (r);
-	  CloseHandle (fhs[1]->select_sem);
-	  delete fhs[1];
-	  CloseHandle (w);
-	}
-      else
-	res = 0;
+      __seterrno_from_win_error (ret);
+      goto out;
     }
-
-  debug_printf ("%R = pipe([%p, %p], %d, %y)", res, fhs[0], fhs[1], psize, mode);
+  if ((fhs[0] = (fhandler_pipe *) build_fh_dev (*piper_dev)) == NULL)
+    goto err_close_rw_handle;
+  if ((fhs[1] = (fhandler_pipe *) build_fh_dev (*pipew_dev)) == NULL)
+    goto err_delete_fhs0;
+  mode |= mode & O_TEXT ?: O_BINARY;
+  fhs[0]->init (r, FILE_CREATE_PIPE_INSTANCE | GENERIC_READ, mode, unique_id);
+  fhs[1]->init (w, FILE_CREATE_PIPE_INSTANCE | GENERIC_WRITE, mode, unique_id);
+
+  /* For the read side of the pipe, add a mutex.  See raw_read for the
+     usage. */
+  fhs[0]->read_mtx = CreateMutexW (sa, FALSE, NULL);
+  if (!fhs[0]->read_mtx)
+    goto err_delete_fhs1;
+
+  fhs[0]->select_sem = CreateSemaphore (sa, 0, INT32_MAX, NULL);
+  if (!fhs[0]->select_sem)
+    goto err_close_read_mtx;
+  if (!DuplicateHandle (GetCurrentProcess (), fhs[0]->select_sem,
+			GetCurrentProcess (), &fhs[1]->select_sem,
+			0, sa->bInheritHandle, DUPLICATE_SAME_ACCESS))
+    goto err_close_select_sem0;
+
+  if (!DuplicateHandle (GetCurrentProcess (), r,
+			GetCurrentProcess (), &fhs[1]->query_hdl,
+			FILE_READ_DATA, sa->bInheritHandle, 0))
+    goto err_close_select_sem1;
+
+  res = 0;
+  goto out;
+
+err_close_select_sem1:
+  CloseHandle (fhs[1]->select_sem);
+err_close_select_sem0:
+  CloseHandle (fhs[0]->select_sem);
+err_close_read_mtx:
+  CloseHandle (fhs[0]->read_mtx);
+err_delete_fhs1:
+  delete fhs[1];
+err_delete_fhs0:
+  delete fhs[0];
+err_close_rw_handle:
+  NtClose (r);
+  NtClose (w);
+out:
+  debug_printf ("%R = pipe([%p, %p], %d, %y)",
+		res, fhs[0], fhs[1], psize, mode);
   return res;
 }
 
-- 
2.33.0

