1#ifndef RUBY_WIN32_H
2#define RUBY_WIN32_H 1
3
4#if defined(__cplusplus)
5extern "C" {
6#if 0
7} /* satisfy cc-mode */
8#endif
9#endif
10
11#if defined __GNUC__ && __GNUC__ >= 4
12#pragma GCC visibility push(default)
13#endif
14
15/*
16 *  Copyright (c) 1993, Intergraph Corporation
17 *
18 *  You may distribute under the terms of either the GNU General Public
19 *  License or the Artistic License, as specified in the perl README file.
20 *
21 */
22
23/*
24 * Definitions for NT port of Perl
25 */
26
27
28/*
29 * Ok now we can include the normal include files.
30 */
31
32/* #include <stdarg.h> conflict with varargs.h? */
33#if !defined(WSAAPI)
34#if defined(__cplusplus) && defined(_MSC_VER)
35extern "C++" {			/* template without extern "C++" */
36#endif
37#if !defined(_WIN64) && !defined(WIN32)
38#define WIN32
39#endif
40#include <winsock2.h>
41#include <ws2tcpip.h>
42#if defined(__cplusplus) && defined(_MSC_VER)
43}
44#endif
45#endif
46
47/*
48 * We're not using Microsoft's "extensions" to C for
49 * Structured Exception Handling (SEH) so we can nuke these
50 */
51#undef try
52#undef except
53#undef finally
54#undef leave
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59#include <direct.h>
60#include <process.h>
61#include <time.h>
62#if defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER == 1200
63extern "C++" {			/* template without extern "C++" */
64#endif
65#include <math.h>
66#if defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER == 1200
67}
68#endif
69#include <signal.h>
70#include <sys/stat.h>
71#include <sys/types.h>
72#ifdef HAVE_SYS_UTIME_H
73# include <sys/utime.h>
74#else
75# include <utime.h>
76#endif
77#include <io.h>
78#include <malloc.h>
79#if defined __MINGW32__ || __BORLANDC__ >= 0x0580
80# include <stdint.h>
81#else
82# if !defined(_INTPTR_T_DEFINED)
83#  ifdef _WIN64
84typedef __int64 intptr_t;
85#  else
86typedef int intptr_t;
87#  endif
88#  define _INTPTR_T_DEFINED
89# endif
90# if !defined(_UINTPTR_T_DEFINED)
91#  ifdef _WIN64
92typedef unsigned __int64 uintptr_t;
93#  else
94typedef unsigned int uintptr_t;
95#  endif
96#  define _UINTPTR_T_DEFINED
97# endif
98#endif
99#ifndef __MINGW32__
100# define mode_t int
101#endif
102#ifdef HAVE_UNISTD_H
103# include <unistd.h>
104#endif
105
106#define rb_w32_iswinnt()  TRUE
107#define rb_w32_iswin95()  FALSE
108
109#define WNOHANG -1
110
111#undef getc
112#undef putc
113#undef fgetc
114#undef fputc
115#undef getchar
116#undef putchar
117#undef fgetchar
118#undef fputchar
119#undef utime
120#undef lseek
121#undef stat
122#undef fstat
123#define getc(_stream)		rb_w32_getc(_stream)
124#define getchar()		rb_w32_getc(stdin)
125#define putc(_c, _stream)	rb_w32_putc(_c, _stream)
126#define putchar(_c)		rb_w32_putc(_c, stdout)
127#ifdef RUBY_EXPORT
128#define fgetc(_stream)		getc(_stream)
129#define fputc(_c, _stream)	putc(_c, _stream)
130#define fgetchar()		getchar()
131#define fputchar(_c)		putchar(_c)
132#define utime(_p, _t)		rb_w32_utime(_p, _t)
133#define lseek(_f, _o, _w)	_lseeki64(_f, _o, _w)
134
135#define pipe(p)			rb_w32_pipe(p)
136#define open			rb_w32_open
137#define close(h)		rb_w32_close(h)
138#define fclose(f)		rb_w32_fclose(f)
139#define read(f, b, s)		rb_w32_read(f, b, s)
140#define write(f, b, s)		rb_w32_write(f, b, s)
141#define getpid()		rb_w32_getpid()
142#define getppid()		rb_w32_getppid()
143#define sleep(x)		rb_w32_Sleep((x)*1000)
144#define Sleep(msec)		(void)rb_w32_Sleep(msec)
145#define fstati64(fd,st) 	rb_w32_fstati64(fd,st)
146#ifdef __BORLANDC__
147#define creat(p, m)		_creat(p, m)
148#define eof()			_eof()
149#define filelength(h)		_filelength(h)
150#define mktemp(t)		_mktemp(t)
151#define tell(h)			_tell(h)
152#define _open			_sopen
153#define sopen			_sopen
154#undef fopen
155#define fopen(p, m)		rb_w32_fopen(p, m)
156#undef fdopen
157#define fdopen(h, m)		rb_w32_fdopen(h, m)
158#undef fsopen
159#define fsopen(p, m, sh)	rb_w32_fsopen(p, m, sh)
160#endif /* __BORLANDC__ */
161
162#undef execv
163#define execv(path,argv)	rb_w32_aspawn(P_OVERLAY,path,argv)
164#if !defined(__BORLANDC__)
165#undef isatty
166#define isatty(h)		rb_w32_isatty(h)
167#endif /* __BORLANDC__ */
168
169#undef mkdir
170#define mkdir(p, m)		rb_w32_mkdir(p, m)
171#undef rmdir
172#define rmdir(p)		rb_w32_rmdir(p)
173#undef unlink
174#define unlink(p)		rb_w32_unlink(p)
175#endif /* RUBY_EXPORT */
176
177#if SIZEOF_OFF_T == 8
178#define off_t __int64
179#define stat stati64
180#define fstat(fd,st)		fstati64(fd,st)
181#if defined(__BORLANDC__)
182#define stati64(path, st) rb_w32_stati64(path, st)
183#elif !defined(_MSC_VER) || RT_VER < 80
184#define stati64 _stati64
185#ifndef _stati64
186#define _stati64(path, st) rb_w32_stati64(path, st)
187#endif
188#else
189#define stati64 _stat64
190#define _stat64(path, st) rb_w32_stati64(path, st)
191#endif
192#else
193#define stat(path,st)		rb_w32_stat(path,st)
194#define fstat(fd,st)		rb_w32_fstat(fd,st)
195extern int rb_w32_stat(const char *, struct stat *);
196extern int rb_w32_fstat(int, struct stat *);
197#endif
198#define access(path,mode)	rb_w32_access(path,mode)
199
200#define strcasecmp		_stricmp
201#define strncasecmp		_strnicmp
202#define fsync			_commit
203
204struct timezone;
205
206#ifdef __MINGW32__
207#undef isascii
208#define isascii __isascii
209#endif
210
211struct iovec {
212    void *iov_base;
213    size_t iov_len;
214};
215struct msghdr {
216    void *msg_name;
217    int msg_namelen;
218    struct iovec *msg_iov;
219    int msg_iovlen;
220    void *msg_control;
221    int msg_controllen;
222    int msg_flags;
223};
224
225extern DWORD  rb_w32_osid(void);
226extern int    rb_w32_cmdvector(const char *, char ***);
227extern rb_pid_t  rb_w32_pipe_exec(const char *, const char *, int, int *, int *);
228extern int    flock(int fd, int oper);
229extern int    rb_w32_io_cancelable_p(int);
230extern int    rb_w32_is_socket(int);
231extern int    WSAAPI rb_w32_accept(int, struct sockaddr *, int *);
232extern int    WSAAPI rb_w32_bind(int, const struct sockaddr *, int);
233extern int    WSAAPI rb_w32_connect(int, const struct sockaddr *, int);
234extern void   rb_w32_fdset(int, fd_set*);
235extern void   rb_w32_fdclr(int, fd_set*);
236extern int    rb_w32_fdisset(int, fd_set*);
237extern int    WSAAPI rb_w32_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
238extern int    WSAAPI rb_w32_getpeername(int, struct sockaddr *, int *);
239extern int    WSAAPI rb_w32_getsockname(int, struct sockaddr *, int *);
240extern int    WSAAPI rb_w32_getsockopt(int, int, int, char *, int *);
241extern int    WSAAPI rb_w32_ioctlsocket(int, long, u_long *);
242extern int    WSAAPI rb_w32_listen(int, int);
243extern int    WSAAPI rb_w32_recv(int, char *, int, int);
244extern int    WSAAPI rb_w32_recvfrom(int, char *, int, int, struct sockaddr *, int *);
245extern int    WSAAPI rb_w32_send(int, const char *, int, int);
246extern int    WSAAPI rb_w32_sendto(int, const char *, int, int, const struct sockaddr *, int);
247extern int    recvmsg(int, struct msghdr *, int);
248extern int    sendmsg(int, const struct msghdr *, int);
249extern int    WSAAPI rb_w32_setsockopt(int, int, int, const char *, int);
250extern int    WSAAPI rb_w32_shutdown(int, int);
251extern int    WSAAPI rb_w32_socket(int, int, int);
252extern SOCKET rb_w32_get_osfhandle(int);
253extern struct hostent *WSAAPI rb_w32_gethostbyaddr(const char *, int, int);
254extern struct hostent *WSAAPI rb_w32_gethostbyname(const char *);
255extern int    WSAAPI rb_w32_gethostname(char *, int);
256extern struct protoent *WSAAPI rb_w32_getprotobyname(const char *);
257extern struct protoent *WSAAPI rb_w32_getprotobynumber(int);
258extern struct servent  *WSAAPI rb_w32_getservbyname(const char *, const char *);
259extern struct servent  *WSAAPI rb_w32_getservbyport(int, const char *);
260extern int    rb_w32_socketpair(int, int, int, int *);
261extern char * rb_w32_getcwd(char *, int);
262extern char * rb_w32_ugetenv(const char *);
263extern char * rb_w32_getenv(const char *);
264extern int    rb_w32_rename(const char *, const char *);
265extern int    rb_w32_urename(const char *, const char *);
266extern char **rb_w32_get_environ(void);
267extern void   rb_w32_free_environ(char **);
268extern int    rb_w32_map_errno(DWORD);
269extern const char *WSAAPI rb_w32_inet_ntop(int,const void *,char *,size_t);
270extern DWORD  rb_w32_osver(void);
271
272extern int chown(const char *, int, int);
273extern int rb_w32_uchown(const char *, int, int);
274extern int link(const char *, const char *);
275extern int rb_w32_ulink(const char *, const char *);
276extern int gettimeofday(struct timeval *, struct timezone *);
277extern rb_pid_t waitpid (rb_pid_t, int *, int);
278extern rb_pid_t rb_w32_spawn(int, const char *, const char*);
279extern rb_pid_t rb_w32_aspawn(int, const char *, char *const *);
280extern rb_pid_t rb_w32_aspawn_flags(int, const char *, char *const *, DWORD);
281extern int kill(int, int);
282extern int fcntl(int, int, ...);
283extern rb_pid_t rb_w32_getpid(void);
284extern rb_pid_t rb_w32_getppid(void);
285#if !defined(__BORLANDC__)
286extern int rb_w32_isatty(int);
287#endif
288extern int rb_w32_uchdir(const char *);
289extern int rb_w32_mkdir(const char *, int);
290extern int rb_w32_umkdir(const char *, int);
291extern int rb_w32_rmdir(const char *);
292extern int rb_w32_urmdir(const char *);
293extern int rb_w32_unlink(const char *);
294extern int rb_w32_uunlink(const char *);
295extern int rb_w32_uchmod(const char *, int);
296extern int rb_w32_stati64(const char *, struct stati64 *);
297extern int rb_w32_ustati64(const char *, struct stati64 *);
298extern int rb_w32_access(const char *, int);
299extern int rb_w32_uaccess(const char *, int);
300extern char rb_w32_fd_is_text(int);
301extern int rb_w32_fstati64(int, struct stati64 *);
302
303#ifdef __BORLANDC__
304extern off_t _lseeki64(int, off_t, int);
305extern FILE *rb_w32_fopen(const char *, const char *);
306extern FILE *rb_w32_fdopen(int, const char *);
307extern FILE *rb_w32_fsopen(const char *, const char *, int);
308#endif
309
310#include <float.h>
311
312#if defined _MSC_VER && _MSC_VER >= 1800 && defined INFINITY
313#pragma warning(push)
314#pragma warning(disable:4756)
315static inline float
316rb_infinity_float(void)
317{
318    return INFINITY;
319}
320#pragma warning(pop)
321#undef INFINITY
322#define INFINITY rb_infinity_float()
323#endif
324
325#if !defined __MINGW32__ || defined __NO_ISOCEXT
326#ifndef isnan
327#define isnan(x) _isnan(x)
328#endif
329static inline int
330finite(double x)
331{
332    return _finite(x);
333}
334#ifndef copysign
335#define copysign(a, b) _copysign(a, b)
336#endif
337static inline double
338scalb(double a, long b)
339{
340    return _scalb(a, b);
341}
342#endif
343
344#if !defined S_IFIFO && defined _S_IFIFO
345#define S_IFIFO _S_IFIFO
346#endif
347
348#if 0 && defined __BORLANDC__
349#undef S_ISDIR
350#undef S_ISFIFO
351#undef S_ISBLK
352#undef S_ISCHR
353#undef S_ISREG
354#define S_ISDIR(m)  (((unsigned short)(m) & S_IFMT) == S_IFDIR)
355#define S_ISFIFO(m) (((unsigned short)(m) & S_IFMT) == S_IFIFO)
356#define S_ISBLK(m)  (((unsigned short)(m) & S_IFMT) == S_IFBLK)
357#define S_ISCHR(m)  (((unsigned short)(m) & S_IFMT) == S_IFCHR)
358#define S_ISREG(m)  (((unsigned short)(m) & S_IFMT) == S_IFREG)
359#endif
360
361#if !defined S_IRUSR && !defined __MINGW32__
362#define S_IRUSR 0400
363#endif
364#ifndef S_IRGRP
365#define S_IRGRP 0040
366#endif
367#ifndef S_IROTH
368#define S_IROTH 0004
369#endif
370
371#if !defined S_IWUSR && !defined __MINGW32__
372#define S_IWUSR 0200
373#endif
374#ifndef S_IWGRP
375#define S_IWGRP 0020
376#endif
377#ifndef S_IWOTH
378#define S_IWOTH 0002
379#endif
380
381#if !defined S_IXUSR && !defined __MINGW32__
382#define S_IXUSR 0100
383#endif
384#ifndef S_IXGRP
385#define S_IXGRP 0010
386#endif
387#ifndef S_IXOTH
388#define S_IXOTH 0001
389#endif
390
391/*
392 * define this so we can do inplace editing
393 */
394
395#define SUFFIX
396
397extern int 	 rb_w32_ftruncate(int fd, off_t length);
398extern int 	 rb_w32_truncate(const char *path, off_t length);
399extern off_t	 rb_w32_ftello(FILE *stream);
400extern int 	 rb_w32_fseeko(FILE *stream, off_t offset, int whence);
401
402#undef HAVE_FTRUNCATE
403#define HAVE_FTRUNCATE 1
404#if defined HAVE_FTRUNCATE64
405#define ftruncate ftruncate64
406#else
407#define ftruncate rb_w32_ftruncate
408#endif
409
410#undef HAVE_TRUNCATE
411#define HAVE_TRUNCATE 1
412#if defined HAVE_TRUNCATE64
413#define truncate truncate64
414#else
415#define truncate rb_w32_truncate
416#endif
417
418#undef HAVE_FSEEKO
419#define HAVE_FSEEKO 1
420#if defined HAVE_FSEEKO64
421#define fseeko fseeko64
422#else
423#define fseeko rb_w32_fseeko
424#endif
425
426#undef HAVE_FTELLO
427#define HAVE_FTELLO 1
428#if defined HAVE_FTELLO64
429#define ftello ftello64
430#else
431#define ftello rb_w32_ftello
432#endif
433
434/*
435 * stubs
436 */
437extern int       ioctl (int, int, ...);
438extern rb_uid_t  getuid (void);
439extern rb_uid_t  geteuid (void);
440extern rb_gid_t  getgid (void);
441extern rb_gid_t  getegid (void);
442extern int       setuid (rb_uid_t);
443extern int       setgid (rb_gid_t);
444
445extern char *rb_w32_strerror(int);
446
447#ifdef RUBY_EXPORT
448#define strerror(e) rb_w32_strerror(e)
449#endif
450
451#define PIPE_BUF 1024
452
453#define LOCK_SH 1
454#define LOCK_EX 2
455#define LOCK_NB 4
456#define LOCK_UN 8
457
458
459#ifndef SIGINT
460#define SIGINT 2
461#endif
462#ifndef SIGKILL
463#define SIGKILL	9
464#endif
465
466
467/* #undef va_start */
468/* #undef va_end */
469
470/* winsock error map */
471#include <errno.h>
472
473#ifndef EWOULDBLOCK
474# define EWOULDBLOCK		WSAEWOULDBLOCK
475#endif
476#ifndef EINPROGRESS
477# define EINPROGRESS		WSAEINPROGRESS
478#endif
479#ifndef EALREADY
480# define EALREADY		WSAEALREADY
481#endif
482#ifndef ENOTSOCK
483# define ENOTSOCK		WSAENOTSOCK
484#endif
485#ifndef EDESTADDRREQ
486# define EDESTADDRREQ		WSAEDESTADDRREQ
487#endif
488#ifndef EMSGSIZE
489# define EMSGSIZE		WSAEMSGSIZE
490#endif
491#ifndef EPROTOTYPE
492# define EPROTOTYPE		WSAEPROTOTYPE
493#endif
494#ifndef ENOPROTOOPT
495# define ENOPROTOOPT		WSAENOPROTOOPT
496#endif
497#ifndef EPROTONOSUPPORT
498# define EPROTONOSUPPORT	WSAEPROTONOSUPPORT
499#endif
500#ifndef ESOCKTNOSUPPORT
501# define ESOCKTNOSUPPORT	WSAESOCKTNOSUPPORT
502#endif
503#ifndef EOPNOTSUPP
504# define EOPNOTSUPP		WSAEOPNOTSUPP
505#endif
506#ifndef EPFNOSUPPORT
507# define EPFNOSUPPORT		WSAEPFNOSUPPORT
508#endif
509#ifndef EAFNOSUPPORT
510# define EAFNOSUPPORT		WSAEAFNOSUPPORT
511#endif
512#ifndef EADDRINUSE
513# define EADDRINUSE		WSAEADDRINUSE
514#endif
515#ifndef EADDRNOTAVAIL
516# define EADDRNOTAVAIL		WSAEADDRNOTAVAIL
517#endif
518#ifndef ENETDOWN
519# define ENETDOWN		WSAENETDOWN
520#endif
521#ifndef ENETUNREACH
522# define ENETUNREACH		WSAENETUNREACH
523#endif
524#ifndef ENETRESET
525# define ENETRESET		WSAENETRESET
526#endif
527#ifndef ECONNABORTED
528# define ECONNABORTED		WSAECONNABORTED
529#endif
530#ifndef ECONNRESET
531# define ECONNRESET		WSAECONNRESET
532#endif
533#ifndef ENOBUFS
534# define ENOBUFS		WSAENOBUFS
535#endif
536#ifndef EISCONN
537# define EISCONN		WSAEISCONN
538#endif
539#ifndef ENOTCONN
540# define ENOTCONN		WSAENOTCONN
541#endif
542#ifndef ESHUTDOWN
543# define ESHUTDOWN		WSAESHUTDOWN
544#endif
545#ifndef ETOOMANYREFS
546# define ETOOMANYREFS		WSAETOOMANYREFS
547#endif
548#ifndef ETIMEDOUT
549# define ETIMEDOUT		WSAETIMEDOUT
550#endif
551#ifndef ECONNREFUSED
552# define ECONNREFUSED		WSAECONNREFUSED
553#endif
554#ifndef ELOOP
555# define ELOOP			WSAELOOP
556#endif
557/*#define ENAMETOOLONG	WSAENAMETOOLONG*/
558#ifndef EHOSTDOWN
559# define EHOSTDOWN		WSAEHOSTDOWN
560#endif
561#ifndef EHOSTUNREACH
562# define EHOSTUNREACH		WSAEHOSTUNREACH
563#endif
564/*#define ENOTEMPTY	WSAENOTEMPTY*/
565#ifndef EPROCLIM
566# define EPROCLIM		WSAEPROCLIM
567#endif
568#ifndef EUSERS
569# define EUSERS			WSAEUSERS
570#endif
571#ifndef EDQUOT
572# define EDQUOT			WSAEDQUOT
573#endif
574#ifndef ESTALE
575# define ESTALE			WSAESTALE
576#endif
577#ifndef EREMOTE
578# define EREMOTE		WSAEREMOTE
579#endif
580
581#define F_DUPFD 0
582#if 0
583#define F_GETFD 1
584#define F_SETFD 2
585#define F_GETFL 3
586#endif
587#define F_SETFL 4
588#if 0
589#define FD_CLOEXEC 1 /* F_GETFD, F_SETFD */
590#endif
591#define O_NONBLOCK 1
592
593#undef FD_SET
594#define FD_SET(fd, set)	do {\
595    unsigned int i;\
596    SOCKET s = _get_osfhandle(fd);\
597\
598    for (i = 0; i < (set)->fd_count; i++) {\
599        if ((set)->fd_array[i] == s) {\
600            break;\
601        }\
602    }\
603    if (i == (set)->fd_count) {\
604        if ((set)->fd_count < FD_SETSIZE) {\
605            (set)->fd_array[i] = s;\
606            (set)->fd_count++;\
607        }\
608    }\
609} while(0)
610
611#undef FD_CLR
612#define FD_CLR(f, s)		rb_w32_fdclr(f, s)
613
614#undef FD_ISSET
615#define FD_ISSET(f, s)		rb_w32_fdisset(f, s)
616
617#ifdef RUBY_EXPORT
618#undef inet_ntop
619#define inet_ntop(f,a,n,l)      rb_w32_inet_ntop(f,a,n,l)
620
621#undef accept
622#define accept(s, a, l)		rb_w32_accept(s, a, l)
623
624#undef bind
625#define bind(s, a, l)		rb_w32_bind(s, a, l)
626
627#undef connect
628#define connect(s, a, l)	rb_w32_connect(s, a, l)
629
630#undef select
631#define select(n, r, w, e, t)	rb_w32_select(n, r, w, e, t)
632
633#undef getpeername
634#define getpeername(s, a, l)	rb_w32_getpeername(s, a, l)
635
636#undef getsockname
637#define getsockname(s, a, l)	rb_w32_getsockname(s, a, l)
638
639#undef getsockopt
640#define getsockopt(s, v, n, o, l) rb_w32_getsockopt(s, v, n, o, l)
641
642#undef ioctlsocket
643#define ioctlsocket(s, c, a)	rb_w32_ioctlsocket(s, c, a)
644
645#undef listen
646#define listen(s, b)		rb_w32_listen(s, b)
647
648#undef recv
649#define recv(s, b, l, f)	rb_w32_recv(s, b, l, f)
650
651#undef recvfrom
652#define recvfrom(s, b, l, f, fr, frl) rb_w32_recvfrom(s, b, l, f, fr, frl)
653
654#undef send
655#define send(s, b, l, f)	rb_w32_send(s, b, l, f)
656
657#undef sendto
658#define sendto(s, b, l, f, t, tl) rb_w32_sendto(s, b, l, f, t, tl)
659
660#undef setsockopt
661#define setsockopt(s, v, n, o, l) rb_w32_setsockopt(s, v, n, o, l)
662
663#undef shutdown
664#define shutdown(s, h)		rb_w32_shutdown(s, h)
665
666#undef socket
667#define socket(s, t, p)		rb_w32_socket(s, t, p)
668
669#undef gethostbyaddr
670#define gethostbyaddr(a, l, t)	rb_w32_gethostbyaddr(a, l, t)
671
672#undef gethostbyname
673#define gethostbyname(n)	rb_w32_gethostbyname(n)
674
675#undef gethostname
676#define gethostname(n, l)	rb_w32_gethostname(n, l)
677
678#undef getprotobyname
679#define getprotobyname(n)	rb_w32_getprotobyname(n)
680
681#undef getprotobynumber
682#define getprotobynumber(n)	rb_w32_getprotobynumber(n)
683
684#undef getservbyname
685#define getservbyname(n, p)	rb_w32_getservbyname(n, p)
686
687#undef getservbyport
688#define getservbyport(p, pr)	rb_w32_getservbyport(p, pr)
689
690#undef socketpair
691#define socketpair(a, t, p, s)	rb_w32_socketpair(a, t, p, s)
692
693#undef get_osfhandle
694#define get_osfhandle(h)	rb_w32_get_osfhandle(h)
695
696#undef getcwd
697#define getcwd(b, s)		rb_w32_getcwd(b, s)
698
699#undef getenv
700#define getenv(n)		rb_w32_getenv(n)
701
702#undef rename
703#define rename(o, n)		rb_w32_rename(o, n)
704
705#undef times
706#define times(t)		rb_w32_times(t)
707#endif
708
709struct tms {
710	long	tms_utime;
711	long	tms_stime;
712	long	tms_cutime;
713	long	tms_cstime;
714};
715
716int rb_w32_times(struct tms *);
717
718struct tm *gmtime_r(const time_t *, struct tm *);
719struct tm *localtime_r(const time_t *, struct tm *);
720
721/* thread stuff */
722int  rb_w32_sleep(unsigned long msec);
723int  rb_w32_putc(int, FILE*);
724int  rb_w32_getc(FILE*);
725int  rb_w32_open(const char *, int, ...);
726int  rb_w32_uopen(const char *, int, ...);
727int  rb_w32_wopen(const WCHAR *, int, ...);
728int  rb_w32_close(int);
729int  rb_w32_fclose(FILE*);
730int  rb_w32_pipe(int[2]);
731ssize_t rb_w32_read(int, void *, size_t);
732ssize_t rb_w32_write(int, const void *, size_t);
733int  rb_w32_utime(const char *, const struct utimbuf *);
734int  rb_w32_uutime(const char *, const struct utimbuf *);
735long rb_w32_write_console(uintptr_t, int);	/* use uintptr_t instead of VALUE because it's not defined yet here */
736int  WINAPI rb_w32_Sleep(unsigned long msec);
737int  rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout);
738int  rb_w32_time_subtract(struct timeval *rest, const struct timeval *wait);
739int  rb_w32_wrap_io_handle(HANDLE, int);
740int  rb_w32_unwrap_io_handle(int);
741
742/*
743== ***CAUTION***
744Since this function is very dangerous, ((*NEVER*))
745* lock any HANDLEs(i.e. Mutex, Semaphore, CriticalSection and so on) or,
746* use anything like TRAP_BEG...TRAP_END block structure,
747in asynchronous_func_t.
748*/
749typedef uintptr_t (*asynchronous_func_t)(uintptr_t self, int argc, uintptr_t* argv);
750uintptr_t rb_w32_asynchronize(asynchronous_func_t func, uintptr_t self, int argc, uintptr_t* argv, uintptr_t intrval);
751
752#if defined __GNUC__ && __GNUC__ >= 4
753#pragma GCC visibility pop
754#endif
755
756#ifdef __MINGW_ATTRIB_PURE
757/* License: Ruby's */
758/* get rid of bugs in math.h of mingw */
759#define frexp(_X, _Y) __extension__ ({\
760    int intpart_frexp_bug = intpart_frexp_bug;\
761    double result_frexp_bug = frexp((_X), &intpart_frexp_bug);\
762    *(_Y) = intpart_frexp_bug;\
763    result_frexp_bug;\
764})
765/* License: Ruby's */
766#define modf(_X, _Y) __extension__ ({\
767    double intpart_modf_bug = intpart_modf_bug;\
768    double result_modf_bug = modf((_X), &intpart_modf_bug);\
769    *(_Y) = intpart_modf_bug;\
770    result_modf_bug;\
771})
772#endif
773
774#if defined(__cplusplus)
775#if 0
776{ /* satisfy cc-mode */
777#endif
778}  /* extern "C" { */
779#endif
780
781#if defined(__MINGW64__)
782/*
783 * Use powl() instead of broken pow() of x86_64-w64-mingw32.
784 * This workaround will fix test failures in test_bignum.rb,
785 * test_fixnum.rb and test_float.rb etc.
786 */
787static inline double
788rb_w32_pow(double x, double y)
789{
790    return powl(x, y);
791}
792#elif defined(__MINGW64_VERSION_MAJOR)
793/*
794 * Set floating point precision for pow() of mingw-w64 x86.
795 * With default precision the result is not proper on WinXP.
796 */
797static inline double
798rb_w32_pow(double x, double y)
799{
800    double r;
801    unsigned int default_control = _controlfp(0, 0);
802    _controlfp(_PC_64, _MCW_PC);
803    r = pow(x, y);
804    /* Restore setting */
805    _controlfp(default_control, _MCW_PC);
806    return r;
807}
808#endif
809#if defined(__MINGW64_VERSION_MAJOR) || defined(__MINGW64__)
810#define pow rb_w32_pow
811#endif
812
813#endif /* RUBY_WIN32_H */
814