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.27.2.19 2007/08/07 05:04:48 das Exp $ 23 */ 24 25#ifndef _TCLUNIXPORT 26#define _TCLUNIXPORT 27 28#ifndef _TCLINT 29# include "tclInt.h" 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#if !HAVE_STRTOLL && defined(TCL_WIDE_INT_TYPE) && !TCL_WIDE_INT_IS_LONG 87EXTERN Tcl_WideInt strtoll _ANSI_ARGS_((CONST char *string, 88 char **endPtr, int base)); 89EXTERN Tcl_WideUInt strtoull _ANSI_ARGS_((CONST char *string, 90 char **endPtr, int base)); 91#endif 92 93#include <sys/file.h> 94#ifdef HAVE_SYS_SELECT_H 95# include <sys/select.h> 96#endif 97#include <sys/stat.h> 98 99#ifdef __CYGWIN__ 100# define timezone _timezone 101 typedef long TIMEZONE_t; 102#else /* !__CYGWIN__ */ 103 typedef int TIMEZONE_t; 104#endif /* !__CYGWIN__ */ 105 106#if TIME_WITH_SYS_TIME 107# include <sys/time.h> 108# include <time.h> 109#else 110#if HAVE_SYS_TIME_H 111# include <sys/time.h> 112#else 113# include <time.h> 114#endif 115#endif 116#ifndef NO_SYS_WAIT_H 117# include <sys/wait.h> 118#endif 119#ifdef HAVE_UNISTD_H 120# include <unistd.h> 121#else 122# include "../compat/unistd.h" 123#endif 124#ifdef USE_FIONBIO 125 /* 126 * Not using the Posix fcntl(...,O_NONBLOCK,...) interface, instead 127 * we are using ioctl(..,FIONBIO,..). 128 */ 129 130# ifdef HAVE_SYS_FILIO_H 131# include <sys/filio.h> /* For FIONBIO. */ 132# endif 133 134# ifdef HAVE_SYS_IOCTL_H 135# include <sys/ioctl.h> /* For FIONBIO. */ 136# endif 137#endif /* USE_FIONBIO */ 138#include <utime.h> 139 140/* 141 * Socket support stuff: This likely needs more work to parameterize for 142 * each system. 143 */ 144 145#include <sys/socket.h> /* struct sockaddr, SOCK_STREAM, ... */ 146#ifndef NO_UNAME 147# include <sys/utsname.h> /* uname system call. */ 148#endif 149#include <netinet/in.h> /* struct in_addr, struct sockaddr_in */ 150#include <arpa/inet.h> /* inet_ntoa() */ 151#include <netdb.h> /* gethostbyname() */ 152 153/* 154 * Some platforms (e.g. SunOS) don't define FLT_MAX and FLT_MIN, so we 155 * look for an alternative definition. If no other alternative is available 156 * we use a reasonable guess. 157 */ 158 159#ifndef NO_FLOAT_H 160# include <float.h> 161#else 162#ifndef NO_VALUES_H 163# include <values.h> 164#endif 165#endif 166 167#ifndef FLT_MAX 168# ifdef MAXFLOAT 169# define FLT_MAX MAXFLOAT 170# else 171# define FLT_MAX 3.402823466E+38F 172# endif 173#endif 174#ifndef FLT_MIN 175# ifdef MINFLOAT 176# define FLT_MIN MINFLOAT 177# else 178# define FLT_MIN 1.175494351E-38F 179# endif 180#endif 181 182/* 183 * NeXT doesn't define O_NONBLOCK, so #define it here if necessary. 184 */ 185 186#ifndef O_NONBLOCK 187# define O_NONBLOCK 0x80 188#endif 189 190/* 191 * HPUX needs the flag O_NONBLOCK to get the right non-blocking I/O 192 * semantics, while most other systems need O_NDELAY. Define the 193 * constant NBIO_FLAG to be one of these 194 */ 195 196#ifdef HPUX 197# define NBIO_FLAG O_NONBLOCK 198#else 199# define NBIO_FLAG O_NDELAY 200#endif 201 202/* 203 * The type of the status returned by wait varies from UNIX system 204 * to UNIX system. The macro below defines it: 205 */ 206 207#ifdef _AIX 208# define WAIT_STATUS_TYPE pid_t 209#else 210#ifndef NO_UNION_WAIT 211# define WAIT_STATUS_TYPE union wait 212#else 213# define WAIT_STATUS_TYPE int 214#endif 215#endif 216 217/* 218 * Supply definitions for macros to query wait status, if not already 219 * defined in header files above. 220 */ 221 222#ifndef WIFEXITED 223# define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0) 224#endif 225 226#ifndef WEXITSTATUS 227# define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) 228#endif 229 230#ifndef WIFSIGNALED 231# define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff))) 232#endif 233 234#ifndef WTERMSIG 235# define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f) 236#endif 237 238#ifndef WIFSTOPPED 239# define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177) 240#endif 241 242#ifndef WSTOPSIG 243# define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff) 244#endif 245 246/* 247 * Define constants for waitpid() system call if they aren't defined 248 * by a system header file. 249 */ 250 251#ifndef WNOHANG 252# define WNOHANG 1 253#endif 254#ifndef WUNTRACED 255# define WUNTRACED 2 256#endif 257 258/* 259 * Supply macros for seek offsets, if they're not already provided by 260 * an include file. 261 */ 262 263#ifndef SEEK_SET 264# define SEEK_SET 0 265#endif 266#ifndef SEEK_CUR 267# define SEEK_CUR 1 268#endif 269#ifndef SEEK_END 270# define SEEK_END 2 271#endif 272 273/* 274 * The stuff below is needed by the "time" command. If this system has no 275 * gettimeofday call, then must use times and the CLK_TCK #define (from 276 * sys/param.h) to compute elapsed time. Unfortunately, some systems only 277 * have HZ and no CLK_TCK, and some might not even have HZ. 278 */ 279 280#ifdef NO_GETTOD 281# include <sys/times.h> 282# include <sys/param.h> 283# ifndef CLK_TCK 284# ifdef HZ 285# define CLK_TCK HZ 286# else 287# define CLK_TCK 60 288# endif 289# endif 290#else 291# ifdef HAVE_BSDGETTIMEOFDAY 292# define gettimeofday BSDgettimeofday 293# endif 294#endif 295 296#ifdef GETTOD_NOT_DECLARED 297EXTERN int gettimeofday _ANSI_ARGS_((struct timeval *tp, 298 struct timezone *tzp)); 299#endif 300 301/* 302 * Define access mode constants if they aren't already defined. 303 */ 304 305#ifndef F_OK 306# define F_OK 00 307#endif 308#ifndef X_OK 309# define X_OK 01 310#endif 311#ifndef W_OK 312# define W_OK 02 313#endif 314#ifndef R_OK 315# define R_OK 04 316#endif 317 318/* 319 * Define FD_CLOEEXEC (the close-on-exec flag bit) if it isn't 320 * already defined. 321 */ 322 323#ifndef FD_CLOEXEC 324# define FD_CLOEXEC 1 325#endif 326 327/* 328 * On systems without symbolic links (i.e. S_IFLNK isn't defined) 329 * define "lstat" to use "stat" instead. 330 */ 331 332#ifndef S_IFLNK 333# undef TclOSlstat 334# define lstat stat 335# define lstat64 stat64 336# define TclOSlstat TclOSstat 337#endif 338 339/* 340 * Define macros to query file type bits, if they're not already 341 * defined. 342 */ 343 344#ifndef S_ISREG 345# ifdef S_IFREG 346# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 347# else 348# define S_ISREG(m) 0 349# endif 350#endif /* !S_ISREG */ 351#ifndef S_ISDIR 352# ifdef S_IFDIR 353# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 354# else 355# define S_ISDIR(m) 0 356# endif 357#endif /* !S_ISDIR */ 358#ifndef S_ISCHR 359# ifdef S_IFCHR 360# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 361# else 362# define S_ISCHR(m) 0 363# endif 364#endif /* !S_ISCHR */ 365#ifndef S_ISBLK 366# ifdef S_IFBLK 367# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 368# else 369# define S_ISBLK(m) 0 370# endif 371#endif /* !S_ISBLK */ 372#ifndef S_ISFIFO 373# ifdef S_IFIFO 374# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 375# else 376# define S_ISFIFO(m) 0 377# endif 378#endif /* !S_ISFIFO */ 379#ifndef S_ISLNK 380# ifdef S_IFLNK 381# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) 382# else 383# define S_ISLNK(m) 0 384# endif 385#endif /* !S_ISLNK */ 386#ifndef S_ISSOCK 387# ifdef S_IFSOCK 388# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) 389# else 390# define S_ISSOCK(m) 0 391# endif 392#endif /* !S_ISSOCK */ 393 394/* 395 * Make sure that MAXPATHLEN and MAXNAMLEN are defined. 396 */ 397 398#ifndef MAXPATHLEN 399# ifdef PATH_MAX 400# define MAXPATHLEN PATH_MAX 401# else 402# define MAXPATHLEN 2048 403# endif 404#endif 405 406#ifndef MAXNAMLEN 407# ifdef NAME_MAX 408# define MAXNAMLEN NAME_MAX 409# else 410# define MAXNAMLEN 255 411# endif 412#endif 413 414/* 415 * Make sure that L_tmpnam is defined. 416 */ 417 418#ifndef L_tmpnam 419# define L_tmpnam 100 420#endif 421 422/* 423 * The following macro defines the type of the mask arguments to 424 * select: 425 */ 426 427#ifndef NO_FD_SET 428# define SELECT_MASK fd_set 429#else /* NO_FD_SET */ 430# ifndef _AIX 431 typedef long fd_mask; 432# endif /* !AIX */ 433# if defined(_IBMR2) 434# define SELECT_MASK void 435# else /* !defined(_IBMR2) */ 436# define SELECT_MASK int 437# endif /* defined(_IBMR2) */ 438#endif /* !NO_FD_SET */ 439 440/* 441 * Define "NBBY" (number of bits per byte) if it's not already defined. 442 */ 443 444#ifndef NBBY 445# define NBBY 8 446#endif 447 448/* 449 * The following macro defines the number of fd_masks in an fd_set: 450 */ 451 452#ifndef FD_SETSIZE 453# ifdef OPEN_MAX 454# define FD_SETSIZE OPEN_MAX 455# else 456# define FD_SETSIZE 256 457# endif 458#endif /* FD_SETSIZE */ 459#if !defined(howmany) 460# define howmany(x, y) (((x)+((y)-1))/(y)) 461#endif /* !defined(howmany) */ 462#ifndef NFDBITS 463# define NFDBITS NBBY*sizeof(fd_mask) 464#endif /* NFDBITS */ 465#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS) 466 467/* 468 * Not all systems declare the errno variable in errno.h. so this 469 * file does it explicitly. The list of system error messages also 470 * isn't generally declared in a header file anywhere. 471 */ 472 473#ifdef NO_ERRNO 474extern int errno; 475#endif 476 477/* 478 * Not all systems declare all the errors that Tcl uses! Provide some 479 * work-arounds... 480 */ 481 482#ifndef EOVERFLOW 483# ifdef EFBIG 484# define EOVERFLOW EFBIG 485# else /* !EFBIG */ 486# define EOVERFLOW EINVAL 487# endif /* EFBIG */ 488#endif /* EOVERFLOW */ 489 490/* 491 * Variables provided by the C library: 492 */ 493 494#if defined(__APPLE__) && defined(__DYNAMIC__) 495# include <crt_externs.h> 496# define environ (*_NSGetEnviron()) 497# define USE_PUTENV 1 498#else 499# if defined(_sgi) || defined(__sgi) 500# define environ _environ 501# endif 502extern char **environ; 503#endif 504 505/* 506 * At present (12/91) not all stdlib.h implementations declare strtod. 507 * The declaration below is here to ensure that it's declared, so that 508 * the compiler won't take the default approach of assuming it returns 509 * an int. There's no ANSI prototype for it because there would end 510 * up being too many conflicts with slightly-different prototypes. 511 */ 512 513extern double strtod(); 514 515/* 516 * There is no platform-specific panic routine for Unix in the Tcl internals. 517 */ 518 519#define TclpPanic ((Tcl_PanicProc *) NULL) 520 521/* 522 * Darwin specifc configure overrides. 523 */ 524 525#ifdef __APPLE__ 526/* 527 * Support for fat compiles: configure runs only once for multiple architectures 528 */ 529# if defined(__LP64__) && defined (NO_COREFOUNDATION_64) 530# undef HAVE_COREFOUNDATION 531# endif /* __LP64__ && NO_COREFOUNDATION_64 */ 532# include <sys/cdefs.h> 533# ifdef __DARWIN_UNIX03 534# if __DARWIN_UNIX03 535# undef HAVE_PUTENV_THAT_COPIES 536# else 537# define HAVE_PUTENV_THAT_COPIES 1 538# endif 539# endif /* __DARWIN_UNIX03 */ 540/* 541 * The termios configure test program relies on the configure script being run 542 * from a terminal, which is not the case e.g. when configuring from Xcode. 543 * Since termios is known to be present on all Mac OS X releases since 10.0, 544 * override the configure defines for serial API here. [Bug 497147] 545 */ 546# define USE_TERMIOS 1 547# undef USE_TERMIO 548# undef USE_SGTTY 549/* 550 * Include AvailabilityMacros.h here (when available) to ensure any symbolic 551 * MAC_OS_X_VERSION_* constants passed on the command line are translated. 552 */ 553# ifdef HAVE_AVAILABILITYMACROS_H 554# include <AvailabilityMacros.h> 555# endif 556/* 557 * Support for weak import. 558 */ 559# ifdef HAVE_WEAK_IMPORT 560# if !defined(HAVE_AVAILABILITYMACROS_H) || !defined(MAC_OS_X_VERSION_MIN_REQUIRED) 561# undef HAVE_WEAK_IMPORT 562# else 563# ifndef WEAK_IMPORT_ATTRIBUTE 564# define WEAK_IMPORT_ATTRIBUTE __attribute__((weak_import)) 565# endif 566# endif 567# endif /* HAVE_WEAK_IMPORT */ 568/* 569 * Support for MAC_OS_X_VERSION_MAX_ALLOWED define from AvailabilityMacros.h: 570 * only use API available in the indicated OS version or earlier. 571 */ 572# ifdef MAC_OS_X_VERSION_MAX_ALLOWED 573# if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 && defined(__LP64__) 574# undef HAVE_COREFOUNDATION 575# endif 576# if MAC_OS_X_VERSION_MAX_ALLOWED < 1040 577# undef HAVE_OSSPINLOCKLOCK 578# undef HAVE_PTHREAD_ATFORK 579# undef HAVE_COPYFILE 580# endif 581# if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 582# ifdef TCL_THREADS 583 /* prior to 10.3, realpath is not threadsafe, c.f. bug 711232 */ 584# define NO_REALPATH 1 585# endif 586# undef HAVE_LANGINFO 587# endif 588# endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ 589# if defined(HAVE_COREFOUNDATION) && defined(__LP64__) && \ 590 defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1050 591# warning "Weak import of 64-bit CoreFoundation is not supported, will not run on Mac OS X < 10.5." 592# endif 593/* 594 * At present, using vfork() instead of fork() causes execve() to fail 595 * intermittently on Darwin x86_64. rdar://4685553 596 */ 597# if defined(__x86_64__) && !defined(FIXED_RDAR_4685553) 598# undef USE_VFORK 599# endif /* __x86_64__ */ 600/* Workaround problems with vfork() when building with llvm-gcc-4.2 */ 601# if defined (__llvm__) && \ 602 (__GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ > 2 || \ 603 (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 0)))) 604# undef USE_VFORK 605# endif /* __llvm__ */ 606#endif /* __APPLE__ */ 607 608/* 609 * Darwin 8 copyfile API. 610 */ 611 612#ifdef HAVE_COPYFILE 613#ifdef HAVE_COPYFILE_H 614#include <copyfile.h> 615#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040 616/* Support for weakly importing copyfile. */ 617#define WEAK_IMPORT_COPYFILE 618extern int copyfile(const char *from, const char *to, copyfile_state_t state, 619 copyfile_flags_t flags) WEAK_IMPORT_ATTRIBUTE; 620#endif /* HAVE_WEAK_IMPORT */ 621#else /* HAVE_COPYFILE_H */ 622int copyfile(const char *from, const char *to, void *state, uint32_t flags); 623#define COPYFILE_ACL (1<<0) 624#define COPYFILE_XATTR (1<<2) 625#define COPYFILE_NOFOLLOW_SRC (1<<18) 626#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040 627/* Support for weakly importing copyfile. */ 628#define WEAK_IMPORT_COPYFILE 629extern int copyfile(const char *from, const char *to, void *state, 630 uint32_t flags) WEAK_IMPORT_ATTRIBUTE; 631#endif /* HAVE_WEAK_IMPORT */ 632#endif /* HAVE_COPYFILE_H */ 633#endif /* HAVE_COPYFILE */ 634 635/* 636 *--------------------------------------------------------------------------- 637 * The following macros and declarations represent the interface between 638 * generic and unix-specific parts of Tcl. Some of the macros may override 639 * functions declared in tclInt.h. 640 *--------------------------------------------------------------------------- 641 */ 642 643/* 644 * The default platform eol translation on Unix is TCL_TRANSLATE_LF. 645 */ 646 647#ifdef DJGPP 648#define TCL_PLATFORM_TRANSLATION TCL_TRANSLATE_CRLF 649#else 650#define TCL_PLATFORM_TRANSLATION TCL_TRANSLATE_LF 651#endif 652 653/* 654 * The following macros have trivial definitions, allowing generic code to 655 * address platform-specific issues. 656 */ 657 658#define TclpGetPid(pid) ((unsigned long) (pid)) 659#define TclpReleaseFile(file) /* Nothing. */ 660 661/* 662 * The following defines wrap the system memory allocation routines for 663 * use by tclAlloc.c. By default off unused on Unix. 664 */ 665 666#if USE_TCLALLOC 667# define TclpSysAlloc(size, isBin) malloc((size_t)size) 668# define TclpSysFree(ptr) free((char*)ptr) 669# define TclpSysRealloc(ptr, size) realloc((char*)ptr, (size_t)size) 670#endif 671 672/* 673 * The following macros and declaration wrap the C runtime library 674 * functions. 675 */ 676 677#define TclpExit exit 678 679/* 680 * Platform specific mutex definition used by memory allocators. 681 * These mutexes are statically allocated and explicitly initialized. 682 * Most modules do not use this, but instead use Tcl_Mutex types and 683 * Tcl_MutexLock and Tcl_MutexUnlock that are self-initializing. 684 */ 685 686#ifdef TCL_THREADS 687#include <pthread.h> 688typedef pthread_mutex_t TclpMutex; 689EXTERN void TclpMutexInit _ANSI_ARGS_((TclpMutex *mPtr)); 690EXTERN void TclpMutexLock _ANSI_ARGS_((TclpMutex *mPtr)); 691EXTERN void TclpMutexUnlock _ANSI_ARGS_((TclpMutex *mPtr)); 692EXTERN Tcl_DirEntry * TclpReaddir(DIR *); 693#ifndef TclpLocaltime 694EXTERN struct tm * TclpLocaltime(TclpTime_t_CONST); 695#endif 696#ifndef TclpGmtime 697EXTERN struct tm * TclpGmtime(TclpTime_t_CONST); 698#endif 699EXTERN char * TclpInetNtoa(struct in_addr); 700#define inet_ntoa(x) TclpInetNtoa(x) 701#else 702typedef int TclpMutex; 703#define TclpMutexInit(a) 704#define TclpMutexLock(a) 705#define TclpMutexUnlock(a) 706#endif /* TCL_THREADS */ 707 708 709/* 710 * Set of MT-safe implementations of some 711 * known-to-be-MT-unsafe library calls. 712 * Instead of returning pointers to the 713 * static storage, those return pointers 714 * to the TSD data. 715 */ 716 717#include <pwd.h> 718#include <grp.h> 719 720EXTERN struct passwd* TclpGetPwNam(const char *name); 721EXTERN struct group* TclpGetGrNam(const char *name); 722EXTERN struct passwd* TclpGetPwUid(uid_t uid); 723EXTERN struct group* TclpGetGrGid(gid_t gid); 724EXTERN struct hostent* TclpGetHostByName(const char *name); 725EXTERN struct hostent* TclpGetHostByAddr(const char *addr, int length, int type); 726 727#include "tclPlatDecls.h" 728#include "tclIntPlatDecls.h" 729 730#endif /* _TCLUNIXPORT */ 731