mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* win32/win32.c: fasten file I/O on mswin32/mingw32.
* win32/win32.h: ditto. * rubysig.h: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1194 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e1c29a3f13
commit
92e4b1b06e
4 changed files with 211 additions and 118 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,11 @@
|
|||
Sun Feb 18 00:09:50 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* win32/win32.c: fasten file I/O on mswin32/mingw32.
|
||||
|
||||
* win32/win32.h: ditto.
|
||||
|
||||
* rubysig.h: ditto.
|
||||
|
||||
Fri Feb 16 01:44:56 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* io.c (set_outfile): f should be the FILE* from the assigning value.
|
||||
|
@ -101,7 +109,7 @@ Sat Feb 10 23:07:15 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
|||
|
||||
Sat Feb 10 00:00:30 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||
|
||||
* win32/win32.c (win32_stat): replace stat for enable when pathname
|
||||
* win32/win32.c (win32_stat): replace stat to enable when pathname
|
||||
ends with '/' or '\' for mswin32 on Win9X / Win2k.
|
||||
|
||||
* win32/win32.h: ditto.
|
||||
|
|
10
rubysig.h
10
rubysig.h
|
@ -22,12 +22,14 @@ typedef LONG rb_atomic_t;
|
|||
# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
|
||||
|
||||
/* Windows doesn't allow interrupt while system calls */
|
||||
# define TRAP_BEG win32_enter_syscall()
|
||||
# define TRAP_END win32_leave_syscall()
|
||||
# define TRAP_BEG do {\
|
||||
rb_atomic_t trap_immediate = ATOMIC_SET(rb_trap_immediate, 1);
|
||||
# define TRAP_END ATOMIC_SET(rb_trap_immediate, trap_immediate);\
|
||||
} while (0)
|
||||
# define RUBY_CRITICAL(statements) do {\
|
||||
win32_disable_interrupt();\
|
||||
win32_enter_critical();\
|
||||
statements;\
|
||||
win32_enable_interrupt();\
|
||||
win32_leave_critical();\
|
||||
} while (0)
|
||||
#else
|
||||
typedef int rb_atomic_t;
|
||||
|
|
284
win32/win32.c
284
win32/win32.c
|
@ -35,15 +35,17 @@
|
|||
#define bool int
|
||||
#endif
|
||||
|
||||
#ifdef _M_IX86
|
||||
# define WIN95 1
|
||||
#else
|
||||
# undef WIN95
|
||||
#endif
|
||||
|
||||
#if HAVE_WSAWAITFORMULTIPLEEVENTS
|
||||
# define USE_INTERRUPT_WINSOCK
|
||||
#endif
|
||||
|
||||
#if USE_INTERRUPT_WINSOCK
|
||||
|
||||
# if defined(_MSC_VER) && _MSC_VER <= 1000
|
||||
/* VC++4.0 doesn't have this. */
|
||||
extern DWORD WSAWaitForMultipleEvents(DWORD nevent, const HANDLE *events,
|
||||
BOOL waitall, DWORD timeout,
|
||||
BOOL alertable);
|
||||
# endif
|
||||
|
||||
# define WaitForMultipleEvents WSAWaitForMultipleEvents
|
||||
# define CreateSignal() (HANDLE)WSACreateEvent()
|
||||
# define SetSignal(ev) WSASetEvent(ev)
|
||||
|
@ -77,6 +79,7 @@ static DWORD wait_events(HANDLE event, DWORD timeout);
|
|||
|
||||
char *NTLoginName;
|
||||
|
||||
#ifdef WIN95
|
||||
DWORD Win32System = (DWORD)-1;
|
||||
|
||||
static DWORD
|
||||
|
@ -102,6 +105,10 @@ static int
|
|||
IsWinNT(void) {
|
||||
return (IdOS() == VER_PLATFORM_WIN32_NT);
|
||||
}
|
||||
#else
|
||||
# define IsWinNT() TRUE
|
||||
# define IsWin95() FALSE
|
||||
#endif
|
||||
|
||||
/* main thread constants */
|
||||
static struct {
|
||||
|
@ -177,6 +184,7 @@ flock_winnt(VALUE self, int argc, VALUE* argv)
|
|||
return i;
|
||||
}
|
||||
|
||||
#ifdef WIN95
|
||||
static VALUE
|
||||
flock_win95(VALUE self, int argc, VALUE* argv)
|
||||
{
|
||||
|
@ -207,6 +215,7 @@ flock_win95(VALUE self, int argc, VALUE* argv)
|
|||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef LK_ERR
|
||||
#undef LK_LEN
|
||||
|
@ -214,6 +223,7 @@ flock_win95(VALUE self, int argc, VALUE* argv)
|
|||
int
|
||||
flock(int fd, int oper)
|
||||
{
|
||||
#ifdef WIN95
|
||||
static asynchronous_func_t locker = NULL;
|
||||
|
||||
if (!locker) {
|
||||
|
@ -222,6 +232,9 @@ flock(int fd, int oper)
|
|||
else
|
||||
locker = flock_win95;
|
||||
}
|
||||
#else
|
||||
const asynchronous_func_t locker = flock_winnt;
|
||||
#endif
|
||||
|
||||
return win32_asynchronize(locker,
|
||||
(VALUE)_get_osfhandle(fd), oper, NULL,
|
||||
|
@ -1671,6 +1684,13 @@ EXTERN_C void __cdecl _unlock(int);
|
|||
#if defined _MT || defined __MSVCRT__
|
||||
#define MSVCRT_THREADS
|
||||
#endif
|
||||
#ifdef MSVCRT_THREADS
|
||||
# define MTHREAD_ONLY(x) x
|
||||
# define STHREAD_ONLY(x)
|
||||
#else
|
||||
# define MTHREAD_ONLY(x)
|
||||
# define STHREAD_ONLY(x) x
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
long osfhnd; /* underlying OS file HANDLE */
|
||||
|
@ -1704,20 +1724,6 @@ EXTERN_C _CRTIMP ioinfo * __pioinfo[];
|
|||
|
||||
#define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = osfh)
|
||||
|
||||
static int
|
||||
_alloc_osfhnd(void)
|
||||
{
|
||||
HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
int fh = _open_osfhandle((long)hF, 0);
|
||||
CloseHandle(hF);
|
||||
if (fh == -1)
|
||||
return fh;
|
||||
#ifdef MSVCRT_THREADS
|
||||
EnterCriticalSection(&(_pioinfo(fh)->lock));
|
||||
#endif
|
||||
return fh;
|
||||
}
|
||||
|
||||
static int
|
||||
my_open_osfhandle(long osfhandle, int flags)
|
||||
{
|
||||
|
@ -1736,22 +1742,27 @@ my_open_osfhandle(long osfhandle, int flags)
|
|||
if (flags & O_NOINHERIT)
|
||||
fileflags |= FNOINHERIT;
|
||||
|
||||
/* attempt to allocate a C Runtime file handle */
|
||||
if ((fh = _alloc_osfhnd()) == -1) {
|
||||
errno = EMFILE; /* too many open files */
|
||||
_doserrno = 0L; /* not an OS error */
|
||||
return -1; /* return error to caller */
|
||||
}
|
||||
RUBY_CRITICAL({
|
||||
/* attempt to allocate a C Runtime file handle */
|
||||
HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
fh = _open_osfhandle((long)hF, 0);
|
||||
CloseHandle(hF);
|
||||
if (fh == -1) {
|
||||
errno = EMFILE; /* too many open files */
|
||||
_doserrno = 0L; /* not an OS error */
|
||||
}
|
||||
else {
|
||||
|
||||
/* the file is open. now, set the info in _osfhnd array */
|
||||
_set_osfhnd(fh, osfhandle);
|
||||
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fh)->lock)));
|
||||
/* the file is open. now, set the info in _osfhnd array */
|
||||
_set_osfhnd(fh, osfhandle);
|
||||
|
||||
fileflags |= FOPEN; /* mark as open */
|
||||
fileflags |= FOPEN; /* mark as open */
|
||||
|
||||
_osfile(fh) = fileflags; /* set osfile entry */
|
||||
#ifdef MSVCRT_THREADS
|
||||
LeaveCriticalSection(&_pioinfo(fh)->lock);
|
||||
#endif
|
||||
_osfile(fh) = fileflags; /* set osfile entry */
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fh)->lock));
|
||||
}
|
||||
});
|
||||
|
||||
return fh; /* return handle */
|
||||
}
|
||||
|
@ -1797,10 +1808,10 @@ myfddup (int fd)
|
|||
void
|
||||
myfdclose(FILE *fp)
|
||||
{
|
||||
#if !defined MSVCRT_THREADS
|
||||
_free_osfhnd(fileno(fp));
|
||||
#endif
|
||||
fclose(fp);
|
||||
RUBY_CRITICAL({
|
||||
STHREAD_ONLY(_free_osfhnd(fileno(fp)));
|
||||
fclose(fp);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -2035,7 +2046,8 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||
ex = &trap;
|
||||
#endif /* USE_INTERRUPT_WINSOCK */
|
||||
|
||||
if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) {
|
||||
RUBY_CRITICAL(r = select (nfds, rd, wr, ex, timeout));
|
||||
if (r == SOCKET_ERROR) {
|
||||
errno = WSAGetLastError();
|
||||
switch (errno) {
|
||||
case WSAEINTR:
|
||||
|
@ -2082,6 +2094,9 @@ StartSockets ()
|
|||
interrupted_event = CreateSignal();
|
||||
if (!interrupted_event)
|
||||
rb_fatal("Unable to create interrupt event!\n");
|
||||
interrupted_event = CreateSignal();
|
||||
if (!interrupted_event)
|
||||
rb_fatal("Unable to create interrupt event!\n");
|
||||
}
|
||||
|
||||
#undef accept
|
||||
|
@ -2094,7 +2109,8 @@ myaccept (SOCKET s, struct sockaddr *addr, int *addrlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = accept (TO_SOCKET(s), addr, addrlen)) == INVALID_SOCKET)
|
||||
RUBY_CRITICAL(r = accept (TO_SOCKET(s), addr, addrlen));
|
||||
if (r == INVALID_SOCKET)
|
||||
errno = WSAGetLastError();
|
||||
return my_open_osfhandle(r, O_RDWR|O_BINARY);
|
||||
}
|
||||
|
@ -2109,7 +2125,8 @@ mybind (SOCKET s, struct sockaddr *addr, int addrlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = bind (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = bind (TO_SOCKET(s), addr, addrlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2123,7 +2140,8 @@ myconnect (SOCKET s, struct sockaddr *addr, int addrlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = connect (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = connect (TO_SOCKET(s), addr, addrlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2138,7 +2156,8 @@ mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getpeername (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = getpeername (TO_SOCKET(s), addr, addrlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2152,7 +2171,8 @@ mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getsockname (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = getsockname (TO_SOCKET(s), addr, addrlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2164,7 +2184,8 @@ mygetsockopt (SOCKET s, int level, int optname, char *optval, int *optlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getsockopt (TO_SOCKET(s), level, optname, optval, optlen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = getsockopt (TO_SOCKET(s), level, optname, optval, optlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2178,7 +2199,8 @@ myioctlsocket (SOCKET s, long cmd, u_long *argp)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = ioctlsocket (TO_SOCKET(s), cmd, argp)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = ioctlsocket (TO_SOCKET(s), cmd, argp));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2192,7 +2214,8 @@ mylisten (SOCKET s, int backlog)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = listen (TO_SOCKET(s), backlog)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = listen (TO_SOCKET(s), backlog));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2206,7 +2229,8 @@ myrecv (SOCKET s, char *buf, int len, int flags)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = recv (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = recv (TO_SOCKET(s), buf, len, flags));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2221,7 +2245,8 @@ myrecvfrom (SOCKET s, char *buf, int len, int flags,
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = recvfrom (TO_SOCKET(s), buf, len, flags, from, fromlen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = recvfrom (TO_SOCKET(s), buf, len, flags, from, fromlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2235,7 +2260,8 @@ mysend (SOCKET s, char *buf, int len, int flags)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = send (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = send (TO_SOCKET(s), buf, len, flags));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2250,7 +2276,8 @@ mysendto (SOCKET s, char *buf, int len, int flags,
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = sendto (TO_SOCKET(s), buf, len, flags, to, tolen)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = sendto (TO_SOCKET(s), buf, len, flags, to, tolen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2264,8 +2291,8 @@ mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen))
|
||||
== SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2279,7 +2306,8 @@ myshutdown (SOCKET s, int how)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = shutdown (TO_SOCKET(s), how)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = shutdown (TO_SOCKET(s), how));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2293,7 +2321,8 @@ mysocket (int af, int type, int protocol)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
|
||||
RUBY_CRITICAL(s = socket (af, type, protocol));
|
||||
if (s == INVALID_SOCKET) {
|
||||
errno = WSAGetLastError();
|
||||
//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
|
||||
}
|
||||
|
@ -2309,7 +2338,8 @@ mygethostbyaddr (char *addr, int len, int type)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = gethostbyaddr (addr, len, type)) == NULL)
|
||||
RUBY_CRITICAL(r = gethostbyaddr (addr, len, type));
|
||||
if (r == NULL)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2323,7 +2353,8 @@ mygethostbyname (char *name)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = gethostbyname (name)) == NULL)
|
||||
RUBY_CRITICAL(r = gethostbyname (name));
|
||||
if (r == NULL)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2337,7 +2368,8 @@ mygethostname (char *name, int len)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = gethostname (name, len)) == SOCKET_ERROR)
|
||||
RUBY_CRITICAL(r = gethostname (name, len));
|
||||
if (r == SOCKET_ERROR)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2351,7 +2383,8 @@ mygetprotobyname (char *name)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getprotobyname (name)) == NULL)
|
||||
RUBY_CRITICAL(r = getprotobyname (name));
|
||||
if (r == NULL)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2365,7 +2398,8 @@ mygetprotobynumber (int num)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getprotobynumber (num)) == NULL)
|
||||
RUBY_CRITICAL(r = getprotobynumber (num));
|
||||
if (r == NULL)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2379,7 +2413,8 @@ mygetservbyname (char *name, char *proto)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getservbyname (name, proto)) == NULL)
|
||||
RUBY_CRITICAL(r = getservbyname (name, proto));
|
||||
if (r == NULL)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2393,7 +2428,8 @@ mygetservbyport (int port, char *proto)
|
|||
if (!NtSocketsInitialized++) {
|
||||
StartSockets();
|
||||
}
|
||||
if ((r = getservbyport (port, proto)) == NULL)
|
||||
RUBY_CRITICAL(r = getservbyport (port, proto));
|
||||
if (r == NULL)
|
||||
errno = WSAGetLastError();
|
||||
return r;
|
||||
}
|
||||
|
@ -2440,14 +2476,18 @@ waitpid (pid_t pid, int *stat_loc, int options)
|
|||
} else {
|
||||
timeout = INFINITE;
|
||||
}
|
||||
if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
|
||||
pid = _cwait(stat_loc, pid, 0);
|
||||
RUBY_CRITICAL({
|
||||
if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
|
||||
pid = _cwait(stat_loc, pid, 0);
|
||||
}
|
||||
else {
|
||||
pid = 0;
|
||||
}
|
||||
});
|
||||
#if !defined __BORLANDC__
|
||||
*stat_loc <<= 8;
|
||||
if (pid) *stat_loc <<= 8;
|
||||
#endif
|
||||
return pid;
|
||||
}
|
||||
return 0;
|
||||
return pid;
|
||||
}
|
||||
|
||||
#include <sys/timeb.h>
|
||||
|
@ -2579,36 +2619,38 @@ myrename(const char *oldpath, const char *newpath)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
|
||||
SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
|
||||
RUBY_CRITICAL({
|
||||
if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
|
||||
SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
|
||||
|
||||
if (!MoveFile(oldpath, newpath))
|
||||
res = -1;
|
||||
if (!MoveFile(oldpath, newpath))
|
||||
res = -1;
|
||||
|
||||
if (res) {
|
||||
switch (GetLastError()) {
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
case ERROR_FILE_EXISTS:
|
||||
if (IsWinNT()) {
|
||||
if (MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
||||
res = 0;
|
||||
} else {
|
||||
for (;;) {
|
||||
if (!DeleteFile(newpath) && GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
break;
|
||||
else if (MoveFile(oldpath, newpath)) {
|
||||
if (res) {
|
||||
switch (GetLastError()) {
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
case ERROR_FILE_EXISTS:
|
||||
if (IsWinNT()) {
|
||||
if (MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
||||
res = 0;
|
||||
break;
|
||||
} else {
|
||||
for (;;) {
|
||||
if (!DeleteFile(newpath) && GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
break;
|
||||
else if (MoveFile(oldpath, newpath)) {
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res)
|
||||
errno = GetLastError();
|
||||
else
|
||||
SetFileAttributes(newpath, oldatts);
|
||||
if (res)
|
||||
errno = GetLastError();
|
||||
else
|
||||
SetFileAttributes(newpath, oldatts);
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@ -2617,6 +2659,7 @@ int
|
|||
win32_stat(const char *path, struct stat *st)
|
||||
{
|
||||
const char *p = path;
|
||||
int ret;
|
||||
|
||||
if ((isdirsep(*p) && (p++, TRUE)) || /* absolute path or UNC */
|
||||
(ISALPHA(*p) && p[1] == ':' && (p += 2, TRUE))) { /* has drive */
|
||||
|
@ -2630,7 +2673,8 @@ win32_stat(const char *path, struct stat *st)
|
|||
s[len] = '\0';
|
||||
path = s;
|
||||
}
|
||||
return stat(path, st);
|
||||
RUBY_CRITICAL(ret = stat(path, st));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long
|
||||
|
@ -2704,7 +2748,7 @@ static CRITICAL_SECTION* system_state(void)
|
|||
static LONG flag_interrupt = -1;
|
||||
static volatile DWORD tlsi_interrupt = TLS_OUT_OF_INDEXES;
|
||||
|
||||
void win32_disable_interrupt(void)
|
||||
void win32_enter_critical(void)
|
||||
{
|
||||
if (IsWinNT()) {
|
||||
EnterCriticalSection(system_state());
|
||||
|
@ -2725,7 +2769,7 @@ void win32_disable_interrupt(void)
|
|||
}
|
||||
}
|
||||
|
||||
void win32_enable_interrupt(void)
|
||||
void win32_leave_critical(void)
|
||||
{
|
||||
if (IsWinNT()) {
|
||||
LeaveCriticalSection(system_state());
|
||||
|
@ -2740,7 +2784,7 @@ struct handler_arg_t {
|
|||
void (*handler)(int);
|
||||
int arg;
|
||||
int status;
|
||||
int userstate;
|
||||
int finished;
|
||||
HANDLE handshake;
|
||||
};
|
||||
|
||||
|
@ -2753,8 +2797,8 @@ static void win32_call_handler(struct handler_arg_t* h)
|
|||
if (status) {
|
||||
rb_jump_tag(status);
|
||||
}
|
||||
h->userstate = 1; /* never syscall after here */
|
||||
for (;;); /* wait here in user state */
|
||||
h->finished = 1;
|
||||
Sleep(INFINITE); /* safe on Win95? */
|
||||
}
|
||||
|
||||
static struct handler_arg_t* setup_handler(struct handler_arg_t *harg,
|
||||
|
@ -2765,7 +2809,7 @@ static struct handler_arg_t* setup_handler(struct handler_arg_t *harg,
|
|||
harg->handler = handler;
|
||||
harg->arg = arg;
|
||||
harg->status = 0;
|
||||
harg->userstate = 0;
|
||||
harg->finished = 0;
|
||||
harg->handshake = handshake;
|
||||
return harg;
|
||||
}
|
||||
|
@ -2829,7 +2873,7 @@ int win32_main_context(int arg, void (*handler)(int))
|
|||
/* no exceptions raised, restore old context. */
|
||||
RUBY_CRITICAL({
|
||||
/* ensure the main thread is in user state. */
|
||||
yield_until(harg.userstate);
|
||||
yield_until(harg.finished);
|
||||
|
||||
SuspendThread(main_thread.handle);
|
||||
ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
|
||||
|
@ -2846,28 +2890,50 @@ int win32_main_context(int arg, void (*handler)(int))
|
|||
|
||||
int win32_sleep(unsigned long msec)
|
||||
{
|
||||
return wait_events(NULL, msec) != WAIT_TIMEOUT;
|
||||
DWORD ret;
|
||||
RUBY_CRITICAL(ret = wait_events(NULL, msec));
|
||||
yield_once();
|
||||
CHECK_INTS;
|
||||
return ret != WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
static void catch_interrupt(void)
|
||||
{
|
||||
yield_once();
|
||||
win32_sleep(0);
|
||||
RUBY_CRITICAL(wait_events(NULL, 0));
|
||||
CHECK_INTS;
|
||||
}
|
||||
|
||||
void win32_enter_syscall(void)
|
||||
#undef fgetc
|
||||
int win32_getc(FILE* stream)
|
||||
{
|
||||
InterlockedExchange(&rb_trap_immediate, 1);
|
||||
catch_interrupt();
|
||||
win32_disable_interrupt();
|
||||
int c, trap_immediate = rb_trap_immediate;
|
||||
if (--stream->_cnt >= 0) {
|
||||
c = (unsigned char)*stream->_ptr++;
|
||||
rb_trap_immediate = trap_immediate;
|
||||
}
|
||||
else {
|
||||
c = _filbuf(stream);
|
||||
rb_trap_immediate = trap_immediate;
|
||||
catch_interrupt();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void win32_leave_syscall(void)
|
||||
#undef fputc
|
||||
int win32_putc(int c, FILE* stream)
|
||||
{
|
||||
win32_enable_interrupt();
|
||||
catch_interrupt();
|
||||
InterlockedExchange(&rb_trap_immediate, 0);
|
||||
int trap_immediate = rb_trap_immediate;
|
||||
if (--stream->_cnt >= 0) {
|
||||
c = (unsigned char)(*stream->_ptr++ = (char)c);
|
||||
rb_trap_immediate = trap_immediate;
|
||||
}
|
||||
else {
|
||||
c = _flsbuf(c, stream);
|
||||
rb_trap_immediate = trap_immediate;
|
||||
catch_interrupt();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
struct asynchronous_arg_t {
|
||||
|
|
|
@ -112,6 +112,23 @@ extern "C++" {
|
|||
#define pid_t int
|
||||
#define WNOHANG -1
|
||||
|
||||
#undef getc
|
||||
#undef putc
|
||||
#undef fgetc
|
||||
#undef fputc
|
||||
#undef getchar
|
||||
#undef putchar
|
||||
#undef fgetchar
|
||||
#undef fputchar
|
||||
#define getc(_stream) win32_getc(_stream)
|
||||
#define putc(_c, _stream) win32_putc(_c, _stream)
|
||||
#define fgetc(_stream) getc(_stream)
|
||||
#define fputc(_c, _stream) putc(_c, _stream)
|
||||
#define getchar() win32_getc(stdin)
|
||||
#define putchar(_c) win32_putc(_c, stdout)
|
||||
#define fgetchar(_stream) getchar()
|
||||
#define fputchar(_c, _stream) putchar(_c)
|
||||
|
||||
#define access _access
|
||||
#define chmod _chmod
|
||||
#define chsize _chsize
|
||||
|
@ -427,10 +444,10 @@ struct tms {
|
|||
HANDLE GetCurrentThreadHandle(void);
|
||||
int win32_main_context(int arg, void (*handler)(int));
|
||||
int win32_sleep(unsigned long msec);
|
||||
void win32_enter_syscall(void);
|
||||
void win32_leave_syscall(void);
|
||||
void win32_disable_interrupt(void);
|
||||
void win32_enable_interrupt(void);
|
||||
void win32_enter_critical(void);
|
||||
void win32_leave_critical(void);
|
||||
int win32_putc(int, FILE*);
|
||||
int win32_getc(FILE*);
|
||||
#define Sleep(msec) (void)win32_sleep(msec)
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue