Started piping implementation.

svn path=/trunk/; revision=2927
This commit is contained in:
Hartmut Birr 2002-05-07 22:31:26 +00:00
parent f88bb45115
commit eb12656476
7 changed files with 421 additions and 152 deletions

View file

@ -1,8 +1,33 @@
/* $Id: dup.c,v 1.2 2002/05/07 22:31:25 hbirr Exp $ */
#include <windows.h>
#include <msvcrt/io.h>
#include <msvcrt/internal/file.h>
int _dup(int handle)
{
return __fileno_alloc(_get_osfhandle(handle), __fileno_getmode(handle));
HANDLE hFile;
HANDLE hProcess = GetCurrentProcess();
BOOL result;
int fd;
hFile = _get_osfhandle(handle);
if (hFile == INVALID_HANDLE_VALUE)
return -1;
result = DuplicateHandle(hProcess,
hFile,
hProcess,
&hFile,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if (result == FALSE)
return -1;
fd = __fileno_alloc(hFile, __fileno_getmode(handle));
if (fd < 0)
{
CloseHandle(hFile);
}
return fd;
}

View file

@ -1,4 +1,5 @@
/*
/* $Id: open.c,v 1.8 2002/05/07 22:31:25 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crtdll/io/open.c
@ -28,6 +29,9 @@
#define NDEBUG
#include <msvcrt/msvcrtdbg.h>
#define STD_AUX_HANDLE 3
#define STD_PRINTER_HANDLE 4
typedef struct _fileno_modes_type
{
HANDLE hFile;
@ -37,8 +41,7 @@ typedef struct _fileno_modes_type
fileno_modes_type *fileno_modes = NULL;
int maxfno = 5;
int minfno = 5;
int maxfno = 0;
char __is_text_file(FILE *p)
{
@ -60,6 +63,7 @@ int _open(const char *_path, int _oflag,...)
DWORD dwCreationDistribution = 0;
DWORD dwFlagsAndAttributes = 0;
DWORD dwLastError;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
#if !defined(NDEBUG) && defined(DBG)
va_start(arg, _oflag);
@ -127,10 +131,13 @@ int _open(const char *_path, int _oflag,...)
DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
}
if (_oflag & _O_NOINHERIT)
sa.bInheritHandle = FALSE;
hFile = CreateFileA(_path,
dwDesiredAccess,
dwShareMode,
NULL,
&sa,
dwCreationDistribution,
dwFlagsAndAttributes,
NULL);
@ -150,6 +157,10 @@ int _open(const char *_path, int _oflag,...)
return -1;
}
DPRINT("OK\n");
if (!(_oflag & (_O_TEXT|_O_BINARY)))
{
_oflag |= _fmode;
}
return __fileno_alloc(hFile,_oflag);
}
@ -165,6 +176,7 @@ int _wopen(const wchar_t *_path, int _oflag,...)
DWORD dwShareMode = 0;
DWORD dwCreationDistribution = 0;
DWORD dwFlagsAndAttributes = 0;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
#if !defined(NDEBUG) && defined(DBG)
va_start(arg, _oflag);
@ -230,10 +242,13 @@ int _wopen(const wchar_t *_path, int _oflag,...)
if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
if (_oflag & _O_NOINHERIT)
sa.bInheritHandle = FALSE;
hFile = CreateFileW(_path,
dwDesiredAccess,
dwShareMode,
NULL,
&sa,
dwCreationDistribution,
dwFlagsAndAttributes,
NULL);
@ -251,7 +266,7 @@ __fileno_alloc(HANDLE hFile, int mode)
if (hFile < 0)
return -1;
for(i=minfno;i<maxfno;i++) {
for(i=5;i<maxfno;i++) {
if (fileno_modes[i].fd == -1 ) {
fileno_modes[i].fd = i;
fileno_modes[i].mode = mode;
@ -273,7 +288,7 @@ __fileno_alloc(HANDLE hFile, int mode)
memcpy(fileno_modes, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
free ( old_fileno_modes );
}
memset(fileno_modes + oldcount, -1, (maxfno-oldcount)*sizeof(fileno_modes));
memset(fileno_modes + oldcount, -1, (maxfno-oldcount)*sizeof(fileno_modes_type));
}
/* Fill in the value */
@ -285,61 +300,80 @@ __fileno_alloc(HANDLE hFile, int mode)
void *filehnd(int fileno)
{
if ( fileno < 0 )
return (void *)-1;
#define STD_AUX_HANDLE 3
#define STD_PRINTER_HANDLE 4
switch(fileno)
if ( fileno < 0 || fileno>= maxfno || fileno_modes[fileno].fd == -1)
{
case 0:
return GetStdHandle(STD_INPUT_HANDLE);
case 1:
return GetStdHandle(STD_OUTPUT_HANDLE);
case 2:
return GetStdHandle(STD_ERROR_HANDLE);
case 3:
return GetStdHandle(STD_AUX_HANDLE);
case 4:
return GetStdHandle(STD_PRINTER_HANDLE);
default:
break;
return (void *)-1;
}
if ( fileno >= maxfno )
return (void *)-1;
if ( fileno_modes[fileno].fd == -1 )
return (void *)-1;
return fileno_modes[fileno].hFile;
}
int __fileno_dup2( int handle1, int handle2 )
{
if ( handle1 >= maxfno )
HANDLE hProcess;
BOOL result;
if (handle1 >= maxfno || handle1 < 0 || handle2 >= maxfno || handle2 < 0 )
{
__set_errno(EBADF);
return -1;
if ( handle1 < 0 )
}
if (fileno_modes[handle1].fd == -1)
{
__set_errno(EBADF);
return -1;
if ( handle2 >= maxfno )
return -1;
if ( handle2 < 0 )
return -1;
memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes));
}
if (handle1 == handle2)
return handle1;
if (fileno_modes[handle2].fd != -1)
{
_close(handle2);
}
hProcess = GetCurrentProcess();
result = DuplicateHandle(hProcess,
fileno_modes[handle1].hFile,
hProcess,
&fileno_modes[handle2].hFile,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
if (result)
{
fileno_modes[handle2].fd = handle2;
fileno_modes[handle2].mode = fileno_modes[handle1].mode;
switch (handle2)
{
case 0:
SetStdHandle(STD_INPUT_HANDLE, fileno_modes[handle2].hFile);
break;
case 1:
SetStdHandle(STD_OUTPUT_HANDLE, fileno_modes[handle2].hFile);
break;
case 2:
SetStdHandle(STD_ERROR_HANDLE, fileno_modes[handle2].hFile);
break;
case 3:
SetStdHandle(STD_AUX_HANDLE, fileno_modes[handle2].hFile);
break;
case 4:
SetStdHandle(STD_AUX_HANDLE, fileno_modes[handle2].hFile);
break;
}
return handle1;
}
else
{
__set_errno(EMFILE); // Is this the correct error no.?
return -1;
}
}
int __fileno_setmode(int _fd, int _newmode)
{
int m;
if ( _fd < minfno )
return -1;
if ( _fd >= maxfno )
if ( _fd < 0 || _fd >= maxfno )
{
__set_errno(EBADF);
return -1;
}
m = fileno_modes[_fd].mode;
fileno_modes[_fd].mode = _newmode;
@ -348,24 +382,22 @@ int __fileno_setmode(int _fd, int _newmode)
int __fileno_getmode(int _fd)
{
if ( _fd < minfno )
if ( _fd < 0 || _fd >= maxfno )
{
__set_errno(EBADF);
return -1;
if ( _fd >= maxfno )
return -1;
}
return fileno_modes[_fd].mode;
}
int __fileno_close(int _fd)
{
if ( _fd < 0 )
return -1;
if ( _fd >= maxfno )
if ( _fd < 0 || _fd >= maxfno )
{
__set_errno(EBADF);
return -1;
}
fileno_modes[_fd].fd = -1;
fileno_modes[_fd].hFile = (HANDLE)-1;
@ -381,3 +413,78 @@ void *_get_osfhandle( int fileno )
{
return filehnd(fileno);
}
void __fileno_init(void)
{
ULONG count = 0, i;
HANDLE *pFile;
char* pmode;
STARTUPINFO StInfo;
GetStartupInfoA(&StInfo);
if (StInfo.lpReserved2 && StInfo.cbReserved2 >= sizeof(ULONG))
{
count = *(ULONG*)StInfo.lpReserved2;
/*
if (sizeof(ULONG) + count * (sizeof(HANDLE) + sizeof(char)) != StInfo.cbReserved2)
{
count = 0;
}
*/
}
maxfno = 255;
while(count >= maxfno)
maxfno += 255;
fileno_modes = (fileno_modes_type*)malloc(sizeof(fileno_modes_type) * maxfno);
memset(fileno_modes, -1, sizeof(fileno_modes_type) * maxfno);
if (count)
{
pFile = (HANDLE*)(StInfo.lpReserved2 + sizeof(ULONG) + count * sizeof(char));
pmode = (char*)(StInfo.lpReserved2 + sizeof(ULONG));
for (i = 0; i < count; i++)
{
if (*pFile != INVALID_HANDLE_VALUE)
{
fileno_modes[i].fd = i;
fileno_modes[i].mode = ((*pmode << 8) & (_O_TEXT|_O_BINARY)) | (*pmode & _O_ACCMODE);
fileno_modes[i].hFile = *pFile;
}
pFile++;
pmode++;
}
}
if (fileno_modes[0].fd == -1)
{
fileno_modes[0].fd = 0;
fileno_modes[0].hFile = GetStdHandle(STD_INPUT_HANDLE);
fileno_modes[0].mode = _O_RDONLY|_O_TEXT;
}
if (fileno_modes[1].fd == -1)
{
fileno_modes[1].fd = 1;
fileno_modes[1].hFile = GetStdHandle(STD_OUTPUT_HANDLE);
fileno_modes[1].mode = _O_WRONLY|_O_TEXT;
}
if (fileno_modes[2].fd == -1)
{
fileno_modes[2].fd = 2;
fileno_modes[2].hFile = GetStdHandle(STD_ERROR_HANDLE);
fileno_modes[2].mode = _O_WRONLY|_O_TEXT;
}
if (fileno_modes[3].fd == -1)
{
fileno_modes[3].fd = 3;
fileno_modes[3].hFile = GetStdHandle(STD_AUX_HANDLE);
fileno_modes[3].mode = _O_WRONLY|_O_TEXT;
}
if (fileno_modes[4].fd == -1)
{
fileno_modes[4].fd = 4;
fileno_modes[4].hFile = GetStdHandle(STD_PRINTER_HANDLE);
fileno_modes[4].mode = _O_WRONLY|_O_TEXT;
}
}

View file

@ -1,4 +1,5 @@
/*
/* $Id: pipe.c,v 1.2 2002/05/07 22:31:25 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crtdll/io/pipe.c
@ -9,18 +10,36 @@
*/
#include <windows.h>
#include <msvcrt/io.h>
#include <msvcrt/errno.h>
#include <msvcrt/internal/file.h>
int _pipe(int _fildes[2], unsigned int size, int mode )
{
HANDLE hReadPipe, hWritePipe;
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
if (!CreatePipe(&hReadPipe,&hWritePipe,NULL,size))
if (mode & O_NOINHERIT)
sa.bInheritHandle = FALSE;
if (!CreatePipe(&hReadPipe,&hWritePipe,&sa,size))
return -1;
_fildes[0] = __fileno_alloc(hReadPipe, mode);
_fildes[1] = __fileno_alloc(hWritePipe, mode);
if ((_fildes[0] = __fileno_alloc(hReadPipe, mode)) < 0)
{
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
__set_errno(EMFILE);
return -1;
}
if ((_fildes[1] = __fileno_alloc(hWritePipe, mode)) < 0)
{
__fileno_close(_fildes[0]);
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
__set_errno(EMFILE);
return -1;
}
return 0;
}

View file

@ -1,4 +1,5 @@
/*
/* $Id: setmode.c,v 1.4 2002/05/07 22:31:25 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crtdll/io/setmode.c
@ -19,7 +20,5 @@
int _setmode(int _fd, int _newmode)
{
DPRINT("_setmod(fd %d, newmode %x)\n", _fd, _newmode);
if (_fd >= 0 && _fd < 5)
return _O_TEXT;
return __fileno_setmode(_fd, _newmode);
}

View file

@ -1,4 +1,4 @@
/* $Id: dllmain.c,v 1.13 2002/05/05 14:57:41 chorns Exp $
/* $Id: dllmain.c,v 1.14 2002/05/07 22:31:25 hbirr Exp $
*
* ReactOS MSVCRT.DLL Compatibility Library
*/
@ -99,6 +99,10 @@ DllMain(PVOID hinstDll,
return FALSE;
}
}
if (nAttachCount==0)
{
__fileno_init();
}
/* create tls stuff */
if (!CreateThreadData())
@ -113,6 +117,7 @@ DllMain(PVOID hinstDll,
/* FIXME: more initializations... */
nAttachCount++;
DPRINT("Attach done\n");
break;
case DLL_THREAD_ATTACH://2
@ -149,6 +154,7 @@ DllMain(PVOID hinstDll,
hHeap = NULL;
#endif
}
DPRINT("Detach done\n");
}
break;
}

View file

@ -1,3 +1,4 @@
/* $Id: spawnve.c,v 1.3 2002/05/07 22:31:26 hbirr Exp $ */
/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@ -12,6 +13,7 @@
#include <msvcrt/process.h>
#include <msvcrt/ctype.h>
#include <msvcrt/io.h>
#include <msvcrt/fcntl.h>
#define NDEBUG
#include <msvcrt/msvcrtdbg.h>
@ -36,36 +38,93 @@
// information about crtdll file handles is not passed to child
int _fileinfo_dll = 0;
extern int maxfno;
static int
direct_exec_tail(const char *program, const char *args,
const char * envp,
PROCESS_INFORMATION *ProcessInformation)
direct_exec_tail(int mode, const char *program,
const char *args, const char * envp)
{
static STARTUPINFO StartupInfo;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
char* fmode;
HANDLE* hFile;
int i, last;
BOOL bResult;
DPRINT("direct_exec_tail()\n");
memset (&StartupInfo, 0, sizeof(STARTUPINFO));
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.lpReserved= NULL;
StartupInfo.dwFlags = 0 /*STARTF_USESTDHANDLES*/;
StartupInfo.wShowWindow = SW_SHOWDEFAULT;
StartupInfo.lpReserved2 = NULL;
StartupInfo.cbReserved2 = 0;
StartupInfo.hStdInput = _get_osfhandle(0);
StartupInfo.hStdOutput = _get_osfhandle(1);
StartupInfo.hStdError = _get_osfhandle(2);
if (! CreateProcessA((char *)program,(char *)args,NULL,NULL,TRUE,0,(LPVOID)envp,NULL,&StartupInfo,ProcessInformation) )
for (last = i = 0; i < maxfno; i++)
{
if ((void*)-1 != _get_osfhandle(i))
{
last = i + 1;
}
}
if (last)
{
StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE));
StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2);
if (StartupInfo.lpReserved2 == NULL)
{
__set_errno( GetLastError() );
return -1;
}
return (int)ProcessInformation->hProcess;
*(DWORD*)StartupInfo.lpReserved2 = last;
fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG));
hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char));
for (i = 0; i < last; i++)
{
int mode = __fileno_getmode(i);
HANDLE h = _get_osfhandle(i);
/* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
* is possible wrong
*/
if ((((ULONG)h) & 0x10000003) == 0x3 || mode & _O_NOINHERIT)
{
*hFile = INVALID_HANDLE_VALUE;
}
else
{
*hFile = h;
*fmode = (_O_ACCMODE & mode) | (((_O_TEXT | _O_BINARY) & mode) >> 8);
}
fmode++;
hFile++;
}
}
bResult = CreateProcessA((char *)program,
(char *)args,
NULL,
NULL,
TRUE,
mode == _P_DETACH ? DETACHED_PROCESS : 0,
(LPVOID)envp,
NULL,
&StartupInfo,
&ProcessInformation);
Sleep(100);
if (StartupInfo.lpReserved2)
{
free(StartupInfo.lpReserved2);
}
if (!bResult)
{
DPRINT("%x\n", GetLastError());
__set_errno( GetLastError() );
return -1;
}
CloseHandle(ProcessInformation.hThread);
return (int)ProcessInformation.hProcess;
}
static int vdm_exec(const char *program, char **argv, char **envp,
PROCESS_INFORMATION *ProcessInformation)
static int vdm_exec(int mode, const char *program, char **argv, char *envp)
{
static char args[1024];
int i = 0;
@ -78,11 +137,10 @@ static int vdm_exec(const char *program, char **argv, char **envp,
i++;
}
return direct_exec_tail(program,args,envp,ProcessInformation);
return direct_exec_tail(mode,program,args,envp);
}
static int go32_exec(const char *program, char **argv, char **envp,
PROCESS_INFORMATION *ProcessInformation)
static int go32_exec(int mode, const char *program, char **argv, char **envp)
{
char * penvblock, * ptr;
char * args;
@ -119,15 +177,15 @@ static int go32_exec(const char *program, char **argv, char **envp,
}
}
result = direct_exec_tail(program,args,(const char*)penvblock,ProcessInformation);
DPRINT("'%s'\n", args);
result = direct_exec_tail(mode, program,args,(const char*)penvblock);
free(args);
free(penvblock);
return result;
}
int
command_exec(const char *program, char **argv, char **envp,
PROCESS_INFORMATION *ProcessInformation)
command_exec(int mode, const char *program, char **argv, char *envp)
{
static char args[1024];
int i = 0;
@ -143,12 +201,11 @@ command_exec(const char *program, char **argv, char **envp,
i++;
}
return direct_exec_tail(program,args,envp,ProcessInformation);
return direct_exec_tail(mode,program,args,envp);
}
static int script_exec(const char *program, char **argv, char **envp,
PROCESS_INFORMATION *ProcessInformation)
static int script_exec(int mode, const char *program, char **argv, char **envp)
{
return 0;
}
@ -160,8 +217,7 @@ static int script_exec(const char *program, char **argv, char **envp,
executable from one of the shells used on MSDOS. */
static struct {
const char *extension;
int (*interp)(const char *, char **, char **,
PROCESS_INFORMATION *);
int (*interp)(int , const char*, char **, char **);
} interpreters[] = {
{ ".com", vdm_exec },
{ ".exe", go32_exec },
@ -190,7 +246,6 @@ static struct {
int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
{
/* This is the one that does the work! */
PROCESS_INFORMATION ProcessInformation;
union { char *const *x; char **p; } u;
int i = -1;
char **argvp;
@ -201,7 +256,7 @@ int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
int found = 0;
DWORD ExitCode;
DPRINT("_spawnve('%s')\n", path);
DPRINT("_spawnve(mode %x, '%s')\n", mode, path);
if (path == 0 || argv[0] == 0)
{
@ -275,20 +330,22 @@ int _spawnve(int mode, const char *path, char *const argv[], char *const envp[])
return -1;
}
errno = e;
i = interpreters[i].interp(rpath, argvp, envpp, &ProcessInformation);
i = interpreters[i].interp(mode, rpath, argvp, envpp);
if (i < 0)
{
return -1;
}
if (mode == P_OVERLAY)
{
CloseHandle((HANDLE)i);
exit(i);
}
if (mode == P_WAIT)
{
WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
GetExitCodeProcess(ProcessInformation.hProcess,&ExitCode);
WaitForSingleObject((HANDLE)i, INFINITE);
GetExitCodeProcess((HANDLE)i, &ExitCode);
CloseHandle((HANDLE)i);
i = (int)ExitCode;
CloseHandle(ProcessInformation.hThread);
CloseHandle(ProcessInformation.hProcess);
}
else
{
CloseHandle(ProcessInformation.hThread);
}
return i;
}

View file

@ -1,7 +1,8 @@
/*
/* $Id: fstat.c,v 1.9 2002/05/07 22:31:26 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crtdll/sys/fstat.c
* FILE: lib/msvcrt/sys/fstat.c
* PURPOSE: Gather file information
* PROGRAMER: Boudewijn Dekker
* UPDATE HISTORY:
@ -18,6 +19,8 @@
int _fstat(int fd, struct stat *statbuf)
{
BY_HANDLE_FILE_INFORMATION FileInformation;
DWORD dwFileType;
void* handle;
if (!statbuf)
{
@ -25,15 +28,19 @@ int _fstat(int fd, struct stat *statbuf)
return -1;
}
if (fd >= 0 && fd <= 4)
if ((void*)-1 == (handle = _get_osfhandle(fd)))
{
memset(statbuf, 0, sizeof(struct stat));
statbuf->st_dev = fd;
statbuf->st_mode = S_IFCHR;
return 0;
__set_errno(EBADF);
return -1;
}
if (!GetFileInformationByHandle(_get_osfhandle(fd),&FileInformation))
memset (statbuf, 0, sizeof(struct stat));
dwFileType = GetFileType(handle);
if (dwFileType == FILE_TYPE_DISK)
{
if (!GetFileInformationByHandle(handle,&FileInformation))
{
__set_errno(EBADF);
return -1;
@ -50,12 +57,31 @@ int _fstat(int fd, struct stat *statbuf)
else
statbuf->st_mode |= S_IFREG;
if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE;
}
else if (dwFileType == FILE_TYPE_CHAR)
{
statbuf->st_dev = fd;
statbuf->st_mode = S_IFCHR;
}
else if (dwFileType == FILE_TYPE_PIPE)
{
statbuf->st_dev = fd;
statbuf->st_mode = S_IFIFO;
}
else
{
// dwFileType is FILE_TYPE_UNKNOWN or has a bad value
__set_errno(EBADF);
return -1;
}
return 0;
}
__int64 _fstati64 (int fd, struct _stati64* statbuf)
{
BY_HANDLE_FILE_INFORMATION FileInformation;
DWORD dwFileType;
void *handle;
if (!statbuf)
{
@ -63,8 +89,19 @@ __int64 _fstati64 (int fd, struct _stati64* statbuf)
return -1;
}
if (!GetFileInformationByHandle(_get_osfhandle(fd),
&FileInformation))
if ((void*)-1 == (handle = _get_osfhandle(fd)))
{
__set_errno(EBADF);
return -1;
}
memset(statbuf, 0, sizeof(struct _stati64));
dwFileType = GetFileType(handle);
if (dwFileType == FILE_TYPE_DISK)
{
if (!GetFileInformationByHandle(handle,&FileInformation))
{
__set_errno(EBADF);
return -1;
@ -82,5 +119,24 @@ __int64 _fstati64 (int fd, struct _stati64* statbuf)
else
statbuf->st_mode |= S_IFREG;
if (!(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) statbuf->st_mode |= S_IWRITE;
}
else if (dwFileType == FILE_TYPE_CHAR)
{
statbuf->st_dev = fd;
statbuf->st_mode = S_IFCHR;
}
else if (dwFileType == FILE_TYPE_PIPE)
{
statbuf->st_dev = fd;
statbuf->st_mode = S_IFIFO;
}
else
{
// dwFileType is FILE_TYPE_UNKNOWN or has a bad value
__set_errno(EBADF);
return -1;
}
return 0;
}