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