xref: /openbsd/gnu/usr.bin/perl/win32/win32.h (revision e0680481)
1 /* WIN32.H
2  *
3  * (c) 1995 Microsoft Corporation. All rights reserved.
4  * 		Developed by hip communications inc.
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  */
9 #ifndef  _INC_WIN32_PERL5
10 #define  _INC_WIN32_PERL5
11 
12 #ifndef _WIN32_WINNT
13 #  define _WIN32_WINNT 0x0500     /* needed for CreateHardlink() etc. */
14 #endif
15 
16 /* Win32 only optimizations for faster building */
17 #ifdef PERL_IS_MINIPERL
18 /* less I/O calls during each require */
19 #  define PERL_DISABLE_PMC
20 
21 /* unnecessary for miniperl to lookup anything from an "installed" perl */
22 #  define WIN32_NO_REGISTRY
23 
24 /* allow minitest to work */
25 #  define PERL_TEXTMODE_SCRIPTS
26 #endif
27 
28 #if defined(PERL_IMPLICIT_SYS)
29 #  define DYNAMIC_ENV_FETCH
30 #  define HAS_GETENV_LEN
31 #  define WIN32IO_IS_STDIO		/* don't pull in custom stdio layer */
32 #  define WIN32SCK_IS_STDSCK		/* don't pull in custom wsock layer */
33 #endif
34 
35 #ifdef __GNUC__
36 #  ifndef __int64		/* some versions seem to #define it already */
37 #    define __int64 long long
38 #  endif
39 #  define Win32_Winsock
40 #endif
41 
42 
43 /* Define DllExport akin to perl's EXT,
44  * If we are in the DLL then Export the symbol,
45  * otherwise import it.
46  */
47 
48 /* now even GCC supports __declspec() */
49 /* miniperl has no reason to export anything */
50 #if defined(PERL_IS_MINIPERL)
51 #  define DllExport
52 #else
53 #  if defined(PERLDLL)
54 #    define DllExport __declspec(dllexport)
55 #  else
56 #    define DllExport __declspec(dllimport)
57 #  endif
58 #endif
59 
60 /* The Perl APIs can only be called directly inside the perl5xx.dll.
61  * All other code has to import them.  By declaring them as "dllimport"
62  * we tell the compiler to generate an indirect call instruction and
63  * avoid redirection through a call thunk.
64  *
65  * The XS code in the re extension is special, in that it redefines
66  * core APIs locally, so don't mark them as "dllimport" because GCC
67  * cannot handle this situation.
68  *
69  * Certain old GCCs will not allow the function pointer of dllimport marked
70  * function to be "const". This was fixed later on. Since this is a
71  * deoptimization, target "gcc version 3.4.5 (mingw-vista special r3)" only,
72  * The GCC bug was fixed in GCC patch "varasm.c (initializer_constant_valid_p):
73  * Don't deny DECL_DLLIMPORT_P on functions", which probably was first released
74  * in GCC 4.3.0, this #if can be expanded upto but not including 4.3.0 if more
75  * deployed GCC are found that wont build with the follow error, initializer
76  * element is a PerlIO func exported from perl5xx.dll.
77  *
78  * encoding.xs:610: error: initializer element is not constant
79  * encoding.xs:610: error: (near initialization for `PerlIO_encode.Open')
80  */
81 
82 #if (defined(__GNUC__) && defined(__MINGW32__) && \
83      !defined(__MINGW64_VERSION_MAJOR) && !defined(__clang__) && \
84         ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 5))))
85 /* use default fallbacks from perl.h for this particular GCC */
86 #else
87 #  if !defined(PERLDLL) && !defined(PERL_EXT_RE_BUILD)
88 #    ifdef __cplusplus
89 #      define PERL_CALLCONV extern "C" __declspec(dllimport)
90 #      ifdef _MSC_VER
91 #        define PERL_CALLCONV_NO_RET extern "C" __declspec(dllimport) __declspec(noreturn)
92 #      endif
93 #    else
94 #      define PERL_CALLCONV __declspec(dllimport)
95 #      ifdef _MSC_VER
96 #        define PERL_CALLCONV_NO_RET __declspec(dllimport) __declspec(noreturn)
97 #      endif
98 #    endif
99 #  else /* MSVC noreturn support inside the interp */
100 #    ifdef _MSC_VER
101 #      define PERL_CALLCONV_NO_RET __declspec(noreturn)
102 #    endif
103 #  endif
104 #endif
105 
106 #ifdef _MSC_VER
107 #  define PERL_STATIC_NO_RET __declspec(noreturn) static
108 #  define PERL_STATIC_INLINE_NO_RET __declspec(noreturn) PERL_STATIC_INLINE
109 #  define PERL_STATIC_FORCE_INLINE __forceinline static
110 #  define PERL_STATIC_FORCE_INLINE_NO_RET __declspec(noreturn) __forceinline static
111 #endif
112 
113 #define  WIN32_LEAN_AND_MEAN
114 #include <windows.h>
115 
116 /*
117  * Bug in winbase.h in mingw-w64 4.4.0-1 at least... they
118  * do #define GetEnvironmentStringsA GetEnvironmentStrings and fail
119  * to declare GetEnvironmentStringsA.
120  */
121 #if defined(__MINGW64__) && defined(GetEnvironmentStringsA) && !defined(UNICODE)
122 #ifdef __cplusplus
123 extern "C" {
124 #endif
125 #undef GetEnvironmentStringsA
126 WINBASEAPI LPCH WINAPI GetEnvironmentStringsA(VOID);
127 #define GetEnvironmentStrings GetEnvironmentStringsA
128 #ifdef __cplusplus
129 }
130 #endif
131 #endif
132 
133 #ifdef   WIN32_LEAN_AND_MEAN		/* C file is NOT a Perl5 original. */
134 #define  CONTEXT	PERL_CONTEXT	/* Avoid conflict of CONTEXT defs. */
135 #endif /*WIN32_LEAN_AND_MEAN */
136 
137 #ifndef TLS_OUT_OF_INDEXES
138 #define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
139 #endif
140 
141 #include <dirent.h>
142 #include <io.h>
143 #include <process.h>
144 #include <stdio.h>
145 #include <direct.h>
146 #include <stdlib.h>
147 #include <stddef.h>
148 #include <fcntl.h>
149 #ifndef EXT
150 #include "EXTERN.h"
151 #endif
152 
153 struct tms {
154         long	tms_utime;
155         long	tms_stime;
156         long	tms_cutime;
157         long	tms_cstime;
158 };
159 
160 #ifndef SYS_NMLN
161 #define SYS_NMLN	257
162 #endif
163 
164 struct utsname {
165     char sysname[SYS_NMLN];
166     char nodename[SYS_NMLN];
167     char release[SYS_NMLN];
168     char version[SYS_NMLN];
169     char machine[SYS_NMLN];
170 };
171 
172 #ifndef START_EXTERN_C
173 #undef EXTERN_C
174 #ifdef __cplusplus
175 #  define START_EXTERN_C extern "C" {
176 #  define END_EXTERN_C }
177 #  define EXTERN_C extern "C"
178 #else
179 #  define START_EXTERN_C
180 #  define END_EXTERN_C
181 #  define EXTERN_C
182 #endif
183 #endif
184 
185 #define  DOSISH		1		/* no escaping our roots */
186 #define  OP_BINARY	O_BINARY	/* mistake in in pp_sys.c? */
187 
188 /* read() and write() aren't transparent for socket handles */
189 #ifndef WIN32_NO_SOCKETS
190 #  define PERL_SOCK_SYSREAD_IS_RECV
191 #  define PERL_SOCK_SYSWRITE_IS_SEND
192 #endif
193 
194 #ifdef WIN32_NO_REGISTRY
195 /* the last _ in WIN32_NO_REGISTRY_M_ is like the _ in aTHX_ */
196 #  define WIN32_NO_REGISTRY_M_(x)
197 #else
198 #  define WIN32_NO_REGISTRY_M_(x) x,
199 #endif
200 
201 #define ENV_IS_CASELESS
202 
203 #define PIPESOCK_MODE	"b"		/* pipes, sockets default to binmode */
204 
205 /* access() mode bits */
206 #ifndef R_OK
207 #  define R_OK  4
208 #  define W_OK  2
209 #  define X_OK  1
210 #  define F_OK  0
211 #endif
212 
213 /* for waitpid() */
214 #ifndef WNOHANG
215 #  define WNOHANG	1
216 #endif
217 
218 #define PERL_GET_CONTEXT_DEFINED
219 
220 /* Compiler-specific stuff. */
221 
222 /* VC uses non-standard way to determine the size and alignment if bit-fields */
223 /* MinGW will compile with -mms-bitfields, so should use the same types */
224 #define PERL_BITFIELD8  U8
225 #define PERL_BITFIELD16 U16
226 #define PERL_BITFIELD32 U32
227 
228 #ifdef _MSC_VER			/* Microsoft Visual C++ */
229 
230 typedef long		uid_t;
231 typedef long		gid_t;
232 typedef unsigned short	mode_t;
233 
234 #define snprintf	_snprintf
235 #define vsnprintf	_vsnprintf
236 
237 MSVC_DIAG_IGNORE(4756 4056)
238 PERL_STATIC_INLINE
S_Infinity()239 double S_Infinity() {
240     /* this is a real C literal which can get further constant folded
241        unlike using HUGE_VAL/_HUGE which are data symbol imports from the CRT
242        and therefore can not by folded by VC, an example of constant
243        folding INF is creating -INF */
244     return (DBL_MAX+DBL_MAX);
245 }
246 MSVC_DIAG_RESTORE
247 
248 #define NV_INF S_Infinity()
249 
250 /* selectany allows duplicate and unused data symbols to be removed by
251    VC linker, if this were static, each translation unit will have its own,
252    usually unused __PL_nan_u, if this were plain extern it will cause link
253    to fail due to multiple definitions, since we dont know if we are being
254    compiled as static or DLL XS, selectany simply always works, the cost of
255    importing __PL_nan_u across DLL boundaries in size in the importing DLL
256    will be more than the 8 bytes it will take up being in each XS DLL if
257    that DLL actually uses __PL_nan_u */
258 union PerlNan { unsigned __int64 __q; double __d; };
259 extern const __declspec(selectany) union PerlNan __PL_nan_u = { 0x7FF8000000000000UI64 };
260 #define NV_NAN ((NV)__PL_nan_u.__d)
261 
262 /* The CRT was rewritten in VS2015. */
263 #if _MSC_VER >= 1900
264 
265 /* No longer declared in stdio.h */
266 EXTERN_C char *gets(char* buffer);
267 
268 #define tzname _tzname
269 
270 /* From corecrt_internal_stdio.h: */
271 typedef struct
272 {
273     union
274     {
275         FILE  _public_file;
276         char* _ptr;
277     };
278 
279     char*            _base;
280     int              _cnt;
281     long             _flags;
282     long             _file;
283     int              _charbuf;
284     int              _bufsiz;
285     char*            _tmpfname;
286     CRITICAL_SECTION _lock;
287 } __crt_stdio_stream_data;
288 
289 #define PERLIO_FILE_flag_RD 0x0001 /* _IOREAD   */
290 #define PERLIO_FILE_flag_WR 0x0002 /* _IOWRITE  */
291 #define PERLIO_FILE_flag_RW 0x0004 /* _IOUPDATE */
292 #define PERLIO_FILE_ptr(f)  (((__crt_stdio_stream_data*)(f))->_ptr)
293 #define PERLIO_FILE_base(f) (((__crt_stdio_stream_data*)(f))->_base)
294 #define PERLIO_FILE_cnt(f)  (((__crt_stdio_stream_data*)(f))->_cnt)
295 #define PERLIO_FILE_flag(f) ((int)(((__crt_stdio_stream_data*)(f))->_flags))
296 #define PERLIO_FILE_file(f) (*(int*)(&((__crt_stdio_stream_data*)(f))->_file))
297 
298 #endif
299 
300 #endif /* _MSC_VER */
301 
302 #if (!defined(_MSC_VER)) || (defined(_MSC_VER) && _MSC_VER < 1900)
303 
304 /* Note: PERLIO_FILE_ptr/base/cnt are not actually used for GCC or <VS2015
305  * since FILE_ptr/base/cnt do the same thing anyway but it doesn't hurt to
306  * define them all here for completeness. */
307 #define PERLIO_FILE_flag_RD _IOREAD /* 0x001 */
308 #define PERLIO_FILE_flag_WR _IOWRT  /* 0x002 */
309 #define PERLIO_FILE_flag_RW _IORW   /* 0x080 */
310 #define PERLIO_FILE_ptr(f)  ((f)->_ptr)
311 #define PERLIO_FILE_base(f) ((f)->_base)
312 #define PERLIO_FILE_cnt(f)  ((f)->_cnt)
313 #define PERLIO_FILE_flag(f) ((f)->_flag)
314 #define PERLIO_FILE_file(f) ((f)->_file)
315 
316 #endif
317 
318 #ifdef __MINGW32__		/* Minimal Gnu-Win32 */
319 
320 typedef long		uid_t;
321 typedef long		gid_t;
322 #ifndef _environ
323 #define _environ	environ
324 #endif
325 #define flushall	_flushall
326 #define fcloseall	_fcloseall
327 #ifndef isnan
328 #define isnan		_isnan	/* ...same libraries as MSVC */
329 #endif
330 
331 #ifndef _O_NOINHERIT
332 #  define _O_NOINHERIT	0x0080
333 #  ifndef _NO_OLDNAMES
334 #    define O_NOINHERIT	_O_NOINHERIT
335 #  endif
336 #endif
337 
338 /* <stdint.h>, pulled in by <io.h> as of mingw-runtime-3.3, typedef's
339  * (u)intptr_t but doesn't set the _(U)INTPTR_T_DEFINED defines */
340 #ifdef _STDINT_H
341 #  ifndef _INTPTR_T_DEFINED
342 #    define _INTPTR_T_DEFINED
343 #  endif
344 #  ifndef _UINTPTR_T_DEFINED
345 #    define _UINTPTR_T_DEFINED
346 #  endif
347 #endif
348 
349 #ifndef CP_UTF8
350 #  define CP_UTF8	65001
351 #endif
352 
353 #endif /* __MINGW32__ */
354 
355 #ifndef _INTPTR_T_DEFINED
356 typedef int		intptr_t;
357 #  define _INTPTR_T_DEFINED
358 #endif
359 
360 #ifndef _UINTPTR_T_DEFINED
361 typedef unsigned int	uintptr_t;
362 #  define _UINTPTR_T_DEFINED
363 #endif
364 
365 START_EXTERN_C
366 
367 /* For UNIX compatibility. */
368 
369 #ifdef PERL_CORE
370 extern  uid_t	getuid(void);
371 extern  gid_t	getgid(void);
372 extern  uid_t	geteuid(void);
373 extern  gid_t	getegid(void);
374 extern  int	setuid(uid_t uid);
375 extern  int	setgid(gid_t gid);
376 extern  int	kill(int pid, int sig);
377 #ifndef USE_PERL_SBRK
378 extern  void	*sbrk(ptrdiff_t need);
379 #  define HAS_SBRK_PROTO
380 #endif
381 extern	char *	getlogin(void);
382 extern	int	chown(const char *p, uid_t o, gid_t g);
383 #if((!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 4) && \
384     (!defined(__MINGW32_MAJOR_VERSION) || __MINGW32_MAJOR_VERSION < 3 || \
385      (__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION < 21)))
386 extern  int	mkstemp(const char *path);
387 #endif
388 #endif
389 
390 #undef	 Stat
391 #define  Stat		win32_stat
392 
393 #undef   init_os_extras
394 #define  init_os_extras Perl_init_os_extras
395 
396 DllExport void		Perl_win32_init(int *argcp, char ***argvp);
397 DllExport void		Perl_win32_term(void);
398 DllExport void		Perl_init_os_extras(void);
399 DllExport void		win32_str_os_error(void *sv, DWORD err);
400 DllExport int		RunPerl(int argc, char **argv, char **env);
401 
402 typedef struct {
403     HANDLE	childStdIn;
404     HANDLE	childStdOut;
405     HANDLE	childStdErr;
406     /*
407      * the following correspond to the fields of the same name
408      * in the STARTUPINFO structure. Embedders can use these to
409      * control the spawning process' look.
410      * Example - to hide the window of the spawned process:
411      *    dwFlags = STARTF_USESHOWWINDOW;
412      *	  wShowWindow = SW_HIDE;
413      */
414     DWORD	dwFlags;
415     DWORD	dwX;
416     DWORD	dwY;
417     DWORD	dwXSize;
418     DWORD	dwYSize;
419     DWORD	dwXCountChars;
420     DWORD	dwYCountChars;
421     DWORD	dwFillAttribute;
422     WORD	wShowWindow;
423 } child_IO_table;
424 
425 DllExport void		win32_get_child_IO(child_IO_table* ptr);
426 DllExport HWND		win32_create_message_window(void);
427 DllExport int		win32_async_check(pTHX);
428 
429 extern char *		win32_get_privlib(WIN32_NO_REGISTRY_M_(const char *pl) STRLEN *const len);
430 extern char *		win32_get_sitelib(const char *pl, STRLEN *const len);
431 extern char *		win32_get_vendorlib(const char *pl, STRLEN *const len);
432 
433 #ifdef PERL_IMPLICIT_SYS
434 extern void		win32_delete_internal_host(void *h);
435 #endif
436 
437 extern int		win32_get_errno(int err);
438 
439 extern const char * const		staticlinkmodules[];
440 
441 END_EXTERN_C
442 
443 typedef  char *		caddr_t;	/* In malloc.c (core address). */
444 
445 /*
446  * handle socket stuff, assuming socket is always available
447  */
448 #include <sys/socket.h>
449 #include <netdb.h>
450 
451 #ifdef MYMALLOC
452 #define EMBEDMYMALLOC	/**/
453 /* #define USE_PERL_SBRK	/ **/
454 /* #define PERL_SBRK_VIA_MALLOC	/ **/
455 #endif
456 
457 #ifdef PERL_TEXTMODE_SCRIPTS
458 #  define PERL_SCRIPT_MODE		"r"
459 #else
460 #  define PERL_SCRIPT_MODE		"rb"
461 #endif
462 
463 /*
464  * Now Win32 specific per-thread data stuff
465  */
466 
467 /* Leave the first couple ids after WM_USER unused because they
468  * might be used by an embedding application, and on Windows
469  * version before 2000 we might end up eating those messages
470  * if they were not meant for us.
471  */
472 #define WM_USER_MIN     (WM_USER+30)
473 #define WM_USER_MESSAGE (WM_USER_MIN)
474 #define WM_USER_KILL    (WM_USER_MIN+1)
475 #define WM_USER_MAX     (WM_USER_MIN+1)
476 
477 struct thread_intern {
478     /* XXX can probably use one buffer instead of several */
479     char		Wstrerror_buffer[512];
480     struct servent	Wservent;
481     char		Wgetlogin_buffer[128];
482     int			Winit_socktype;
483     char		Wcrypt_buffer[30];
484 #    ifdef USE_RTL_THREAD_API
485     void *		retv;	/* slot for thread return value */
486 #    endif
487     BOOL               Wuse_showwindow;
488     WORD               Wshowwindow;
489 };
490 
491 #define HAVE_INTERP_INTERN
492 typedef struct {
493     long	num;
494     DWORD	pids[MAXIMUM_WAIT_OBJECTS];
495     HANDLE	handles[MAXIMUM_WAIT_OBJECTS];
496 } child_tab;
497 
498 #ifdef USE_ITHREADS
499 typedef struct {
500     long	num;
501     DWORD	pids[MAXIMUM_WAIT_OBJECTS];
502     HANDLE	handles[MAXIMUM_WAIT_OBJECTS];
503     HWND	message_hwnds[MAXIMUM_WAIT_OBJECTS];
504     char        sigterm[MAXIMUM_WAIT_OBJECTS];
505 } pseudo_child_tab;
506 #endif
507 
508 #ifndef Sighandler_t
509 typedef Signal_t (*Sighandler_t) (int);
510 #define Sighandler_t	Sighandler_t
511 #endif
512 
513 struct interp_intern {
514     char *	perlshell_tokens;
515     char **	perlshell_vec;
516     long	perlshell_items;
517     struct av *	fdpid;
518     child_tab *	children;
519 #ifdef USE_ITHREADS
520     DWORD	pseudo_id;
521     pseudo_child_tab * pseudo_children;
522 #endif
523     void *	internal_host;
524     struct thread_intern	thr_intern;
525     HWND        message_hwnd;
526     UINT	timerid;
527     unsigned 	poll_count;
528     Sighandler_t sigtable[SIG_SIZE];
529 };
530 
531 #define WIN32_POLL_INTERVAL 32768
532 #define PERL_ASYNC_CHECK() if (w32_do_async || PL_sig_pending) win32_async_check(aTHX)
533 
534 #define w32_perlshell_tokens	(PL_sys_intern.perlshell_tokens)
535 #define w32_perlshell_vec	(PL_sys_intern.perlshell_vec)
536 #define w32_perlshell_items	(PL_sys_intern.perlshell_items)
537 #define w32_fdpid		(PL_sys_intern.fdpid)
538 #define w32_children		(PL_sys_intern.children)
539 #define w32_num_children	(w32_children->num)
540 #define w32_child_pids		(w32_children->pids)
541 #define w32_child_handles	(w32_children->handles)
542 #define w32_pseudo_id		(PL_sys_intern.pseudo_id)
543 #define w32_pseudo_children	(PL_sys_intern.pseudo_children)
544 #define w32_num_pseudo_children		(w32_pseudo_children->num)
545 #define w32_pseudo_child_pids		(w32_pseudo_children->pids)
546 #define w32_pseudo_child_handles	(w32_pseudo_children->handles)
547 #define w32_pseudo_child_message_hwnds	(w32_pseudo_children->message_hwnds)
548 #define w32_pseudo_child_sigterm	(w32_pseudo_children->sigterm)
549 #define w32_internal_host		(PL_sys_intern.internal_host)
550 #define w32_timerid			(PL_sys_intern.timerid)
551 #define w32_message_hwnd		(PL_sys_intern.message_hwnd)
552 #define w32_sighandler			(PL_sys_intern.sigtable)
553 #define w32_poll_count			(PL_sys_intern.poll_count)
554 #define w32_do_async			(w32_poll_count++ > WIN32_POLL_INTERVAL)
555 #define w32_strerror_buffer	(PL_sys_intern.thr_intern.Wstrerror_buffer)
556 #define w32_getlogin_buffer	(PL_sys_intern.thr_intern.Wgetlogin_buffer)
557 #define w32_crypt_buffer	(PL_sys_intern.thr_intern.Wcrypt_buffer)
558 #define w32_servent		(PL_sys_intern.thr_intern.Wservent)
559 #define w32_init_socktype	(PL_sys_intern.thr_intern.Winit_socktype)
560 #define w32_use_showwindow	(PL_sys_intern.thr_intern.Wuse_showwindow)
561 #define w32_showwindow	(PL_sys_intern.thr_intern.Wshowwindow)
562 
563 #ifdef USE_ITHREADS
564 void win32_wait_for_children(pTHX);
565 #  define PERL_WAIT_FOR_CHILDREN win32_wait_for_children(aTHX)
566 #endif
567 
568 /* IO.xs and POSIX.xs define PERLIO_NOT_STDIO to 1 */
569 #if defined(PERL_EXT_IO) || defined(PERL_EXT_POSIX)
570 #undef  PERLIO_NOT_STDIO
571 #endif
572 #define PERLIO_NOT_STDIO 0
573 
574 #define EXEC_ARGV_CAST(x) ((const char *const *) x)
575 
576 DllExport void *win32_signal_context(void);
577 #define PERL_GET_SIG_CONTEXT win32_signal_context()
578 
579 #define Win_GetModuleHandle   GetModuleHandle
580 #define Win_GetProcAddress    GetProcAddress
581 #define Win_GetModuleFileName GetModuleFileName
582 #define Win_CreateSemaphore   CreateSemaphore
583 
584 #if defined(PERL_CORE) && !defined(O_ACCMODE)
585 #  define O_ACCMODE (O_RDWR | O_WRONLY | O_RDONLY)
586 #endif
587 
588 /* ucrt at least seems to allocate a whole bit per type,
589    just mask off one bit from the mask for our symlink
590    and socket file types.
591 */
592 #define _S_IFLNK ((unsigned)(_S_IFDIR | _S_IFCHR))
593 #define _S_IFSOCK ((unsigned)(_S_IFDIR | _S_IFIFO))
594 /* mingw64 defines _S_IFBLK to 0x3000 which is _S_IFDIR | _S_IFIFO */
595 #ifndef _S_IFBLK
596 #  define _S_IFBLK ((unsigned)(_S_IFCHR | _S_IFIFO))
597 #endif
598 #undef S_ISLNK
599 #define S_ISLNK(mode) (((mode) & _S_IFMT) == _S_IFLNK)
600 #undef S_ISSOCK
601 #define S_ISSOCK(mode) (((mode) & _S_IFMT) == _S_IFSOCK)
602 #undef S_ISBLK
603 #define S_ISBLK(mode) (((mode) & _S_IFMT) == _S_IFBLK)
604 
605 /*
606 
607 The default CRT struct stat uses unsigned short for st_dev and st_ino
608 which obviously isn't enough, so we define our own structure.
609 
610  */
611 
612 typedef DWORD Dev_t;
613 typedef unsigned __int64 Ino_t;
614 
615 struct w32_stat {
616     Dev_t st_dev;
617     Ino_t st_ino;
618     unsigned short st_mode;
619     DWORD st_nlink;
620     short st_uid;
621     short st_gid;
622     Dev_t st_rdev;
623     Off_t st_size;
624     time_t st_atime;
625     time_t st_mtime;
626     time_t st_ctime;
627 };
628 
629 #endif /* _INC_WIN32_PERL5 */
630 
631