* 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
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>
|
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.
|
* 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>
|
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.
|
ends with '/' or '\' for mswin32 on Win9X / Win2k.
|
||||||
|
|
||||||
* win32/win32.h: ditto.
|
* 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))
|
# define ATOMIC_DEC(var) InterlockedDecrement(&(var))
|
||||||
|
|
||||||
/* Windows doesn't allow interrupt while system calls */
|
/* Windows doesn't allow interrupt while system calls */
|
||||||
# define TRAP_BEG win32_enter_syscall()
|
# define TRAP_BEG do {\
|
||||||
# define TRAP_END win32_leave_syscall()
|
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 {\
|
# define RUBY_CRITICAL(statements) do {\
|
||||||
win32_disable_interrupt();\
|
win32_enter_critical();\
|
||||||
statements;\
|
statements;\
|
||||||
win32_enable_interrupt();\
|
win32_leave_critical();\
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
typedef int rb_atomic_t;
|
typedef int rb_atomic_t;
|
||||||
|
284
win32/win32.c
284
win32/win32.c
@ -35,15 +35,17 @@
|
|||||||
#define bool int
|
#define bool int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
|
# define WIN95 1
|
||||||
|
#else
|
||||||
|
# undef WIN95
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_WSAWAITFORMULTIPLEEVENTS
|
||||||
|
# define USE_INTERRUPT_WINSOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
#if USE_INTERRUPT_WINSOCK
|
#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 WaitForMultipleEvents WSAWaitForMultipleEvents
|
||||||
# define CreateSignal() (HANDLE)WSACreateEvent()
|
# define CreateSignal() (HANDLE)WSACreateEvent()
|
||||||
# define SetSignal(ev) WSASetEvent(ev)
|
# define SetSignal(ev) WSASetEvent(ev)
|
||||||
@ -77,6 +79,7 @@ static DWORD wait_events(HANDLE event, DWORD timeout);
|
|||||||
|
|
||||||
char *NTLoginName;
|
char *NTLoginName;
|
||||||
|
|
||||||
|
#ifdef WIN95
|
||||||
DWORD Win32System = (DWORD)-1;
|
DWORD Win32System = (DWORD)-1;
|
||||||
|
|
||||||
static DWORD
|
static DWORD
|
||||||
@ -102,6 +105,10 @@ static int
|
|||||||
IsWinNT(void) {
|
IsWinNT(void) {
|
||||||
return (IdOS() == VER_PLATFORM_WIN32_NT);
|
return (IdOS() == VER_PLATFORM_WIN32_NT);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
# define IsWinNT() TRUE
|
||||||
|
# define IsWin95() FALSE
|
||||||
|
#endif
|
||||||
|
|
||||||
/* main thread constants */
|
/* main thread constants */
|
||||||
static struct {
|
static struct {
|
||||||
@ -177,6 +184,7 @@ flock_winnt(VALUE self, int argc, VALUE* argv)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN95
|
||||||
static VALUE
|
static VALUE
|
||||||
flock_win95(VALUE self, int argc, VALUE* argv)
|
flock_win95(VALUE self, int argc, VALUE* argv)
|
||||||
{
|
{
|
||||||
@ -207,6 +215,7 @@ flock_win95(VALUE self, int argc, VALUE* argv)
|
|||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef LK_ERR
|
#undef LK_ERR
|
||||||
#undef LK_LEN
|
#undef LK_LEN
|
||||||
@ -214,6 +223,7 @@ flock_win95(VALUE self, int argc, VALUE* argv)
|
|||||||
int
|
int
|
||||||
flock(int fd, int oper)
|
flock(int fd, int oper)
|
||||||
{
|
{
|
||||||
|
#ifdef WIN95
|
||||||
static asynchronous_func_t locker = NULL;
|
static asynchronous_func_t locker = NULL;
|
||||||
|
|
||||||
if (!locker) {
|
if (!locker) {
|
||||||
@ -222,6 +232,9 @@ flock(int fd, int oper)
|
|||||||
else
|
else
|
||||||
locker = flock_win95;
|
locker = flock_win95;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
const asynchronous_func_t locker = flock_winnt;
|
||||||
|
#endif
|
||||||
|
|
||||||
return win32_asynchronize(locker,
|
return win32_asynchronize(locker,
|
||||||
(VALUE)_get_osfhandle(fd), oper, NULL,
|
(VALUE)_get_osfhandle(fd), oper, NULL,
|
||||||
@ -1671,6 +1684,13 @@ EXTERN_C void __cdecl _unlock(int);
|
|||||||
#if defined _MT || defined __MSVCRT__
|
#if defined _MT || defined __MSVCRT__
|
||||||
#define MSVCRT_THREADS
|
#define MSVCRT_THREADS
|
||||||
#endif
|
#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 {
|
typedef struct {
|
||||||
long osfhnd; /* underlying OS file HANDLE */
|
long osfhnd; /* underlying OS file HANDLE */
|
||||||
@ -1704,20 +1724,6 @@ EXTERN_C _CRTIMP ioinfo * __pioinfo[];
|
|||||||
|
|
||||||
#define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = osfh)
|
#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
|
static int
|
||||||
my_open_osfhandle(long osfhandle, int flags)
|
my_open_osfhandle(long osfhandle, int flags)
|
||||||
{
|
{
|
||||||
@ -1736,22 +1742,27 @@ my_open_osfhandle(long osfhandle, int flags)
|
|||||||
if (flags & O_NOINHERIT)
|
if (flags & O_NOINHERIT)
|
||||||
fileflags |= FNOINHERIT;
|
fileflags |= FNOINHERIT;
|
||||||
|
|
||||||
/* attempt to allocate a C Runtime file handle */
|
RUBY_CRITICAL({
|
||||||
if ((fh = _alloc_osfhnd()) == -1) {
|
/* attempt to allocate a C Runtime file handle */
|
||||||
errno = EMFILE; /* too many open files */
|
HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
|
||||||
_doserrno = 0L; /* not an OS error */
|
fh = _open_osfhandle((long)hF, 0);
|
||||||
return -1; /* return error to caller */
|
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 */
|
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fh)->lock)));
|
||||||
_set_osfhnd(fh, osfhandle);
|
/* 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 */
|
_osfile(fh) = fileflags; /* set osfile entry */
|
||||||
#ifdef MSVCRT_THREADS
|
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fh)->lock));
|
||||||
LeaveCriticalSection(&_pioinfo(fh)->lock);
|
}
|
||||||
#endif
|
});
|
||||||
|
|
||||||
return fh; /* return handle */
|
return fh; /* return handle */
|
||||||
}
|
}
|
||||||
@ -1797,10 +1808,10 @@ myfddup (int fd)
|
|||||||
void
|
void
|
||||||
myfdclose(FILE *fp)
|
myfdclose(FILE *fp)
|
||||||
{
|
{
|
||||||
#if !defined MSVCRT_THREADS
|
RUBY_CRITICAL({
|
||||||
_free_osfhnd(fileno(fp));
|
STHREAD_ONLY(_free_osfhnd(fileno(fp)));
|
||||||
#endif
|
fclose(fp);
|
||||||
fclose(fp);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2035,7 +2046,8 @@ myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
|||||||
ex = &trap;
|
ex = &trap;
|
||||||
#endif /* USE_INTERRUPT_WINSOCK */
|
#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();
|
errno = WSAGetLastError();
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case WSAEINTR:
|
case WSAEINTR:
|
||||||
@ -2082,6 +2094,9 @@ StartSockets ()
|
|||||||
interrupted_event = CreateSignal();
|
interrupted_event = CreateSignal();
|
||||||
if (!interrupted_event)
|
if (!interrupted_event)
|
||||||
rb_fatal("Unable to create interrupt event!\n");
|
rb_fatal("Unable to create interrupt event!\n");
|
||||||
|
interrupted_event = CreateSignal();
|
||||||
|
if (!interrupted_event)
|
||||||
|
rb_fatal("Unable to create interrupt event!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef accept
|
#undef accept
|
||||||
@ -2094,7 +2109,8 @@ myaccept (SOCKET s, struct sockaddr *addr, int *addrlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return my_open_osfhandle(r, O_RDWR|O_BINARY);
|
return my_open_osfhandle(r, O_RDWR|O_BINARY);
|
||||||
}
|
}
|
||||||
@ -2109,7 +2125,8 @@ mybind (SOCKET s, struct sockaddr *addr, int addrlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2123,7 +2140,8 @@ myconnect (SOCKET s, struct sockaddr *addr, int addrlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2138,7 +2156,8 @@ mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2152,7 +2171,8 @@ mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2164,7 +2184,8 @@ mygetsockopt (SOCKET s, int level, int optname, char *optval, int *optlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2178,7 +2199,8 @@ myioctlsocket (SOCKET s, long cmd, u_long *argp)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2192,7 +2214,8 @@ mylisten (SOCKET s, int backlog)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = listen (TO_SOCKET(s), backlog)) == SOCKET_ERROR)
|
RUBY_CRITICAL(r = listen (TO_SOCKET(s), backlog));
|
||||||
|
if (r == SOCKET_ERROR)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2206,7 +2229,8 @@ myrecv (SOCKET s, char *buf, int len, int flags)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2221,7 +2245,8 @@ myrecvfrom (SOCKET s, char *buf, int len, int flags,
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2235,7 +2260,8 @@ mysend (SOCKET s, char *buf, int len, int flags)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2250,7 +2276,8 @@ mysendto (SOCKET s, char *buf, int len, int flags,
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
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();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2264,8 +2291,8 @@ mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen))
|
RUBY_CRITICAL(r = setsockopt (TO_SOCKET(s), level, optname, optval, optlen));
|
||||||
== SOCKET_ERROR)
|
if (r == SOCKET_ERROR)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2279,7 +2306,8 @@ myshutdown (SOCKET s, int how)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = shutdown (TO_SOCKET(s), how)) == SOCKET_ERROR)
|
RUBY_CRITICAL(r = shutdown (TO_SOCKET(s), how));
|
||||||
|
if (r == SOCKET_ERROR)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2293,7 +2321,8 @@ mysocket (int af, int type, int protocol)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
|
RUBY_CRITICAL(s = socket (af, type, protocol));
|
||||||
|
if (s == INVALID_SOCKET) {
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
|
//fprintf(stderr, "socket fail (%d)", WSAGetLastError());
|
||||||
}
|
}
|
||||||
@ -2309,7 +2338,8 @@ mygethostbyaddr (char *addr, int len, int type)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = gethostbyaddr (addr, len, type)) == NULL)
|
RUBY_CRITICAL(r = gethostbyaddr (addr, len, type));
|
||||||
|
if (r == NULL)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2323,7 +2353,8 @@ mygethostbyname (char *name)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = gethostbyname (name)) == NULL)
|
RUBY_CRITICAL(r = gethostbyname (name));
|
||||||
|
if (r == NULL)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2337,7 +2368,8 @@ mygethostname (char *name, int len)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = gethostname (name, len)) == SOCKET_ERROR)
|
RUBY_CRITICAL(r = gethostname (name, len));
|
||||||
|
if (r == SOCKET_ERROR)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2351,7 +2383,8 @@ mygetprotobyname (char *name)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = getprotobyname (name)) == NULL)
|
RUBY_CRITICAL(r = getprotobyname (name));
|
||||||
|
if (r == NULL)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2365,7 +2398,8 @@ mygetprotobynumber (int num)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = getprotobynumber (num)) == NULL)
|
RUBY_CRITICAL(r = getprotobynumber (num));
|
||||||
|
if (r == NULL)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2379,7 +2413,8 @@ mygetservbyname (char *name, char *proto)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = getservbyname (name, proto)) == NULL)
|
RUBY_CRITICAL(r = getservbyname (name, proto));
|
||||||
|
if (r == NULL)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2393,7 +2428,8 @@ mygetservbyport (int port, char *proto)
|
|||||||
if (!NtSocketsInitialized++) {
|
if (!NtSocketsInitialized++) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
if ((r = getservbyport (port, proto)) == NULL)
|
RUBY_CRITICAL(r = getservbyport (port, proto));
|
||||||
|
if (r == NULL)
|
||||||
errno = WSAGetLastError();
|
errno = WSAGetLastError();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2440,14 +2476,18 @@ waitpid (pid_t pid, int *stat_loc, int options)
|
|||||||
} else {
|
} else {
|
||||||
timeout = INFINITE;
|
timeout = INFINITE;
|
||||||
}
|
}
|
||||||
if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
|
RUBY_CRITICAL({
|
||||||
pid = _cwait(stat_loc, pid, 0);
|
if (wait_events((HANDLE)pid, timeout) == WAIT_OBJECT_0) {
|
||||||
|
pid = _cwait(stat_loc, pid, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pid = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
#if !defined __BORLANDC__
|
#if !defined __BORLANDC__
|
||||||
*stat_loc <<= 8;
|
if (pid) *stat_loc <<= 8;
|
||||||
#endif
|
#endif
|
||||||
return pid;
|
return pid;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
@ -2579,36 +2619,38 @@ myrename(const char *oldpath, const char *newpath)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
|
RUBY_CRITICAL({
|
||||||
SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
|
if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
|
||||||
|
SetFileAttributesA(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
|
||||||
|
|
||||||
if (!MoveFile(oldpath, newpath))
|
if (!MoveFile(oldpath, newpath))
|
||||||
res = -1;
|
res = -1;
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
switch (GetLastError()) {
|
switch (GetLastError()) {
|
||||||
case ERROR_ALREADY_EXISTS:
|
case ERROR_ALREADY_EXISTS:
|
||||||
case ERROR_FILE_EXISTS:
|
case ERROR_FILE_EXISTS:
|
||||||
if (IsWinNT()) {
|
if (IsWinNT()) {
|
||||||
if (MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING))
|
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)) {
|
|
||||||
res = 0;
|
res = 0;
|
||||||
break;
|
} else {
|
||||||
|
for (;;) {
|
||||||
|
if (!DeleteFile(newpath) && GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||||
|
break;
|
||||||
|
else if (MoveFile(oldpath, newpath)) {
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
errno = GetLastError();
|
errno = GetLastError();
|
||||||
else
|
else
|
||||||
SetFileAttributes(newpath, oldatts);
|
SetFileAttributes(newpath, oldatts);
|
||||||
|
});
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -2617,6 +2659,7 @@ int
|
|||||||
win32_stat(const char *path, struct stat *st)
|
win32_stat(const char *path, struct stat *st)
|
||||||
{
|
{
|
||||||
const char *p = path;
|
const char *p = path;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((isdirsep(*p) && (p++, TRUE)) || /* absolute path or UNC */
|
if ((isdirsep(*p) && (p++, TRUE)) || /* absolute path or UNC */
|
||||||
(ISALPHA(*p) && p[1] == ':' && (p += 2, TRUE))) { /* has drive */
|
(ISALPHA(*p) && p[1] == ':' && (p += 2, TRUE))) { /* has drive */
|
||||||
@ -2630,7 +2673,8 @@ win32_stat(const char *path, struct stat *st)
|
|||||||
s[len] = '\0';
|
s[len] = '\0';
|
||||||
path = s;
|
path = s;
|
||||||
}
|
}
|
||||||
return stat(path, st);
|
RUBY_CRITICAL(ret = stat(path, st));
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
@ -2704,7 +2748,7 @@ static CRITICAL_SECTION* system_state(void)
|
|||||||
static LONG flag_interrupt = -1;
|
static LONG flag_interrupt = -1;
|
||||||
static volatile DWORD tlsi_interrupt = TLS_OUT_OF_INDEXES;
|
static volatile DWORD tlsi_interrupt = TLS_OUT_OF_INDEXES;
|
||||||
|
|
||||||
void win32_disable_interrupt(void)
|
void win32_enter_critical(void)
|
||||||
{
|
{
|
||||||
if (IsWinNT()) {
|
if (IsWinNT()) {
|
||||||
EnterCriticalSection(system_state());
|
EnterCriticalSection(system_state());
|
||||||
@ -2725,7 +2769,7 @@ void win32_disable_interrupt(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void win32_enable_interrupt(void)
|
void win32_leave_critical(void)
|
||||||
{
|
{
|
||||||
if (IsWinNT()) {
|
if (IsWinNT()) {
|
||||||
LeaveCriticalSection(system_state());
|
LeaveCriticalSection(system_state());
|
||||||
@ -2740,7 +2784,7 @@ struct handler_arg_t {
|
|||||||
void (*handler)(int);
|
void (*handler)(int);
|
||||||
int arg;
|
int arg;
|
||||||
int status;
|
int status;
|
||||||
int userstate;
|
int finished;
|
||||||
HANDLE handshake;
|
HANDLE handshake;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2753,8 +2797,8 @@ static void win32_call_handler(struct handler_arg_t* h)
|
|||||||
if (status) {
|
if (status) {
|
||||||
rb_jump_tag(status);
|
rb_jump_tag(status);
|
||||||
}
|
}
|
||||||
h->userstate = 1; /* never syscall after here */
|
h->finished = 1;
|
||||||
for (;;); /* wait here in user state */
|
Sleep(INFINITE); /* safe on Win95? */
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct handler_arg_t* setup_handler(struct handler_arg_t *harg,
|
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->handler = handler;
|
||||||
harg->arg = arg;
|
harg->arg = arg;
|
||||||
harg->status = 0;
|
harg->status = 0;
|
||||||
harg->userstate = 0;
|
harg->finished = 0;
|
||||||
harg->handshake = handshake;
|
harg->handshake = handshake;
|
||||||
return harg;
|
return harg;
|
||||||
}
|
}
|
||||||
@ -2829,7 +2873,7 @@ int win32_main_context(int arg, void (*handler)(int))
|
|||||||
/* no exceptions raised, restore old context. */
|
/* no exceptions raised, restore old context. */
|
||||||
RUBY_CRITICAL({
|
RUBY_CRITICAL({
|
||||||
/* ensure the main thread is in user state. */
|
/* ensure the main thread is in user state. */
|
||||||
yield_until(harg.userstate);
|
yield_until(harg.finished);
|
||||||
|
|
||||||
SuspendThread(main_thread.handle);
|
SuspendThread(main_thread.handle);
|
||||||
ctx_orig.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
|
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)
|
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)
|
static void catch_interrupt(void)
|
||||||
{
|
{
|
||||||
yield_once();
|
yield_once();
|
||||||
win32_sleep(0);
|
RUBY_CRITICAL(wait_events(NULL, 0));
|
||||||
CHECK_INTS;
|
CHECK_INTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void win32_enter_syscall(void)
|
#undef fgetc
|
||||||
|
int win32_getc(FILE* stream)
|
||||||
{
|
{
|
||||||
InterlockedExchange(&rb_trap_immediate, 1);
|
int c, trap_immediate = rb_trap_immediate;
|
||||||
catch_interrupt();
|
if (--stream->_cnt >= 0) {
|
||||||
win32_disable_interrupt();
|
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();
|
int trap_immediate = rb_trap_immediate;
|
||||||
catch_interrupt();
|
if (--stream->_cnt >= 0) {
|
||||||
InterlockedExchange(&rb_trap_immediate, 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 {
|
struct asynchronous_arg_t {
|
||||||
|
@ -112,6 +112,23 @@ extern "C++" {
|
|||||||
#define pid_t int
|
#define pid_t int
|
||||||
#define WNOHANG -1
|
#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 access _access
|
||||||
#define chmod _chmod
|
#define chmod _chmod
|
||||||
#define chsize _chsize
|
#define chsize _chsize
|
||||||
@ -427,10 +444,10 @@ struct tms {
|
|||||||
HANDLE GetCurrentThreadHandle(void);
|
HANDLE GetCurrentThreadHandle(void);
|
||||||
int win32_main_context(int arg, void (*handler)(int));
|
int win32_main_context(int arg, void (*handler)(int));
|
||||||
int win32_sleep(unsigned long msec);
|
int win32_sleep(unsigned long msec);
|
||||||
void win32_enter_syscall(void);
|
void win32_enter_critical(void);
|
||||||
void win32_leave_syscall(void);
|
void win32_leave_critical(void);
|
||||||
void win32_disable_interrupt(void);
|
int win32_putc(int, FILE*);
|
||||||
void win32_enable_interrupt(void);
|
int win32_getc(FILE*);
|
||||||
#define Sleep(msec) (void)win32_sleep(msec)
|
#define Sleep(msec) (void)win32_sleep(msec)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user