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