MSVCRT: implement dup2

Mike McCormack mike at codeweavers.com
Mon Jan 19 01:56:42 CST 2004


ChangeLog:
* implement msvcrt's dup2
-------------- next part --------------
Index: dlls/msvcrt/file.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/file.c,v
retrieving revision 1.62
diff -u -r1.62 file.c
--- dlls/msvcrt/file.c	13 Jan 2004 05:45:05 -0000	1.62
+++ dlls/msvcrt/file.c	19 Jan 2004 07:27:22 -0000
@@ -77,6 +77,8 @@
 #define MSVCRT_stdout      (MSVCRT__iob+STDOUT_FILENO)
 #define MSVCRT_stderr      (MSVCRT__iob+STDERR_FILENO)
 
+#define MSVCRT_INTERNAL_INHERIT 0x40000000
+
 static int MSVCRT_fdstart = 3; /* first unallocated fd */
 static int MSVCRT_fdend = 3; /* highest allocated fd */
 
@@ -146,21 +148,27 @@
 }
 
 /* INTERNAL: Allocate an fd slot from a Win32 HANDLE */
-static int msvcrt_alloc_fd(HANDLE hand, int flag)
+static int msvcrt_alloc_fd(HANDLE hand, int flag, int fd)
 {
-  int fd = MSVCRT_fdstart;
-
+  if( fd < 0 )
+    fd = MSVCRT_fdstart;
   TRACE(":handle (%p) allocating fd (%d)\n",hand,fd);
   if (fd >= MSVCRT_MAX_FILES)
   {
     WARN(":files exhausted!\n");
+    CloseHandle(hand);
     return -1;
   }
   MSVCRT_handles[fd] = hand;
   MSVCRT_flags[fd] = flag;
 
+  if (fd != MSVCRT_fdstart)
+  {
+    if (fd > MSVCRT_fdend )
+      MSVCRT_fdend = fd + 1;
+  }
   /* locate next free slot */
-  if (fd == MSVCRT_fdend)
+  else if (fd == MSVCRT_fdend)
     MSVCRT_fdstart = ++MSVCRT_fdend;
   else
     while(MSVCRT_fdstart < MSVCRT_fdend &&
@@ -401,8 +409,21 @@
  */
 int _dup2(int od, int nd)
 {
-    FIXME("(od=%d, nd=%d): stub\n", od, nd);
-    return -1;
+    HANDLE hand;
+    BOOL inherit = FALSE;
+
+    TRACE("(od=%d, nd=%d): stub\n", od, nd);
+
+    hand = msvcrt_fdtoh(od);
+    if (hand==INVALID_HANDLE_VALUE)
+        return -1;
+    if (MSVCRT_flags[od]&MSVCRT_INTERNAL_INHERIT)
+        inherit = TRUE;
+    if (!DuplicateHandle(GetCurrentProcess(),hand,GetCurrentProcess(),
+                           &hand,inherit,FALSE,DUPLICATE_SAME_ACCESS))
+        return -1;
+    _close(nd);
+    return msvcrt_alloc_fd(hand,MSVCRT_flags[od],nd);
 }
 
 /*********************************************************************
@@ -1055,7 +1076,12 @@
 
   sa.nLength              = sizeof( SECURITY_ATTRIBUTES );
   sa.lpSecurityDescriptor = NULL;
-  sa.bInheritHandle       = (oflags & _O_NOINHERIT) ? FALSE : TRUE;
+  sa.bInheritHandle       = FALSE;
+  if (oflags & _O_NOINHERIT)
+  {
+      sa.bInheritHandle   = TRUE;
+      ioflag |= MSVCRT_INTERNAL_INHERIT;
+  }
 
   hand = CreateFileA(path, access, sharing,
                       &sa, creation, FILE_ATTRIBUTE_NORMAL, 0);
@@ -1066,7 +1092,7 @@
     return -1;
   }
 
-  fd = msvcrt_alloc_fd(hand, ioflag);
+  fd = msvcrt_alloc_fd(hand, ioflag, -1);
 
   TRACE(":fd (%d) handle (%p)\n",fd, hand);
 
@@ -1184,7 +1210,7 @@
   flags |= MSVCRT__IOREAD|MSVCRT__IOWRT;
   if ( !( flags & _O_TEXT ) ) flags |= _O_BINARY;
 
-  fd = msvcrt_alloc_fd((HANDLE)hand,flags);
+  fd = msvcrt_alloc_fd((HANDLE)hand,flags,-1);
   TRACE(":handle (%ld) fd (%d) flags 0x%08x\n",hand,fd, flags);
   return fd;
 }


More information about the wine-patches mailing list