📄 open.c
字号:
case 1: SetStdHandle(STD_OUTPUT_HANDLE, hand); break;
case 2: SetStdHandle(STD_ERROR_HANDLE, hand); break;
}
return fd;
}
/*
* 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;
}
/*
* INTERNAL
*/
char __fileno_getmode(int fd)
{
if (!is_valid_fd(fd)) {
__set_errno(EBADF);
return -1;
}
return fdinfo(fd)->fdflags;
}
/*
* INTERNAL
*/
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)
{
case 0: SetStdHandle(STD_INPUT_HANDLE, NULL); break;
case 1: SetStdHandle(STD_OUTPUT_HANDLE, NULL); break;
case 2: SetStdHandle(STD_ERROR_HANDLE, NULL); break;
}
}
else
{
if (fd == g_fdend - 1)
g_fdend--;
if (fd < g_fdstart)
g_fdstart = fd;
}
UNLOCK_FILES();
}
/*
* @implemented
*/
int _open_osfhandle(long osfhandle, int oflags)
{
/*
PREV:
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.
* file, so set the write flag. It also only sets _O_TEXT if it wants
* text - it never sets _O_BINARY.
*/
/* FIXME: handle more flags */
/*
flags |= MSVCRT__IOREAD|MSVCRT__IOWRT;
if ( !( flags & _O_TEXT ) ) flags |= _O_BINARY;
fd = msvcrt_alloc_fd((HANDLE)hand,flags);
TRACE(":handle (%ld) fd (%d) flags 0x%08x\n",hand,fd, flags);
*/
/* MSVCRT__O_RDONLY (0) always matches, so set the read flag
* MFC's CStdioFile clears O_RDONLY (0)! if it wants to write to the
* file, so set the write flag. It also only sets MSVCRT__O_TEXT if it wants
* text - it never sets MSVCRT__O_BINARY.
*/
/* FIXME: handle more flags */
/*
LAG TEST SOM TESTER UT ALT DETTE flag tingern
*/
if (!(oflags & (_O_BINARY | _O_TEXT)) && (_fmode & _O_BINARY))
oflags |= _O_BINARY;
else
oflags |= _O_TEXT;
return alloc_fd((HANDLE)osfhandle, split_oflags(oflags));
}
/*
* @implemented
*/
long _get_osfhandle(int fd)
{
TRACE("_get_osfhandle(%i)",fd);
if (!is_valid_fd(fd)) {
return( -1 );
}
return( (long)fdinfo(fd)->hFile );
}
/*
* INTERNAL
*/
int __fileno_dup2(int handle1, int handle2)
{
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) {
__set_errno(EBADF);
return -1;
}
if (handle1 == handle2)
return handle1;
// if (_pioinfo[handle2]->fd != -1) {
if (fdinfo(handle2)->hFile != INVALID_HANDLE_VALUE) {
_close(handle2);
}
hProcess = GetCurrentProcess();
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;
fdinfo(handle2)->fdflags = fdinfo(handle1)->fdflags;
switch (handle2) {
case 0:
SetStdHandle(STD_INPUT_HANDLE, fdinfo(handle2)->hFile);
break;
case 1:
SetStdHandle(STD_OUTPUT_HANDLE, fdinfo(handle2)->hFile);
break;
case 2:
SetStdHandle(STD_ERROR_HANDLE, fdinfo(handle2)->hFile);
break;
}
return handle1;
} else {
__set_errno(EMFILE); // Is this the correct error no.?
return -1;
}
}
void* malloc(size_t sizeObject);
/*
* INTERNAL
*/
BOOL __fileno_init(void)
{
STARTUPINFOA si;
int i;
init_bucket(first_bucket);
GetStartupInfoA(&si);
if (si.cbReserved2 != 0 && si.lpReserved2 != NULL)
{
char* fdflags_ptr;
HANDLE* handle_ptr;
g_fdend = *(unsigned*)si.lpReserved2;
fdflags_ptr= (char*)(si.lpReserved2 + sizeof(unsigned));
handle_ptr = (HANDLE*)(fdflags_ptr + g_fdend * sizeof(char));
g_fdend = min(g_fdend, FDINFO_ENTRIES);
for (i = 0; i < g_fdend; i++)
{
if (!fdinfo_bucket(i))
{
if (!alloc_init_bucket(i)){
/* FIXME: free other buckets? */
return FALSE;
}
}
if ((*fdflags_ptr & FOPEN) && *handle_ptr != INVALID_HANDLE_VALUE)
{
fdinfo(i)->fdflags = *fdflags_ptr;
fdinfo(i)->hFile = *handle_ptr;
}
/*
else
{
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;
}
for (i = 0; i < 3; i++)
{
/* FILE structs for stdin/out/err are static and never deleted */
// MSVCRT_fstreams[i] = &MSVCRT__iob[i];
}
// MSVCRT_stream_idx = 3;
return TRUE;
}
/* INTERNAL: Create an inheritance data block (for spawned process)
* The inheritance block is made of:
* 00 int nb of file descriptor (NBFD)
* 04 char file flags (wxflag): repeated for each fd
* 4+NBFD HANDLE file handle: repeated for each fd
*/
unsigned create_io_inherit_block(STARTUPINFOA* si)
{
int fd;
char* fdflags_ptr;
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)
{
si->cbReserved2 = 0;
return( FALSE );
}
fdflags_ptr = (char*)si->lpReserved2 + sizeof(unsigned);
handle_ptr = (HANDLE*)(fdflags_ptr + g_fdend * sizeof(char));
*(unsigned*)si->lpReserved2 = g_fdend;
for (fd = 0; fd < g_fdend; fd++)
{
/* to be inherited, we need it to be open, and that DONTINHERIT isn't set */
if ((fdinfo(fd)->fdflags & (FOPEN | FNOINHERIT)) == FOPEN)
{
*fdflags_ptr = fdinfo(fd)->fdflags;
*handle_ptr = fdinfo(fd)->hFile;
}
else
{
*fdflags_ptr = 0;
*handle_ptr = INVALID_HANDLE_VALUE;
}
fdflags_ptr++; handle_ptr++;
}
return( TRUE );
}
/*
* @implemented
*/
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);
/* FIXME: Should we fail with EINVAL here? */
}
prevmode = fdinfo(fd)->fdflags & FTEXT ? _O_TEXT : _O_BINARY;
if ((newmode & _O_TEXT) == _O_TEXT)
{
fdinfo(fd)->fdflags |= FTEXT;
}
else
{
/* FIXME: If both _O_TEXT and _O_BINARY are set, we get here.
* Should we fail with EINVAL instead? -Gunnar
*/
fdinfo(fd)->fdflags &= ~FTEXT;
}
return(prevmode);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -