mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[CRT] Update file descriptor handling to match Wine (2/7). CORE-14504
Import Wine commits by Piotr Caban: * 4508e665c07 msvcrt: Use fd critical section in _commit. * afc6962a24a msvcrt: Use fd critical section in _close. * 9a4cfbc3edc msvcrt: Use fd critical section in _eof. * ffdd16cc0d7 msvcrt: Use fd critical section in _locking. * fa6de597700 msvcrt: Use fd critical section in _lseeki64. * f2f45d5fe67 msvcrt: Use fd critical section in _chsize_s.
This commit is contained in:
parent
25064fdf3c
commit
9eb1eae28c
1 changed files with 93 additions and 64 deletions
|
@ -182,13 +182,16 @@ static inline ioinfo* get_ioinfo_nolock(int fd)
|
||||||
|
|
||||||
static inline ioinfo* get_ioinfo(int fd)
|
static inline ioinfo* get_ioinfo(int fd)
|
||||||
{
|
{
|
||||||
ioinfo *ret = NULL;
|
ioinfo *ret = get_ioinfo_nolock(fd);
|
||||||
if(fd < MSVCRT_MAX_FILES)
|
if(ret->exflag & EF_CRIT_INIT)
|
||||||
ret = __pioinfo[fd/MSVCRT_FD_BLOCK_SIZE];
|
EnterCriticalSection(&ret->crit);
|
||||||
if(!ret)
|
return ret;
|
||||||
return &__badioinfo;
|
}
|
||||||
|
|
||||||
return ret + (fd%MSVCRT_FD_BLOCK_SIZE);
|
static inline void release_ioinfo(ioinfo *info)
|
||||||
|
{
|
||||||
|
if(info->exflag & EF_CRIT_INIT)
|
||||||
|
LeaveCriticalSection(&info->crit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FILE* msvcrt_get_file(int i)
|
static inline FILE* msvcrt_get_file(int i)
|
||||||
|
@ -814,27 +817,36 @@ int CDECL _wunlink(const wchar_t *path)
|
||||||
*/
|
*/
|
||||||
int CDECL _commit(int fd)
|
int CDECL _commit(int fd)
|
||||||
{
|
{
|
||||||
HANDLE hand = fdtoh(fd);
|
ioinfo *info = get_ioinfo(fd);
|
||||||
|
int ret;
|
||||||
|
|
||||||
TRACE(":fd (%d) handle (%p)\n",fd,hand);
|
TRACE(":fd (%d) handle (%p)\n", fd, info->handle);
|
||||||
if (hand == INVALID_HANDLE_VALUE)
|
if (info->handle == INVALID_HANDLE_VALUE)
|
||||||
return -1;
|
ret = -1;
|
||||||
|
else if (!FlushFileBuffers(info->handle))
|
||||||
if (!FlushFileBuffers(hand))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_INVALID_HANDLE)
|
|
||||||
{
|
{
|
||||||
/* FlushFileBuffers fails for console handles
|
if (GetLastError() == ERROR_INVALID_HANDLE)
|
||||||
* so we ignore this error.
|
{
|
||||||
*/
|
/* FlushFileBuffers fails for console handles
|
||||||
return 0;
|
* so we ignore this error.
|
||||||
|
*/
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE(":failed-last error (%d)\n",GetLastError());
|
||||||
|
_dosmaperr(GetLastError());
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TRACE(":failed-last error (%d)\n",GetLastError());
|
else
|
||||||
_dosmaperr(GetLastError());
|
{
|
||||||
return -1;
|
TRACE(":ok\n");
|
||||||
}
|
ret = 0;
|
||||||
TRACE(":ok\n");
|
}
|
||||||
return 0;
|
|
||||||
|
release_ioinfo(info);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _flushall calls fflush which calls _flushall */
|
/* _flushall calls fflush which calls _flushall */
|
||||||
|
@ -907,27 +919,24 @@ int CDECL fflush(FILE* file)
|
||||||
*/
|
*/
|
||||||
int CDECL _close(int fd)
|
int CDECL _close(int fd)
|
||||||
{
|
{
|
||||||
HANDLE hand;
|
ioinfo *info = get_ioinfo(fd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
LOCK_FILES();
|
LOCK_FILES();
|
||||||
hand = fdtoh(fd);
|
TRACE(":fd (%d) handle (%p)\n", fd, info->handle);
|
||||||
TRACE(":fd (%d) handle (%p)\n",fd,hand);
|
if (!(info->wxflag & WX_OPEN)) {
|
||||||
if (hand == INVALID_HANDLE_VALUE)
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
else if (!CloseHandle(hand))
|
} else {
|
||||||
{
|
ret = CloseHandle(info->handle) ? 0 : -1;
|
||||||
WARN(":failed-last error (%d)\n",GetLastError());
|
|
||||||
_dosmaperr(GetLastError());
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msvcrt_free_fd(fd);
|
msvcrt_free_fd(fd);
|
||||||
ret = 0;
|
if (ret) {
|
||||||
|
WARN(":failed-last error (%d)\n",GetLastError());
|
||||||
|
_dosmaperr(GetLastError());
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UNLOCK_FILES();
|
UNLOCK_FILES();
|
||||||
TRACE(":ok\n");
|
release_ioinfo(info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,29 +1013,38 @@ int CDECL _dup(int od)
|
||||||
*/
|
*/
|
||||||
int CDECL _eof(int fd)
|
int CDECL _eof(int fd)
|
||||||
{
|
{
|
||||||
|
ioinfo *info = get_ioinfo(fd);
|
||||||
DWORD curpos,endpos;
|
DWORD curpos,endpos;
|
||||||
LONG hcurpos,hendpos;
|
LONG hcurpos,hendpos;
|
||||||
HANDLE hand = fdtoh(fd);
|
|
||||||
|
|
||||||
TRACE(":fd (%d) handle (%p)\n",fd,hand);
|
TRACE(":fd (%d) handle (%p)\n", fd, info->handle);
|
||||||
|
|
||||||
if (hand == INVALID_HANDLE_VALUE)
|
if (info->handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (get_ioinfo_nolock(fd)->wxflag & WX_ATEOF) return TRUE;
|
if (info->wxflag & WX_ATEOF)
|
||||||
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Otherwise we do it the hard way */
|
/* Otherwise we do it the hard way */
|
||||||
hcurpos = hendpos = 0;
|
hcurpos = hendpos = 0;
|
||||||
curpos = SetFilePointer(hand, 0, &hcurpos, FILE_CURRENT);
|
curpos = SetFilePointer(info->handle, 0, &hcurpos, FILE_CURRENT);
|
||||||
endpos = SetFilePointer(hand, 0, &hendpos, FILE_END);
|
endpos = SetFilePointer(info->handle, 0, &hendpos, FILE_END);
|
||||||
|
|
||||||
if (curpos == endpos && hcurpos == hendpos)
|
if (curpos == endpos && hcurpos == hendpos)
|
||||||
{
|
{
|
||||||
/* FIXME: shouldn't WX_ATEOF be set here? */
|
/* FIXME: shouldn't WX_ATEOF be set here? */
|
||||||
|
release_ioinfo(info);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFilePointer(hand, curpos, &hcurpos, FILE_BEGIN);
|
SetFilePointer(info->handle, curpos, &hcurpos, FILE_BEGIN);
|
||||||
|
release_ioinfo(info);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,15 +1110,20 @@ void msvcrt_free_io(void)
|
||||||
*/
|
*/
|
||||||
__int64 CDECL _lseeki64(int fd, __int64 offset, int whence)
|
__int64 CDECL _lseeki64(int fd, __int64 offset, int whence)
|
||||||
{
|
{
|
||||||
HANDLE hand = fdtoh(fd);
|
ioinfo *info = get_ioinfo(fd);
|
||||||
LARGE_INTEGER ofs;
|
LARGE_INTEGER ofs;
|
||||||
|
|
||||||
TRACE(":fd (%d) handle (%p)\n",fd,hand);
|
TRACE(":fd (%d) handle (%p)\n", fd, info->handle);
|
||||||
if (hand == INVALID_HANDLE_VALUE)
|
|
||||||
|
if (info->handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (whence < 0 || whence > 2)
|
if (whence < 0 || whence > 2)
|
||||||
{
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
*_errno() = EINVAL;
|
*_errno() = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1114,14 +1137,16 @@ __int64 CDECL _lseeki64(int fd, __int64 offset, int whence)
|
||||||
/* The MoleBox protection scheme expects msvcrt to use SetFilePointer only,
|
/* The MoleBox protection scheme expects msvcrt to use SetFilePointer only,
|
||||||
* so a LARGE_INTEGER offset cannot be passed directly via SetFilePointerEx. */
|
* so a LARGE_INTEGER offset cannot be passed directly via SetFilePointerEx. */
|
||||||
ofs.QuadPart = offset;
|
ofs.QuadPart = offset;
|
||||||
if ((ofs.u.LowPart = SetFilePointer(hand, ofs.u.LowPart, &ofs.u.HighPart, whence)) != INVALID_SET_FILE_POINTER ||
|
if ((ofs.u.LowPart = SetFilePointer(info->handle, ofs.u.LowPart, &ofs.u.HighPart, whence)) != INVALID_SET_FILE_POINTER ||
|
||||||
GetLastError() == ERROR_SUCCESS)
|
GetLastError() == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
get_ioinfo_nolock(fd)->wxflag &= ~(WX_ATEOF|WX_READEOF);
|
info->wxflag &= ~(WX_ATEOF|WX_READEOF);
|
||||||
/* FIXME: What if we seek _to_ EOF - is EOF set? */
|
/* FIXME: What if we seek _to_ EOF - is EOF set? */
|
||||||
|
|
||||||
|
release_ioinfo(info);
|
||||||
return ofs.QuadPart;
|
return ofs.QuadPart;
|
||||||
}
|
}
|
||||||
|
release_ioinfo(info);
|
||||||
TRACE(":error-last error (%d)\n",GetLastError());
|
TRACE(":error-last error (%d)\n",GetLastError());
|
||||||
_dosmaperr(GetLastError());
|
_dosmaperr(GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1167,16 +1192,20 @@ void CDECL _unlock_file(FILE *file)
|
||||||
*/
|
*/
|
||||||
int CDECL _locking(int fd, int mode, LONG nbytes)
|
int CDECL _locking(int fd, int mode, LONG nbytes)
|
||||||
{
|
{
|
||||||
|
ioinfo *info = get_ioinfo(fd);
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
DWORD cur_locn;
|
DWORD cur_locn;
|
||||||
HANDLE hand = fdtoh(fd);
|
|
||||||
|
|
||||||
TRACE(":fd (%d) handle (%p)\n",fd,hand);
|
TRACE(":fd (%d) handle (%p)\n", fd, info->handle);
|
||||||
if (hand == INVALID_HANDLE_VALUE)
|
if (info->handle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode < 0 || mode > 4)
|
if (mode < 0 || mode > 4)
|
||||||
{
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
*_errno() = EINVAL;
|
*_errno() = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1189,8 +1218,9 @@ int CDECL _locking(int fd, int mode, LONG nbytes)
|
||||||
(mode==_LK_NBRLCK)?"_LK_NBRLCK":
|
(mode==_LK_NBRLCK)?"_LK_NBRLCK":
|
||||||
"UNKNOWN");
|
"UNKNOWN");
|
||||||
|
|
||||||
if ((cur_locn = SetFilePointer(hand, 0L, NULL, SEEK_CUR)) == INVALID_SET_FILE_POINTER)
|
if ((cur_locn = SetFilePointer(info->handle, 0L, NULL, SEEK_CUR)) == INVALID_SET_FILE_POINTER)
|
||||||
{
|
{
|
||||||
|
release_ioinfo(info);
|
||||||
FIXME ("Seek failed\n");
|
FIXME ("Seek failed\n");
|
||||||
*_errno() = EINVAL; /* FIXME */
|
*_errno() = EINVAL; /* FIXME */
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1201,16 +1231,17 @@ int CDECL _locking(int fd, int mode, LONG nbytes)
|
||||||
ret = 1; /* just to satisfy gcc */
|
ret = 1; /* just to satisfy gcc */
|
||||||
while (nretry--)
|
while (nretry--)
|
||||||
{
|
{
|
||||||
ret = LockFile(hand, cur_locn, 0L, nbytes, 0L);
|
ret = LockFile(info->handle, cur_locn, 0L, nbytes, 0L);
|
||||||
if (ret) break;
|
if (ret) break;
|
||||||
Sleep(1);
|
Sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mode == _LK_UNLCK)
|
else if (mode == _LK_UNLCK)
|
||||||
ret = UnlockFile(hand, cur_locn, 0L, nbytes, 0L);
|
ret = UnlockFile(info->handle, cur_locn, 0L, nbytes, 0L);
|
||||||
else
|
else
|
||||||
ret = LockFile(hand, cur_locn, 0L, nbytes, 0L);
|
ret = LockFile(info->handle, cur_locn, 0L, nbytes, 0L);
|
||||||
/* FIXME - what about error settings? */
|
/* FIXME - what about error settings? */
|
||||||
|
release_ioinfo(info);
|
||||||
return ret ? 0 : -1;
|
return ret ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,18 +1290,16 @@ int CDECL fseek(FILE* file, long offset, int whence)
|
||||||
*/
|
*/
|
||||||
int CDECL _chsize_s(int fd, __int64 size)
|
int CDECL _chsize_s(int fd, __int64 size)
|
||||||
{
|
{
|
||||||
|
ioinfo *info;
|
||||||
__int64 cur, pos;
|
__int64 cur, pos;
|
||||||
HANDLE handle;
|
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
TRACE("(fd=%d, size=%s)\n", fd, wine_dbgstr_longlong(size));
|
TRACE("(fd=%d, size=%s)\n", fd, wine_dbgstr_longlong(size));
|
||||||
|
|
||||||
if (!MSVCRT_CHECK_PMT(size >= 0)) return EINVAL;
|
if (!MSVCRT_CHECK_PMT(size >= 0)) return EINVAL;
|
||||||
|
|
||||||
LOCK_FILES();
|
info = get_ioinfo(fd);
|
||||||
|
if (info->handle != INVALID_HANDLE_VALUE)
|
||||||
handle = fdtoh(fd);
|
|
||||||
if (handle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
/* save the current file pointer */
|
/* save the current file pointer */
|
||||||
cur = _lseeki64(fd, 0, SEEK_CUR);
|
cur = _lseeki64(fd, 0, SEEK_CUR);
|
||||||
|
@ -1279,7 +1308,7 @@ int CDECL _chsize_s(int fd, __int64 size)
|
||||||
pos = _lseeki64(fd, size, SEEK_SET);
|
pos = _lseeki64(fd, size, SEEK_SET);
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
{
|
{
|
||||||
ret = SetEndOfFile(handle);
|
ret = SetEndOfFile(info->handle);
|
||||||
if (!ret) _dosmaperr(GetLastError());
|
if (!ret) _dosmaperr(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1288,7 +1317,7 @@ int CDECL _chsize_s(int fd, __int64 size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK_FILES();
|
release_ioinfo(info);
|
||||||
return ret ? 0 : *_errno();
|
return ret ? 0 : *_errno();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue