1/*
2 * tclWinPort.h --
3 *
4 *	This header file handles porting issues that occur because of
5 *	differences between Windows and Unix. It should be the only
6 *	file that contains #ifdefs to handle different flavors of OS.
7 *
8 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
9 *
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id: tclWinPort.h,v 1.36.2.2 2005/11/04 18:33:35 patthoyts Exp $
14 */
15
16#ifndef _TCLWINPORT
17#define _TCLWINPORT
18
19#ifndef _TCLINT
20#   include "tclInt.h"
21#endif
22
23#ifdef CHECK_UNICODE_CALLS
24#   define _UNICODE
25#   define UNICODE
26#   define __TCHAR_DEFINED
27    typedef float *_TCHAR;
28#   define _TCHAR_DEFINED
29    typedef float *TCHAR;
30#endif /* CHECK_UNICODE_CALLS */
31
32/*
33 *---------------------------------------------------------------------------
34 * The following sets of #includes and #ifdefs are required to get Tcl to
35 * compile under the windows compilers.
36 *---------------------------------------------------------------------------
37 */
38
39#include <stdio.h>
40#include <stdlib.h>
41
42#include <errno.h>
43#include <fcntl.h>
44#include <float.h>
45#include <io.h>
46#include <malloc.h>
47#include <process.h>
48#include <signal.h>
49#include <string.h>
50
51/*
52 * Need to block out these includes for building extensions with MetroWerks
53 * compiler for Win32.
54 */
55
56#ifndef __MWERKS__
57#include <sys/stat.h>
58#include <sys/timeb.h>
59#   ifdef __BORLANDC__
60#	include <utime.h>
61#   else
62#	include <sys/utime.h>
63#   endif /* __BORLANDC__ */
64#endif /* __MWERKS__ */
65
66#include <time.h>
67
68#define WIN32_LEAN_AND_MEAN
69#include <windows.h>
70#undef WIN32_LEAN_AND_MEAN
71
72/*
73 * Ask for the winsock function typedefs, also.
74 */
75#define INCL_WINSOCK_API_TYPEDEFS   1
76#include <winsock2.h>
77
78#ifdef BUILD_tcl
79#   undef TCL_STORAGE_CLASS
80#   define TCL_STORAGE_CLASS DLLEXPORT
81#endif /* BUILD_tcl */
82
83/*
84 * Define EINPROGRESS in terms of WSAEINPROGRESS.
85 */
86
87#ifndef	EINPROGRESS
88#   define EINPROGRESS	WSAEINPROGRESS
89#endif
90
91/*
92 * If ENOTSUP is not defined, define it to a value that will never occur.
93 */
94
95#ifndef ENOTSUP
96#   define ENOTSUP	-1030507
97#endif
98
99/*
100 * The following defines redefine the Windows Socket errors as
101 * BSD errors so Tcl_PosixError can do the right thing.
102 */
103
104#ifndef EWOULDBLOCK
105#   define EWOULDBLOCK	EAGAIN
106#endif
107#ifndef EALREADY
108#   define EALREADY	149	/* operation already in progress */
109#endif
110#ifndef ENOTSOCK
111#   define ENOTSOCK	95	/* Socket operation on non-socket */
112#endif
113#ifndef EDESTADDRREQ
114#   define EDESTADDRREQ	96	/* Destination address required */
115#endif
116#ifndef EMSGSIZE
117#   define EMSGSIZE	97	/* Message too long */
118#endif
119#ifndef EPROTOTYPE
120#   define EPROTOTYPE	98	/* Protocol wrong type for socket */
121#endif
122#ifndef ENOPROTOOPT
123#   define ENOPROTOOPT	99	/* Protocol not available */
124#endif
125#ifndef EPROTONOSUPPORT
126#   define EPROTONOSUPPORT 120	/* Protocol not supported */
127#endif
128#ifndef ESOCKTNOSUPPORT
129#   define ESOCKTNOSUPPORT 121	/* Socket type not supported */
130#endif
131#ifndef EOPNOTSUPP
132#   define EOPNOTSUPP	122	/* Operation not supported on socket */
133#endif
134#ifndef EPFNOSUPPORT
135#   define EPFNOSUPPORT	123	/* Protocol family not supported */
136#endif
137#ifndef EAFNOSUPPORT
138#   define EAFNOSUPPORT	124	/* Address family not supported */
139#endif
140#ifndef EADDRINUSE
141#   define EADDRINUSE	125	/* Address already in use */
142#endif
143#ifndef EADDRNOTAVAIL
144#   define EADDRNOTAVAIL 126	/* Can't assign requested address */
145#endif
146#ifndef ENETDOWN
147#   define ENETDOWN	127	/* Network is down */
148#endif
149#ifndef ENETUNREACH
150#   define ENETUNREACH	128	/* Network is unreachable */
151#endif
152#ifndef ENETRESET
153#   define ENETRESET	129	/* Network dropped connection on reset */
154#endif
155#ifndef ECONNABORTED
156#   define ECONNABORTED	130	/* Software caused connection abort */
157#endif
158#ifndef ECONNRESET
159#   define ECONNRESET	131	/* Connection reset by peer */
160#endif
161#ifndef ENOBUFS
162#   define ENOBUFS	132	/* No buffer space available */
163#endif
164#ifndef EISCONN
165#   define EISCONN	133	/* Socket is already connected */
166#endif
167#ifndef ENOTCONN
168#   define ENOTCONN	134	/* Socket is not connected */
169#endif
170#ifndef ESHUTDOWN
171#   define ESHUTDOWN	143	/* Can't send after socket shutdown */
172#endif
173#ifndef ETOOMANYREFS
174#   define ETOOMANYREFS	144	/* Too many references: can't splice */
175#endif
176#ifndef ETIMEDOUT
177#   define ETIMEDOUT	145	/* Connection timed out */
178#endif
179#ifndef ECONNREFUSED
180#   define ECONNREFUSED	146	/* Connection refused */
181#endif
182#ifndef ELOOP
183#   define ELOOP	90	/* Symbolic link loop */
184#endif
185#ifndef EHOSTDOWN
186#   define EHOSTDOWN	147	/* Host is down */
187#endif
188#ifndef EHOSTUNREACH
189#   define EHOSTUNREACH	148	/* No route to host */
190#endif
191#ifndef ENOTEMPTY
192#   define ENOTEMPTY 	93	/* directory not empty */
193#endif
194#ifndef EUSERS
195#   define EUSERS	94	/* Too many users (for UFS) */
196#endif
197#ifndef EDQUOT
198#   define EDQUOT	69	/* Disc quota exceeded */
199#endif
200#ifndef ESTALE
201#   define ESTALE	151	/* Stale NFS file handle */
202#endif
203#ifndef EREMOTE
204#   define EREMOTE	66	/* The object is remote */
205#endif
206
207/*
208 * It is very hard to determine how Windows reacts to attempting to
209 * set a file pointer outside the input datatype's representable
210 * region.  So we fake the error code ourselves.
211 */
212
213#ifndef EOVERFLOW
214#   ifdef EFBIG
215#      define EOVERFLOW	EFBIG	/* The object couldn't fit in the datatype */
216#   else /* !EFBIG */
217#      define EOVERFLOW	EINVAL	/* Better than nothing! */
218#   endif /* EFBIG */
219#endif /* !EOVERFLOW */
220
221/*
222 * Supply definitions for macros to query wait status, if not already
223 * defined in header files above.
224 */
225
226#if TCL_UNION_WAIT
227#   define WAIT_STATUS_TYPE union wait
228#else
229#   define WAIT_STATUS_TYPE int
230#endif /* TCL_UNION_WAIT */
231
232#ifndef WIFEXITED
233#   define WIFEXITED(stat)  (((*((int *) &(stat))) & 0xC0000000) == 0)
234#endif
235
236#ifndef WEXITSTATUS
237#   define WEXITSTATUS(stat) (*((int *) &(stat)))
238#endif
239
240#ifndef WIFSIGNALED
241#   define WIFSIGNALED(stat) ((*((int *) &(stat))) & 0xC0000000)
242#endif
243
244#ifndef WTERMSIG
245#   define WTERMSIG(stat)    ((*((int *) &(stat))) & 0x7f)
246#endif
247
248#ifndef WIFSTOPPED
249#   define WIFSTOPPED(stat)  0
250#endif
251
252#ifndef WSTOPSIG
253#   define WSTOPSIG(stat)    (((*((int *) &(stat))) >> 8) & 0xff)
254#endif
255
256/*
257 * Define constants for waitpid() system call if they aren't defined
258 * by a system header file.
259 */
260
261#ifndef WNOHANG
262#   define WNOHANG 1
263#endif
264#ifndef WUNTRACED
265#   define WUNTRACED 2
266#endif
267
268/*
269 * Define access mode constants if they aren't already defined.
270 */
271
272#ifndef F_OK
273#    define F_OK 00
274#endif
275#ifndef X_OK
276#    define X_OK 01
277#endif
278#ifndef W_OK
279#    define W_OK 02
280#endif
281#ifndef R_OK
282#    define R_OK 04
283#endif
284
285/*
286 * Define macros to query file type bits, if they're not already
287 * defined.
288 */
289
290#ifndef S_IFLNK
291#define S_IFLNK        0120000  /* Symbolic Link */
292#endif
293
294#ifndef S_ISREG
295#   ifdef S_IFREG
296#       define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
297#   else
298#       define S_ISREG(m) 0
299#   endif
300#endif /* !S_ISREG */
301#ifndef S_ISDIR
302#   ifdef S_IFDIR
303#       define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
304#   else
305#       define S_ISDIR(m) 0
306#   endif
307#endif /* !S_ISDIR */
308#ifndef S_ISCHR
309#   ifdef S_IFCHR
310#       define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
311#   else
312#       define S_ISCHR(m) 0
313#   endif
314#endif /* !S_ISCHR */
315#ifndef S_ISBLK
316#   ifdef S_IFBLK
317#       define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
318#   else
319#       define S_ISBLK(m) 0
320#   endif
321#endif /* !S_ISBLK */
322#ifndef S_ISFIFO
323#   ifdef S_IFIFO
324#       define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
325#   else
326#       define S_ISFIFO(m) 0
327#   endif
328#endif /* !S_ISFIFO */
329#ifndef S_ISLNK
330#   ifdef S_IFLNK
331#       define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
332#   else
333#       define S_ISLNK(m) 0
334#   endif
335#endif /* !S_ISLNK */
336
337
338/*
339 * Define MAXPATHLEN in terms of MAXPATH if available
340 */
341
342#ifndef MAXPATH
343#define MAXPATH MAX_PATH
344#endif /* MAXPATH */
345
346#ifndef MAXPATHLEN
347#define MAXPATHLEN MAXPATH
348#endif /* MAXPATHLEN */
349
350/*
351 * Define pid_t and uid_t if they're not already defined.
352 */
353
354#if ! TCL_PID_T
355#   define pid_t int
356#endif /* !TCL_PID_T */
357#if ! TCL_UID_T
358#   define uid_t int
359#endif /* !TCL_UID_T */
360
361/*
362 * Visual C++ has some odd names for common functions, so we need to
363 * define a few macros to handle them.  Also, it defines EDEADLOCK and
364 * EDEADLK as the same value, which confuses Tcl_ErrnoId().
365 */
366
367#if defined(_MSC_VER) || defined(__MINGW32__)
368#    define environ _environ
369#    define hypot _hypot
370#    define exception _exception
371#    undef EDEADLOCK
372#    if defined(__MINGW32__) && !defined(__MSVCRT__)
373#	define timezone _timezone
374#    endif
375#endif /* _MSC_VER || __MINGW32__ */
376
377/*
378 * Borland's timezone and environ functions.
379 */
380
381#ifdef  __BORLANDC__
382#   define timezone _timezone
383#   define environ  _environ
384#endif /* __BORLANDC__ */
385
386#ifdef __CYGWIN__
387/* On Cygwin, the environment is imported from the Cygwin DLL. */
388     DLLIMPORT extern char **__cygwin_environ;
389#    define environ __cygwin_environ
390#    define putenv TclCygwinPutenv
391#    define timezone _timezone
392#endif /* __CYGWIN__ */
393
394/*
395 * There is no platform-specific panic routine for Windows in the Tcl internals.
396 */
397
398#define TclpPanic ((Tcl_PanicProc *) NULL)
399
400/*
401 *---------------------------------------------------------------------------
402 * The following macros and declarations represent the interface between
403 * generic and windows-specific parts of Tcl.  Some of the macros may
404 * override functions declared in tclInt.h.
405 *---------------------------------------------------------------------------
406 */
407
408/*
409 * The default platform eol translation on Windows is TCL_TRANSLATE_CRLF:
410 */
411
412#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_CRLF
413
414/*
415 * Declare dynamic loading extension macro.
416 */
417
418#define TCL_SHLIB_EXT ".dll"
419
420/*
421 * The following define ensures that we use the native putenv
422 * implementation to modify the environment array.  This keeps
423 * the C level environment in synch with the system level environment.
424 */
425
426#define USE_PUTENV		1
427#define USE_PUTENV_FOR_UNSET	1
428
429/*
430 * Msvcrt's putenv() copies the string rather than takes ownership of it.
431 */
432
433#if defined(_MSC_VER) || defined(__MINGW32__)
434#   define HAVE_PUTENV_THAT_COPIES 1
435#endif
436
437/*
438 * The following defines wrap the system memory allocation routines for
439 * use by tclAlloc.c.
440 */
441
442#ifdef __CYGWIN__
443#   define TclpSysAlloc(size, isBin)	malloc((size))
444#   define TclpSysFree(ptr)		free((ptr))
445#   define TclpSysRealloc(ptr, size)	realloc((ptr), (size))
446#else
447#   define TclpSysAlloc(size, isBin)	((void*)HeapAlloc(GetProcessHeap(), \
448					    (DWORD)0, (DWORD)size))
449#   define TclpSysFree(ptr)		(HeapFree(GetProcessHeap(), \
450					    (DWORD)0, (HGLOBAL)ptr))
451#   define TclpSysRealloc(ptr, size)	((void*)HeapReAlloc(GetProcessHeap(), \
452					    (DWORD)0, (LPVOID)ptr, (DWORD)size))
453#endif
454
455/*
456 * The following defines map from standard socket names to our internal
457 * wrappers that redirect through the winSock function table (see the
458 * file tclWinSock.c).
459 */
460
461#define getservbyname	TclWinGetServByName
462#define getsockopt	TclWinGetSockOpt
463#define ntohs		TclWinNToHS
464#define setsockopt	TclWinSetSockOpt
465/* This type is not defined in the Windows headers */
466#define socklen_t       int
467
468
469/*
470 * The following macros have trivial definitions, allowing generic code to
471 * address platform-specific issues.
472 */
473
474#define TclpReleaseFile(file)	ckfree((char *) file)
475
476/*
477 * The following macros and declarations wrap the C runtime library
478 * functions.
479 */
480
481#define TclpExit		exit
482
483/*
484 * Declarations for Windows-only functions.
485 */
486
487EXTERN HANDLE	    TclWinSerialReopen _ANSI_ARGS_(( HANDLE handle,
488			CONST TCHAR *name, DWORD access));
489
490EXTERN Tcl_Channel  TclWinOpenSerialChannel _ANSI_ARGS_((HANDLE handle,
491                        char *channelName, int permissions));
492
493EXTERN Tcl_Channel  TclWinOpenConsoleChannel _ANSI_ARGS_((HANDLE handle,
494                        char *channelName, int permissions));
495
496EXTERN Tcl_Channel  TclWinOpenFileChannel _ANSI_ARGS_((HANDLE handle,
497                        char *channelName, int permissions, int appendMode));
498
499EXTERN TclFile TclWinMakeFile _ANSI_ARGS_((HANDLE handle));
500
501/*
502 * Platform specific mutex definition used by memory allocators.
503 * These mutexes are statically allocated and explicitly initialized.
504 * Most modules do not use this, but instead use Tcl_Mutex types and
505 * Tcl_MutexLock and Tcl_MutexUnlock that are self-initializing.
506 */
507
508#ifdef TCL_THREADS
509typedef CRITICAL_SECTION TclpMutex;
510EXTERN void	TclpMutexInit _ANSI_ARGS_((TclpMutex *mPtr));
511EXTERN void	TclpMutexLock _ANSI_ARGS_((TclpMutex *mPtr));
512EXTERN void	TclpMutexUnlock _ANSI_ARGS_((TclpMutex *mPtr));
513#else /* !TCL_THREADS */
514typedef int TclpMutex;
515#define	TclpMutexInit(a)
516#define	TclpMutexLock(a)
517#define	TclpMutexUnlock(a)
518#endif /* TCL_THREADS */
519
520#ifdef TCL_WIDE_INT_TYPE
521EXTERN Tcl_WideInt	strtoll _ANSI_ARGS_((CONST char *string,
522					     char **endPtr, int base));
523EXTERN Tcl_WideUInt	strtoull _ANSI_ARGS_((CONST char *string,
524					      char **endPtr, int base));
525#endif /* TCL_WIDE_INT_TYPE */
526
527#ifndef INVALID_SET_FILE_POINTER
528#define INVALID_SET_FILE_POINTER 0xFFFFFFFF
529#endif /* INVALID_SET_FILE_POINTER */
530
531#include "tclPlatDecls.h"
532#include "tclIntPlatDecls.h"
533
534#undef TCL_STORAGE_CLASS
535#define TCL_STORAGE_CLASS DLLIMPORT
536
537#endif /* _TCLWINPORT */
538