* Copyright 2004 Eric Pouech
* Copyright 2004 Juan Lang
*/
-
+
// rember to interlock the allocation of fileno when making this thread safe
// possibly store extra information at the handle
inline BOOL is_valid_fd(int fd)
{
BOOL b = (fd >= 0 && fd < g_fdend && (fdinfo(fd)->fdflags & FOPEN));
-
+
if (!b){
- DPRINT1("not valid fd %i, g_fdend %i, fdinfo %x, bucket %x, fdflags %x\n",
- fd,g_fdend,fdinfo(fd),fdinfo_bucket(fd),fdinfo(fd)->fdflags);
-
+ if (fd >= 0 && fd < g_fdend)
+ {
+ DPRINT1("not valid fd %i, g_fdend %i, fdinfo %x, bucket %x, fdflags %x\n",
+ fd,g_fdend,fdinfo(fd),fdinfo_bucket(fd),fdinfo(fd)->fdflags);
+ }
+ else
+ {
+ DPRINT1("not valid fd %i, g_fdend %i\n",fd,g_fdend);
+ }
+
}
-
+
return b;
}
char fdflags = 0;
if (oflags & _O_APPEND) fdflags |= FAPPEND;
-
+
if (oflags & _O_BINARY) ;
else if (oflags & _O_TEXT) fdflags |= FTEXT;
else if (_fmode& _O_BINARY) ;
else fdflags |= FTEXT; /* default to TEXT*/
-
+
if (oflags & _O_NOINHERIT) fdflags |= FNOINHERIT;
if (oflags & ~(_O_BINARY|_O_TEXT|_O_APPEND|_O_TRUNC|
hFile = CreateFileA(_path,
dwDesiredAccess,
- dwShareMode,
+ dwShareMode,
&sa,
dwCreationDistribution,
dwFlagsAndAttributes,
static void init_bucket(FDINFO* entry)
{
int i;
-
- for(i=0;
- i < FDINFO_ENTRIES_PER_BUCKET;
+
+ for(i=0;
+ i < FDINFO_ENTRIES_PER_BUCKET;
i++, entry++)
{
entry->hFile = INVALID_HANDLE_VALUE;
{
fdinfo_bucket(fd) = malloc(FDINFO_ENTRIES_PER_BUCKET * sizeof(FDINFO));
if (!fdinfo_bucket(fd)) return FALSE;
-
+
init_bucket(fdinfo_bucket(fd));
-
+
return TRUE;
}
-/*
+/*
* INTERNAL
* Allocate an fd slot from a Win32 HANDLE, starting from fd
* caller must hold the files lock
*/
static int alloc_fd_from(HANDLE hand, char flag, int fd)
{
-
+
if (fd >= FDINFO_ENTRIES)
{
DPRINT1("files exhausted!\n");
return -1;
}
-
+
if (!fdinfo_bucket(fd))
{
if (!alloc_init_bucket(fd)){
return -1;
}
}
-
+
fdinfo(fd)->hFile = hand;
fdinfo(fd)->fdflags = FOPEN | (flag & (FNOINHERIT | FAPPEND | FTEXT));
- fdinfo(fd)->pipechar = LF;
+ fdinfo(fd)->pipechar = LF;
fdinfo(fd)->lockinitflag = 0;
//fdinfo(fd)->lock
{
g_fdstart++;
}
-#endif
+#endif
}
-
+
/* update last fd in use */
if (fd >= g_fdend)
g_fdend = fd + 1;
}
-/*
- * INTERNAL: Allocate an fd slot from a Win32 HANDLE
+/*
+ * INTERNAL: Allocate an fd slot from a Win32 HANDLE
*/
int alloc_fd(HANDLE hand, char flag)
{
int ret;
LOCK_FILES();
-
+
// TRACE(":handle (%p) allocating fd (%d)\n",hand,MSVCRT_fdstart);
ret = alloc_fd_from(hand, flag, g_fdstart);
-
+
UNLOCK_FILES();
return ret;
}
void free_fd(int fd)
{
LOCK_FILES();
-
-
+
+
fdinfo(fd)->hFile = INVALID_HANDLE_VALUE;
fdinfo(fd)->fdflags = 0;
-
+
if (fd < 3) /* don't use 0,1,2 for user files */
{
switch (fd)
{
if (fd == g_fdend - 1)
g_fdend--;
-
+
if (fd < g_fdstart)
g_fdstart = fd;
}
-
+
UNLOCK_FILES();
}
The _open_osfhandle() function in MSVCRT is expected to take the absence
of either _O_TEXT or _O_BINARY to mean _O_BINARY. Currently it defaults to
_O_TEXT.
-
+
An example of this is MFC's CStdioFile::Open in binary mode - it passes flags
of 0 when it wants to write a binary file - under WINE we do text mode conversions!
-
+
The attached patch ensures that _O_BINARY is set if neither is set in the passed-in
flags.
long _get_osfhandle(int fd)
{
TRACE("_get_osfhandle(%i)",fd);
-
+
if (!is_valid_fd(fd)) {
return( -1 );
}
{
HANDLE hProcess;
BOOL result;
-
+
if (handle1 >= FDINFO_ENTRIES || handle1 < 0 || handle2 >= FDINFO_ENTRIES || handle2 < 0) {
__set_errno(EBADF);
return -1;
}
// if (_pioinfo[handle1]->fd == -1) {
- if (fdinfo(handle1)->hFile == INVALID_HANDLE_VALUE) {
+ if (fdinfo(handle1)->hFile == INVALID_HANDLE_VALUE) {
__set_errno(EBADF);
return -1;
}
if (handle1 == handle2)
return handle1;
// if (_pioinfo[handle2]->fd != -1) {
- if (fdinfo(handle2)->hFile != INVALID_HANDLE_VALUE) {
+ if (fdinfo(handle2)->hFile != INVALID_HANDLE_VALUE) {
_close(handle2);
}
hProcess = GetCurrentProcess();
- result = DuplicateHandle(hProcess,
- fdinfo(handle1)->hFile,
- hProcess,
- &fdinfo(handle2)->hFile,
- 0,
- TRUE,
+ result = DuplicateHandle(hProcess,
+ fdinfo(handle1)->hFile,
+ hProcess,
+ &fdinfo(handle2)->hFile,
+ 0,
+ fdinfo(handle1)->fdflags & FNOINHERIT ? FALSE : TRUE,
DUPLICATE_SAME_ACCESS);
if (result) {
// _pioinfo[handle2]->fd = handle2;
SetStdHandle(STD_ERROR_HANDLE, fdinfo(handle2)->hFile);
break;
}
-
+
return handle1;
} else {
__set_errno(EMFILE); // Is this the correct error no.?
init_bucket(first_bucket);
GetStartupInfoA(&si);
-
+
if (si.cbReserved2 != 0 && si.lpReserved2 != NULL)
{
char* fdflags_ptr;
return FALSE;
}
}
-
+
if ((*fdflags_ptr & FOPEN) && *handle_ptr != INVALID_HANDLE_VALUE)
{
fdinfo(i)->fdflags = *fdflags_ptr;
fdinfo(i)->fdflags = 0;
fdinfo(i)->hFile = INVALID_HANDLE_VALUE;
}
-*/
+*/
fdflags_ptr++; handle_ptr++;
}
for (g_fdstart = 3; g_fdstart < g_fdend; g_fdstart++)
if (fdinfo(g_fdstart)->hFile == INVALID_HANDLE_VALUE) break;
}
-
+
InitializeCriticalSection(&g_file_cs);
if (fdinfo(0)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(0)->fdflags & FOPEN)) {
fdinfo(0)->hFile = GetStdHandle(STD_INPUT_HANDLE);
+ if (fdinfo(0)->hFile == NULL)
+ fdinfo(0)->hFile = INVALID_HANDLE_VALUE;
fdinfo(0)->fdflags = FOPEN|FTEXT;
}
if (fdinfo(1)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(1)->fdflags & FOPEN)) {
fdinfo(1)->hFile = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (fdinfo(1)->hFile == NULL)
+ fdinfo(1)->hFile = INVALID_HANDLE_VALUE;
fdinfo(1)->fdflags = FOPEN|FTEXT;
}
if (fdinfo(2)->hFile == INVALID_HANDLE_VALUE || !(fdinfo(2)->fdflags & FOPEN)) {
fdinfo(2)->hFile = GetStdHandle(STD_ERROR_HANDLE);
+ if (fdinfo(2)->hFile == NULL)
+ fdinfo(2)->hFile = INVALID_HANDLE_VALUE;
fdinfo(2)->fdflags = FOPEN|FTEXT;
}
HANDLE* handle_ptr;
TRACE("create_io_inherit_block(%x)",si);
-
+
si->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * g_fdend;
si->lpReserved2 = calloc(si->cbReserved2, 1);
if (!si->lpReserved2)
*handle_ptr = INVALID_HANDLE_VALUE;
}
fdflags_ptr++; handle_ptr++;
- }
+ }
return( TRUE );
}
int _setmode(int fd, int newmode)
{
int prevmode;
-
+
TRACE("_setmode(%d, %d)", fd, newmode);
-
+
if (!is_valid_fd(fd))
{
DPRINT1("_setmode: inval fd (%d)\n",fd);
//errno = EBADF;
return(-1);
}
-
+
if (newmode & ~(_O_TEXT|_O_BINARY))
{
DPRINT1("_setmode: fd (%d) mode (0x%08x) unknown\n",fd,newmode);
}
prevmode = fdinfo(fd)->fdflags & FTEXT ? _O_TEXT : _O_BINARY;
-
+
if ((newmode & _O_TEXT) == _O_TEXT)
{
fdinfo(fd)->fdflags |= FTEXT;
*/
fdinfo(fd)->fdflags &= ~FTEXT;
}
-
+
return(prevmode);
}