https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=ec36c59f1a9349e690849e393251623f5936408c

commit ec36c59f1a9349e690849e393251623f5936408c
Author: Corinna Vinschen <cori...@vinschen.de>
Date:   Tue Jan 8 21:37:43 2019 +0100

    Cygwin: open: workaround reopen file w/ delete disposition set
    
    On pre-W10 systems there's no way to reopen a file by handle if
    the delete disposition is set.  We try to get around with
    duplicating the handle.
    
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler.cc | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 9af08d7..9643373 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -693,6 +693,23 @@ fhandler_base::open (int flags, mode_t mode)
 
   status = NtCreateFile (&fh, access, &attr, &io, NULL, file_attributes, 
shared,
                         create_disposition, options, p, plen);
+  /* Pre-W10, we can't open a file by handle with delete disposition
+     set, so we have to lie our ass off. */
+  if (get_handle () && status == STATUS_DELETE_PENDING)
+    {
+      BOOL ret = DuplicateHandle (GetCurrentProcess (), get_handle (),
+                                 GetCurrentProcess (), &fh,
+                                 access, !(flags & O_CLOEXEC), 0);
+      if (!ret)
+       ret = DuplicateHandle (GetCurrentProcess (), get_handle (),
+                              GetCurrentProcess (), &fh,
+                              0, !(flags & O_CLOEXEC),
+                              DUPLICATE_SAME_ACCESS);
+      if (!ret)
+       debug_printf ("DuplicateHandle after STATUS_DELETE_PENDING, %E");
+      else
+       status = STATUS_SUCCESS;
+    }
   if (!NT_SUCCESS (status))
     {
       /* Trying to create a directory should return EISDIR, not ENOENT. */

Reply via email to