- implement _dup, _dup2, and _pipe
- make max file descriptors 2048 to match MS - increase max file streams to match
This commit is contained in:
parent
ebe3c529b1
commit
1e23777ae5
|
@ -60,8 +60,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
|
||||||
#define WX_APPEND 0x20
|
#define WX_APPEND 0x20
|
||||||
#define WX_TEXT 0x80
|
#define WX_TEXT 0x80
|
||||||
|
|
||||||
/* FIXME: Make this dynamic */
|
#define MSVCRT_MAX_FILES 2048
|
||||||
#define MSVCRT_MAX_FILES 257
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
@ -73,8 +72,7 @@ MSVCRT_FILE MSVCRT__iob[3];
|
||||||
static int MSVCRT_fdstart = 3; /* first unallocated fd */
|
static int MSVCRT_fdstart = 3; /* first unallocated fd */
|
||||||
static int MSVCRT_fdend = 3; /* highest allocated fd */
|
static int MSVCRT_fdend = 3; /* highest allocated fd */
|
||||||
|
|
||||||
/* FIXME: make this dynamic */
|
static MSVCRT_FILE* MSVCRT_fstreams[2048];
|
||||||
static MSVCRT_FILE* MSVCRT_fstreams[1024];
|
|
||||||
static int MSVCRT_stream_idx;
|
static int MSVCRT_stream_idx;
|
||||||
|
|
||||||
/* INTERNAL: process umask */
|
/* INTERNAL: process umask */
|
||||||
|
@ -156,12 +154,9 @@ static void msvcrt_free_fd(int fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INTERNAL: Allocate an fd slot from a Win32 HANDLE */
|
/* INTERNAL: Allocate an fd slot from a Win32 HANDLE, starting from fd */
|
||||||
static int msvcrt_alloc_fd(HANDLE hand, int flag)
|
static int msvcrt_alloc_fd_from(HANDLE hand, int flag, int fd)
|
||||||
{
|
{
|
||||||
int fd = MSVCRT_fdstart;
|
|
||||||
|
|
||||||
TRACE(":handle (%p) allocating fd (%d)\n",hand,fd);
|
|
||||||
if (fd >= MSVCRT_MAX_FILES)
|
if (fd >= MSVCRT_MAX_FILES)
|
||||||
{
|
{
|
||||||
WARN(":files exhausted!\n");
|
WARN(":files exhausted!\n");
|
||||||
|
@ -171,12 +166,16 @@ static int msvcrt_alloc_fd(HANDLE hand, int flag)
|
||||||
MSVCRT_fdesc[fd].wxflag = WX_OPEN | (flag & (WX_DONTINHERIT | WX_APPEND | WX_TEXT));
|
MSVCRT_fdesc[fd].wxflag = WX_OPEN | (flag & (WX_DONTINHERIT | WX_APPEND | WX_TEXT));
|
||||||
|
|
||||||
/* locate next free slot */
|
/* locate next free slot */
|
||||||
if (fd == MSVCRT_fdend)
|
if (fd == MSVCRT_fdstart && fd == MSVCRT_fdend)
|
||||||
MSVCRT_fdstart = ++MSVCRT_fdend;
|
MSVCRT_fdstart = MSVCRT_fdend + 1;
|
||||||
else
|
else
|
||||||
while (MSVCRT_fdstart < MSVCRT_fdend &&
|
while (MSVCRT_fdstart < MSVCRT_fdend &&
|
||||||
MSVCRT_fdesc[MSVCRT_fdstart].handle != INVALID_HANDLE_VALUE)
|
MSVCRT_fdesc[MSVCRT_fdstart].handle != INVALID_HANDLE_VALUE)
|
||||||
MSVCRT_fdstart++;
|
MSVCRT_fdstart++;
|
||||||
|
/* update last fd in use */
|
||||||
|
if (fd >= MSVCRT_fdend)
|
||||||
|
MSVCRT_fdend = fd + 1;
|
||||||
|
TRACE("fdstart is %d, fdend is %d\n", MSVCRT_fdstart, MSVCRT_fdend);
|
||||||
|
|
||||||
switch (fd)
|
switch (fd)
|
||||||
{
|
{
|
||||||
|
@ -188,6 +187,13 @@ static int msvcrt_alloc_fd(HANDLE hand, int flag)
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* INTERNAL: Allocate an fd slot from a Win32 HANDLE */
|
||||||
|
static int msvcrt_alloc_fd(HANDLE hand, int flag)
|
||||||
|
{
|
||||||
|
TRACE(":handle (%p) allocating fd (%d)\n",hand,MSVCRT_fdstart);
|
||||||
|
return msvcrt_alloc_fd_from(hand, flag, MSVCRT_fdstart);
|
||||||
|
}
|
||||||
|
|
||||||
/* INTERNAL: Allocate a FILE* for an fd slot
|
/* INTERNAL: Allocate a FILE* for an fd slot
|
||||||
*/
|
*/
|
||||||
static MSVCRT_FILE* msvcrt_alloc_fp(void)
|
static MSVCRT_FILE* msvcrt_alloc_fp(void)
|
||||||
|
@ -498,24 +504,6 @@ int _chsize(int fd, long size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* _dup (MSVCRT.@)
|
|
||||||
*/
|
|
||||||
int _dup(int od)
|
|
||||||
{
|
|
||||||
FIXME("(od=%d): stub\n", od);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* _dup2 (MSVCRT.@)
|
|
||||||
*/
|
|
||||||
int _dup2(int od, int nd)
|
|
||||||
{
|
|
||||||
FIXME("(od=%d, nd=%d): stub\n", od, nd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _unlink (MSVCRT.@)
|
* _unlink (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -635,6 +623,68 @@ int _commit(int fd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _dup2 (MSVCRT.@)
|
||||||
|
* NOTES
|
||||||
|
* MSDN isn't clear on this point, but the remarks for _pipe,
|
||||||
|
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__pipe.asp
|
||||||
|
* indicate file descriptors duplicated with _dup and _dup2 are always
|
||||||
|
* inheritable.
|
||||||
|
*/
|
||||||
|
int _dup2(int od, int nd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
TRACE("(od=%d, nd=%d)\n", od, nd);
|
||||||
|
if (nd < MSVCRT_MAX_FILES && msvcrt_is_valid_fd(od))
|
||||||
|
{
|
||||||
|
HANDLE handle;
|
||||||
|
|
||||||
|
if (DuplicateHandle(GetCurrentProcess(), MSVCRT_fdesc[od].handle,
|
||||||
|
GetCurrentProcess(), &handle, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||||
|
{
|
||||||
|
int wxflag = MSVCRT_fdesc[od].wxflag & ~MSVCRT__O_NOINHERIT;
|
||||||
|
|
||||||
|
if (msvcrt_is_valid_fd(nd))
|
||||||
|
_close(nd);
|
||||||
|
ret = msvcrt_alloc_fd_from(handle, wxflag, nd);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
CloseHandle(handle);
|
||||||
|
*MSVCRT__errno() = MSVCRT_EMFILE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* _dup2 returns 0, not nd, on success */
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
msvcrt_set_errno(GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*MSVCRT__errno() = MSVCRT_EBADF;
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _dup (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int _dup(int od)
|
||||||
|
{
|
||||||
|
int fd = MSVCRT_fdstart;
|
||||||
|
|
||||||
|
if (_dup2(od, fd) == 0)
|
||||||
|
return fd;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _eof (MSVCRT.@)
|
* _eof (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -1188,6 +1238,59 @@ static unsigned split_oflags(unsigned oflags)
|
||||||
return wxflags;
|
return wxflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _pipe (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
int _pipe(int *pfds, unsigned int psize, int textmode)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
HANDLE readHandle, writeHandle;
|
||||||
|
|
||||||
|
if (!pfds)
|
||||||
|
{
|
||||||
|
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
sa.bInheritHandle = !(textmode & MSVCRT__O_NOINHERIT);
|
||||||
|
sa.lpSecurityDescriptor = NULL;
|
||||||
|
if (CreatePipe(&readHandle, &writeHandle, &sa, psize))
|
||||||
|
{
|
||||||
|
unsigned int wxflags = split_oflags(textmode);
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = msvcrt_alloc_fd(readHandle, wxflags);
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
pfds[0] = fd;
|
||||||
|
fd = msvcrt_alloc_fd(writeHandle, wxflags);
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
pfds[1] = fd;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_close(pfds[0]);
|
||||||
|
CloseHandle(writeHandle);
|
||||||
|
*MSVCRT__errno() = MSVCRT_EMFILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle(readHandle);
|
||||||
|
CloseHandle(writeHandle);
|
||||||
|
*MSVCRT__errno() = MSVCRT_EMFILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msvcrt_set_errno(GetLastError());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _sopen (MSVCRT.@)
|
* _sopen (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -403,7 +403,7 @@
|
||||||
@ cdecl _pclose (ptr) MSVCRT__pclose
|
@ cdecl _pclose (ptr) MSVCRT__pclose
|
||||||
@ extern _pctype MSVCRT__pctype
|
@ extern _pctype MSVCRT__pctype
|
||||||
@ extern _pgmptr MSVCRT__pgmptr
|
@ extern _pgmptr MSVCRT__pgmptr
|
||||||
@ stub _pipe #(ptr long long)
|
@ cdecl _pipe (ptr long long)
|
||||||
@ cdecl _popen (str str) MSVCRT__popen
|
@ cdecl _popen (str str) MSVCRT__popen
|
||||||
@ cdecl _purecall()
|
@ cdecl _purecall()
|
||||||
@ cdecl _putch(long)
|
@ cdecl _putch(long)
|
||||||
|
|
Loading…
Reference in New Issue