1/*
2 * tclUnixPort.h --
3 *
4 *	This header file handles porting issues that occur because
5 *	of differences between systems.  It reads in UNIX-related
6 *	header files and sets up UNIX-related macros for Tcl's UNIX
7 *	core.  It should be the only file that contains #ifdefs to
8 *	handle different flavors of UNIX.  This file sets up the
9 *	union of all UNIX-related things needed by any of the Tcl
10 *	core files.  This file depends on configuration #defines such
11 *	as NO_DIRENT_H that are set up by the "configure" script.
12 *
13 *	Much of the material in this file was originally contributed
14 *	by Karl Lehenbauer, Mark Diekhans and Peter da Silva.
15 *
16 * Copyright (c) 1991-1994 The Regents of the University of California.
17 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
18 *
19 * See the file "license.terms" for information on usage and redistribution
20 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
21 *
22 * RCS: @(#) $Id: tclUnixPort.h,v 1.65.2.1 2010/05/25 10:37:18 nijtmans Exp $
23 */
24
25#ifndef _TCLUNIXPORT
26#define _TCLUNIXPORT
27
28#ifndef MODULE_SCOPE
29#define MODULE_SCOPE extern
30#endif
31
32/*
33 *---------------------------------------------------------------------------
34 * The following sets of #includes and #ifdefs are required to get Tcl to
35 * compile under the various flavors of unix.
36 *---------------------------------------------------------------------------
37 */
38
39#include <errno.h>
40#include <fcntl.h>
41#ifdef HAVE_NET_ERRNO_H
42#   include <net/errno.h>
43#endif
44#include <pwd.h>
45#include <signal.h>
46#ifdef HAVE_SYS_PARAM_H
47#   include <sys/param.h>
48#endif
49#include <sys/types.h>
50#ifdef USE_DIRENT2_H
51#   include "../compat/dirent2.h"
52#else
53#ifdef NO_DIRENT_H
54#   include "../compat/dirent.h"
55#else
56#   include <dirent.h>
57#endif
58#endif
59
60#ifdef HAVE_STRUCT_DIRENT64
61typedef struct dirent64	Tcl_DirEntry;
62#   define TclOSreaddir		readdir64
63#else
64typedef struct dirent	Tcl_DirEntry;
65#   define TclOSreaddir		readdir
66#endif
67
68#ifdef HAVE_TYPE_OFF64_T
69typedef off64_t		Tcl_SeekOffset;
70#   define TclOSseek		lseek64
71#   define TclOSopen		open64
72#else
73typedef off_t		Tcl_SeekOffset;
74#   define TclOSseek		lseek
75#   define TclOSopen		open
76#endif
77
78#ifdef HAVE_STRUCT_STAT64
79#   define TclOSstat		stat64
80#   define TclOSlstat		lstat64
81#else
82#   define TclOSstat		stat
83#   define TclOSlstat		lstat
84#endif
85
86#include <sys/file.h>
87#ifdef HAVE_SYS_SELECT_H
88#   include <sys/select.h>
89#endif
90#include <sys/stat.h>
91#if TIME_WITH_SYS_TIME
92#   include <sys/time.h>
93#   include <time.h>
94#else
95#if HAVE_SYS_TIME_H
96#   include <sys/time.h>
97#else
98#   include <time.h>
99#endif
100#endif
101#ifndef NO_SYS_WAIT_H
102#   include <sys/wait.h>
103#endif
104#if HAVE_INTTYPES_H
105#   include <inttypes.h>
106#endif
107#ifdef NO_LIMITS_H
108#   include "../compat/limits.h"
109#else
110#   include <limits.h>
111#endif
112#if HAVE_STDINT_H
113#   include <stdint.h>
114#endif
115#ifdef HAVE_UNISTD_H
116#   include <unistd.h>
117#else
118#   include "../compat/unistd.h"
119#endif
120
121MODULE_SCOPE int TclUnixSetBlockingMode(int fd, int mode);
122
123#include <utime.h>
124
125/*
126 * Socket support stuff: This likely needs more work to parameterize for
127 * each system.
128 */
129#include <sys/socket.h>		/* struct sockaddr, SOCK_STREAM, ... */
130#ifndef NO_UNAME
131#   include <sys/utsname.h>	/* uname system call. */
132#endif
133#include <netinet/in.h>		/* struct in_addr, struct sockaddr_in */
134#include <arpa/inet.h>		/* inet_ntoa() */
135#include <netdb.h>		/* gethostbyname() */
136
137/*
138 * Some platforms (e.g. SunOS) don't define FLT_MAX and FLT_MIN, so we
139 * look for an alternative definition.  If no other alternative is available
140 * we use a reasonable guess.
141 */
142
143#ifndef NO_FLOAT_H
144#   include <float.h>
145#else
146#ifndef NO_VALUES_H
147#   include <values.h>
148#endif
149#endif
150
151#ifndef FLT_MAX
152#   ifdef MAXFLOAT
153#	define FLT_MAX MAXFLOAT
154#   else
155#	define FLT_MAX 3.402823466E+38F
156#   endif
157#endif
158#ifndef FLT_MIN
159#   ifdef MINFLOAT
160#	define FLT_MIN MINFLOAT
161#   else
162#	define FLT_MIN 1.175494351E-38F
163#   endif
164#endif
165
166/*
167 * NeXT doesn't define O_NONBLOCK, so #define it here if necessary.
168 */
169
170#ifndef O_NONBLOCK
171#   define O_NONBLOCK 0x80
172#endif
173
174/*
175 * The type of the status returned by wait varies from UNIX system
176 * to UNIX system.  The macro below defines it:
177 */
178
179#ifdef _AIX
180#   define WAIT_STATUS_TYPE pid_t
181#else
182#ifndef NO_UNION_WAIT
183#   define WAIT_STATUS_TYPE union wait
184#else
185#   define WAIT_STATUS_TYPE int
186#endif
187#endif
188
189/*
190 * Supply definitions for macros to query wait status, if not already
191 * defined in header files above.
192 */
193
194#ifndef WIFEXITED
195#   define WIFEXITED(stat)  (((*((int *) &(stat))) & 0xff) == 0)
196#endif
197
198#ifndef WEXITSTATUS
199#   define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
200#endif
201
202#ifndef WIFSIGNALED
203#   define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
204#endif
205
206#ifndef WTERMSIG
207#   define WTERMSIG(stat)    ((*((int *) &(stat))) & 0x7f)
208#endif
209
210#ifndef WIFSTOPPED
211#   define WIFSTOPPED(stat)  (((*((int *) &(stat))) & 0xff) == 0177)
212#endif
213
214#ifndef WSTOPSIG
215#   define WSTOPSIG(stat)    (((*((int *) &(stat))) >> 8) & 0xff)
216#endif
217
218/*
219 * Define constants for waitpid() system call if they aren't defined
220 * by a system header file.
221 */
222
223#ifndef WNOHANG
224#   define WNOHANG 1
225#endif
226#ifndef WUNTRACED
227#   define WUNTRACED 2
228#endif
229
230/*
231 * Supply macros for seek offsets, if they're not already provided by
232 * an include file.
233 */
234
235#ifndef SEEK_SET
236#   define SEEK_SET 0
237#endif
238#ifndef SEEK_CUR
239#   define SEEK_CUR 1
240#endif
241#ifndef SEEK_END
242#   define SEEK_END 2
243#endif
244
245/*
246 * The stuff below is needed by the "time" command.  If this system has no
247 * gettimeofday call, then must use times() instead.
248 */
249
250#ifdef NO_GETTOD
251#   include <sys/times.h>
252#else
253#   ifdef HAVE_BSDGETTIMEOFDAY
254#	define gettimeofday BSDgettimeofday
255#   endif
256#endif
257
258#ifdef GETTOD_NOT_DECLARED
259EXTERN int		gettimeofday _ANSI_ARGS_((struct timeval *tp,
260			    struct timezone *tzp));
261#endif
262
263/*
264 * Define access mode constants if they aren't already defined.
265 */
266
267#ifndef F_OK
268#    define F_OK 00
269#endif
270#ifndef X_OK
271#    define X_OK 01
272#endif
273#ifndef W_OK
274#    define W_OK 02
275#endif
276#ifndef R_OK
277#    define R_OK 04
278#endif
279
280/*
281 * Define FD_CLOEEXEC (the close-on-exec flag bit) if it isn't
282 * already defined.
283 */
284
285#ifndef FD_CLOEXEC
286#   define FD_CLOEXEC 1
287#endif
288
289/*
290 * On systems without symbolic links (i.e. S_IFLNK isn't defined)
291 * define "lstat" to use "stat" instead.
292 */
293
294#ifndef S_IFLNK
295#   undef TclOSlstat
296#   define lstat	stat
297#   define lstat64	stat64
298#   define TclOSlstat	TclOSstat
299#endif
300
301/*
302 * Define macros to query file type bits, if they're not already
303 * defined.
304 */
305
306#ifndef S_ISREG
307#   ifdef S_IFREG
308#       define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
309#   else
310#       define S_ISREG(m) 0
311#   endif
312#endif /* !S_ISREG */
313#ifndef S_ISDIR
314#   ifdef S_IFDIR
315#       define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
316#   else
317#       define S_ISDIR(m) 0
318#   endif
319#endif /* !S_ISDIR */
320#ifndef S_ISCHR
321#   ifdef S_IFCHR
322#       define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
323#   else
324#       define S_ISCHR(m) 0
325#   endif
326#endif /* !S_ISCHR */
327#ifndef S_ISBLK
328#   ifdef S_IFBLK
329#       define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
330#   else
331#       define S_ISBLK(m) 0
332#   endif
333#endif /* !S_ISBLK */
334#ifndef S_ISFIFO
335#   ifdef S_IFIFO
336#       define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
337#   else
338#       define S_ISFIFO(m) 0
339#   endif
340#endif /* !S_ISFIFO */
341#ifndef S_ISLNK
342#   ifdef S_IFLNK
343#       define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
344#   else
345#       define S_ISLNK(m) 0
346#   endif
347#endif /* !S_ISLNK */
348#ifndef S_ISSOCK
349#   ifdef S_IFSOCK
350#       define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
351#   else
352#       define S_ISSOCK(m) 0
353#   endif
354#endif /* !S_ISSOCK */
355
356/*
357 * Make sure that MAXPATHLEN and MAXNAMLEN are defined.
358 */
359
360#ifndef MAXPATHLEN
361#   ifdef PATH_MAX
362#       define MAXPATHLEN PATH_MAX
363#   else
364#       define MAXPATHLEN 2048
365#   endif
366#endif
367
368#ifndef MAXNAMLEN
369#   ifdef NAME_MAX
370#	define MAXNAMLEN NAME_MAX
371#   else
372#	define MAXNAMLEN 255
373#   endif
374#endif
375
376/*
377 * Make sure that L_tmpnam is defined.
378 */
379
380#ifndef L_tmpnam
381#   define L_tmpnam 100
382#endif
383
384/*
385 * The following macro defines the type of the mask arguments to
386 * select:
387 */
388
389#ifndef NO_FD_SET
390#   define SELECT_MASK fd_set
391#else /* NO_FD_SET */
392#   ifndef _AIX
393	typedef long fd_mask;
394#   endif /* !AIX */
395#   if defined(_IBMR2)
396#	define SELECT_MASK void
397#   else /* !defined(_IBMR2) */
398#	define SELECT_MASK int
399#   endif /* defined(_IBMR2) */
400#endif /* !NO_FD_SET */
401
402/*
403 * Define "NBBY" (number of bits per byte) if it's not already defined.
404 */
405
406#ifndef NBBY
407#   define NBBY 8
408#endif
409
410/*
411 * The following macro defines the number of fd_masks in an fd_set:
412 */
413
414#ifndef FD_SETSIZE
415#   ifdef OPEN_MAX
416#	define FD_SETSIZE OPEN_MAX
417#   else
418#	define FD_SETSIZE 256
419#   endif
420#endif /* FD_SETSIZE */
421#if !defined(howmany)
422#   define howmany(x, y) (((x)+((y)-1))/(y))
423#endif /* !defined(howmany) */
424#ifndef NFDBITS
425#   define NFDBITS NBBY*sizeof(fd_mask)
426#endif /* NFDBITS */
427#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)
428
429/*
430 * Not all systems declare the errno variable in errno.h. so this
431 * file does it explicitly.  The list of system error messages also
432 * isn't generally declared in a header file anywhere.
433 */
434
435#ifdef NO_ERRNO
436extern int errno;
437#endif /* NO_ERRNO */
438
439/*
440 * Not all systems declare all the errors that Tcl uses!  Provide some
441 * work-arounds...
442 */
443
444#ifndef EOVERFLOW
445#   ifdef EFBIG
446#	define EOVERFLOW EFBIG
447#   else /* !EFBIG */
448#	define EOVERFLOW EINVAL
449#   endif /* EFBIG */
450#endif /* EOVERFLOW */
451
452/*
453 * Variables provided by the C library:
454 */
455
456#if defined(__APPLE__) && defined(__DYNAMIC__)
457#   include <crt_externs.h>
458#   define environ (*_NSGetEnviron())
459#   define USE_PUTENV 1
460#else
461#   if defined(_sgi) || defined(__sgi)
462#       define environ _environ
463#   endif
464extern char **environ;
465#endif
466
467/*
468 * There is no platform-specific panic routine for Unix in the Tcl internals.
469 */
470
471#define TclpPanic ((Tcl_PanicProc *) NULL)
472
473/*
474 * Darwin specifc configure overrides.
475 */
476
477#ifdef __APPLE__
478/*
479 * Support for fat compiles: configure runs only once for multiple architectures
480 */
481#   if defined(__LP64__) && defined (NO_COREFOUNDATION_64)
482#       undef HAVE_COREFOUNDATION
483#    endif /* __LP64__ && NO_COREFOUNDATION_64 */
484#   include <sys/cdefs.h>
485#   ifdef __DARWIN_UNIX03
486#       if __DARWIN_UNIX03
487#           undef HAVE_PUTENV_THAT_COPIES
488#       else
489#           define HAVE_PUTENV_THAT_COPIES 1
490#       endif
491#   endif /* __DARWIN_UNIX03 */
492/*
493 * The termios configure test program relies on the configure script being run
494 * from a terminal, which is not the case e.g. when configuring from Xcode.
495 * Since termios is known to be present on all Mac OS X releases since 10.0,
496 * override the configure defines for serial API here. [Bug 497147]
497 */
498#   define USE_TERMIOS 1
499#   undef  USE_TERMIO
500#   undef  USE_SGTTY
501/*
502 * Include AvailabilityMacros.h here (when available) to ensure any symbolic
503 * MAC_OS_X_VERSION_* constants passed on the command line are translated.
504 */
505#   ifdef HAVE_AVAILABILITYMACROS_H
506#       include <AvailabilityMacros.h>
507#   endif
508/*
509 * Support for weak import.
510 */
511#   ifdef HAVE_WEAK_IMPORT
512#       if !defined(HAVE_AVAILABILITYMACROS_H) || !defined(MAC_OS_X_VERSION_MIN_REQUIRED)
513#           undef HAVE_WEAK_IMPORT
514#       else
515#           ifndef WEAK_IMPORT_ATTRIBUTE
516#               define WEAK_IMPORT_ATTRIBUTE __attribute__((weak_import))
517#           endif
518#       endif
519#   endif /* HAVE_WEAK_IMPORT */
520/*
521 * Support for MAC_OS_X_VERSION_MAX_ALLOWED define from AvailabilityMacros.h:
522 * only use API available in the indicated OS version or earlier.
523 */
524#   ifdef MAC_OS_X_VERSION_MAX_ALLOWED
525#       if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 && defined(__LP64__)
526#           undef HAVE_COREFOUNDATION
527#       endif
528#       if MAC_OS_X_VERSION_MAX_ALLOWED < 1040
529#           undef HAVE_OSSPINLOCKLOCK
530#           undef HAVE_PTHREAD_ATFORK
531#           undef HAVE_COPYFILE
532#       endif
533#       if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
534#           ifdef TCL_THREADS
535		/* prior to 10.3, realpath is not threadsafe, c.f. bug 711232 */
536#               define NO_REALPATH 1
537#           endif
538#           undef HAVE_LANGINFO
539#       endif
540#   endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
541#   if defined(HAVE_COREFOUNDATION) && defined(__LP64__) && \
542	    defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050
543#       warning "Weak import of 64-bit CoreFoundation is not supported, will not run on Mac OS X < 10.5."
544#   endif
545/*
546 * At present, using vfork() instead of fork() causes execve() to fail
547 * intermittently on Darwin x86_64. rdar://4685553
548 */
549#   if defined(__x86_64__) && !defined(FIXED_RDAR_4685553)
550#       undef USE_VFORK
551#   endif /* __x86_64__ */
552/* Workaround problems with vfork() when building with llvm-gcc-4.2 */
553#   if defined (__llvm__) && \
554	    (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 2 || \
555	    (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 0))))
556#       undef USE_VFORK
557#   endif /* __llvm__ */
558#endif /* __APPLE__ */
559
560/*
561 *---------------------------------------------------------------------------
562 * The following macros and declarations represent the interface between
563 * generic and unix-specific parts of Tcl.  Some of the macros may override
564 * functions declared in tclInt.h.
565 *---------------------------------------------------------------------------
566 */
567
568/*
569 * The default platform eol translation on Unix is TCL_TRANSLATE_LF.
570 */
571
572#ifdef DJGPP
573#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_CRLF
574typedef int socklen_t;
575#else
576#define	TCL_PLATFORM_TRANSLATION	TCL_TRANSLATE_LF
577#endif
578
579/*
580 * The following macros have trivial definitions, allowing generic code to
581 * address platform-specific issues.
582 */
583
584#define TclpGetPid(pid)		((unsigned long) (pid))
585#define TclpReleaseFile(file)	/* Nothing. */
586
587/*
588 * The following defines wrap the system memory allocation routines.
589 */
590
591#define TclpSysAlloc(size, isBin)	malloc((size_t)size)
592#define TclpSysFree(ptr)		free((char*)ptr)
593#define TclpSysRealloc(ptr, size)	realloc((char*)ptr, (size_t)size)
594
595/*
596 * The following macros and declaration wrap the C runtime library
597 * functions.
598 */
599
600#define TclpExit		exit
601
602#ifdef TCL_THREADS
603EXTERN struct tm *     	TclpLocaltime(CONST time_t *);
604EXTERN struct tm *     	TclpGmtime(CONST time_t *);
605EXTERN char *          	TclpInetNtoa(struct in_addr);
606/* #define localtime(x)	TclpLocaltime(x)
607 * #define gmtime(x)	TclpGmtime(x)    */
608#   undef inet_ntoa
609#   define inet_ntoa(x)	TclpInetNtoa(x)
610#   ifdef HAVE_PTHREAD_ATTR_GET_NP
611#	define TclpPthreadGetAttrs	pthread_attr_get_np
612#	ifdef ATTRGETNP_NOT_DECLARED
613/*
614 * Assume it is in pthread_np.h if it isn't in pthread.h. [Bug 1064882]
615 * We might need to revisit this in the future. :^(
616 */
617#	    include <pthread.h>
618#	    include <pthread_np.h>
619#	endif
620#   else
621#	ifdef HAVE_PTHREAD_GETATTR_NP
622#	    define TclpPthreadGetAttrs	pthread_getattr_np
623#	    ifdef GETATTRNP_NOT_DECLARED
624EXTERN int pthread_getattr_np _ANSI_ARGS_((pthread_t, pthread_attr_t *));
625#	    endif
626#	endif /* HAVE_PTHREAD_GETATTR_NP */
627#   endif /* HAVE_PTHREAD_ATTR_GET_NP */
628#endif /* TCL_THREADS */
629
630/*
631 * Set of MT-safe implementations of some
632 * known-to-be-MT-unsafe library calls.
633 * Instead of returning pointers to the
634 * static storage, those return pointers
635 * to the TSD data.
636 */
637
638#include <grp.h>
639
640MODULE_SCOPE struct passwd*  TclpGetPwNam(const char *name);
641MODULE_SCOPE struct group*   TclpGetGrNam(const char *name);
642MODULE_SCOPE struct passwd*  TclpGetPwUid(uid_t uid);
643MODULE_SCOPE struct group*   TclpGetGrGid(gid_t gid);
644MODULE_SCOPE struct hostent* TclpGetHostByName(const char *name);
645MODULE_SCOPE struct hostent* TclpGetHostByAddr(const char *addr, int length, int type);
646
647#endif /* _TCLUNIXPORT */
648