458 lines
15 KiB
C
458 lines
15 KiB
C
//
|
|
// The developer of the original code and/or files is Tripwire, Inc.
|
|
// Portions created by Tripwire, Inc. are copyright (C) 2000-2019 Tripwire,
|
|
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
|
|
// reserved.
|
|
//
|
|
// This program is free software. The contents of this file are subject
|
|
// to the terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 2 of the License, or (at your
|
|
// option) any later version. You may redistribute it and/or modify it
|
|
// only in compliance with the GNU General Public License.
|
|
//
|
|
// This program is distributed in the hope that it will be useful.
|
|
// However, this program is distributed AS-IS WITHOUT ANY
|
|
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
|
|
// for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
// USA.
|
|
//
|
|
// Nothing in the GNU General Public License or any other license to use
|
|
// the code or files shall permit you to use Tripwire's trademarks,
|
|
// service marks, or other intellectual property without Tripwire's
|
|
// prior written consent.
|
|
//
|
|
// If you have any questions, please contact Tripwire, Inc. at either
|
|
// info@tripwire.org or www.tripwire.org.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// platform.h
|
|
//
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifndef __PLATFORM_H
|
|
# define __PLATFORM_H
|
|
|
|
//NOTE: Autoconf is strongly preferred as the Right Way to detect platform-specific features/behaviors.
|
|
// These macros should really only be used when autoconf can't get the job done.
|
|
|
|
//=============================================================================
|
|
// Enumerations
|
|
//
|
|
// For each of these "enumerations" we create unique integers identifying each
|
|
// variation. We group similar items together, such as OS_REDHAT and OS_SLACKWARE
|
|
|
|
# define OS_UNKNOWN 0
|
|
|
|
# define OS_WIN32 0x0101
|
|
# define OS_CYGWIN 0x0102
|
|
# define OS_DOS_DJGPP 0x0103
|
|
|
|
# define OS_LINUX 0x0201
|
|
# define OS_ANDROID 0x0202
|
|
|
|
# define OS_FREEBSD 0x0301
|
|
# define OS_NETBSD 0x0302
|
|
# define OS_OPENBSD 0x0303
|
|
# define OS_DARWIN 0x0304
|
|
# define OS_DRAGONFLYBSD 0x0305
|
|
# define OS_MIDNIGHTBSD 0x0306
|
|
# define OS_MIRBSD 0x0307
|
|
# define OS_BITRIG 0x0308
|
|
# define OS_LIBERTYBSD 0x0309
|
|
# define OS_BSDI 0x030A
|
|
|
|
# define OS_SOLARIS 0x0400
|
|
# define OS_AIX 0x0401
|
|
# define OS_HPUX 0x0402
|
|
# define OS_IRIX 0x0403
|
|
# define OS_OSF1 0x0404
|
|
# define OS_OS400 0x0405
|
|
|
|
# define OS_MINIX 0x0501
|
|
# define OS_HURD 0x0502
|
|
# define OS_HAIKU 0x0503
|
|
# define OS_SYLLABLE 0x0504
|
|
# define OS_SKYOS 0x0505
|
|
# define OS_SORTIX 0x0506
|
|
# define OS_MINT 0x0507
|
|
# define OS_AROS 0x0508
|
|
# define OS_RTEMS 0x0509
|
|
# define OS_RISCOS 0x050A
|
|
# define OS_REDOX 0x050B
|
|
# define OS_QNX 0x050C
|
|
# define OS_VXWORKS 0x50D
|
|
# define OS_LYNXOS 0x50E
|
|
# define OS_OS9 0x50F // For Microware's OS-9, not the Apple one.
|
|
# define OS_PLAN9 0x510
|
|
|
|
# define COMP_UNKNOWN 0
|
|
# define COMP_GCC 0x0001
|
|
# define COMP_CLANG 0x0002
|
|
|
|
# define COMP_MSVC 0x0101
|
|
|
|
// Definitions for the old KAI C++ compiler.
|
|
// KCC was EOL'd ages ago, but I'm leaving these definitions here for now
|
|
// on the off chance someone's still using it.
|
|
# define COMP_KAI_GCC 0x0201
|
|
# define COMP_KAI_SUNPRO 0x0202
|
|
# define COMP_KAI_GLIBC 0x0203
|
|
# define COMP_KAI_VISUALAGE 0x0204
|
|
# define COMP_KAI_HPANSIC 0x0205
|
|
# define COMP_KAI_IRIX 0x0206
|
|
# define COMP_KAI_OSF1ALPHA 0x0207
|
|
|
|
# define COMP_SUNPRO 0x0301
|
|
# define COMP_XL_C 0x0302
|
|
# define COMP_ACC 0x0303
|
|
|
|
//=============================================================================
|
|
// Platform detection
|
|
//
|
|
// Using boolean logic on predefined compilers variables, detect and set
|
|
// PLATFORM preprosessor defines to the unique ID specified above.
|
|
//
|
|
// The following definitions are set in this section:
|
|
//
|
|
// OS The OS
|
|
// COMP The compiler
|
|
//
|
|
// PLEASE NOTE: Do not set any preprocessor variable other than the above three in this
|
|
// section. Use the following sections for anything that does not fall into
|
|
// the above catagories.
|
|
|
|
# if defined(_WIN32)
|
|
# define OS OS_WIN32
|
|
# define IS_WIN32 1
|
|
|
|
# elif defined(__CYGWIN__)
|
|
# define OS OS_CYGWIN
|
|
# define IS_CYGWIN 1
|
|
|
|
# elif defined(__DJGPP__)
|
|
# define OS OS_DOS_DJGPP
|
|
# define IS_DOS_DJGPP 1
|
|
|
|
// Detect Android first, since Linux macros are also defined there
|
|
# elif defined(__ANDROID__)
|
|
# define OS OS_ANDROID
|
|
# define IS_ANDROID 1
|
|
|
|
# elif defined(__linux__)
|
|
# define OS OS_LINUX
|
|
# define IS_LINUX 1
|
|
|
|
|
|
// A herd of BSDs. Have to detect MidnightBSD before FreeBSD, and MirOS & Bitrig before OpenBSD
|
|
// because they also define symbols for their ancestor BSDs.
|
|
# elif defined(__DragonFly__)
|
|
# define OS OS_DRAGONFLYBSD
|
|
# define IS_DRAGONFLYBSD 1
|
|
|
|
# elif defined(__MidnightBSD__)
|
|
# define OS OS_MIDNIGHTBSD
|
|
# define IS_MIDNIGHTBSD 1
|
|
|
|
# elif defined(__FreeBSD__)
|
|
# define OS OS_FREEBSD
|
|
# define IS_FREEBSD 1
|
|
|
|
# elif defined(__NetBSD__)
|
|
# define OS OS_NETBSD
|
|
# define IS_NETBSD 1
|
|
|
|
# elif defined(__MirBSD__)
|
|
# define OS OS_MIRBSD
|
|
# define IS_MIRBSD 1
|
|
|
|
# elif defined(__Bitrig__)
|
|
# define OS OS_BITRIG
|
|
# define IS_BITRIG 1
|
|
|
|
// Detect LibertyBSD first since OpenBSD macros are also defined.
|
|
// Autotools can tell them apart by target triplet, so we define
|
|
// 'TW_LibertybSD' there and pass it in.
|
|
# elif defined(TW_LibertyBSD)
|
|
# define OS OS_LIBERTYBSD
|
|
# define IS_LIBERTYBSD 1
|
|
|
|
# elif defined(__OpenBSD__)
|
|
# define OS OS_OPENBSD
|
|
# define IS_OPENBSD 1
|
|
|
|
# elif defined(__APPLE__)
|
|
# define OS OS_DARWIN
|
|
# define IS_DARWIN 1
|
|
|
|
|
|
# elif defined(__sun)
|
|
# define OS OS_SOLARIS
|
|
# define IS_SOLARIS 1
|
|
|
|
# elif defined(_AIX)
|
|
# define OS OS_AIX
|
|
# define IS_AIX 1
|
|
# if defined(__PASE__)
|
|
# define IS_PASE 1
|
|
# endif
|
|
|
|
# elif defined(__hpux)
|
|
# define OS OS_HPUX
|
|
# define IS_HPUX 1
|
|
|
|
# elif defined(__sgi)
|
|
# define OS OS_IRIX
|
|
# define IS_IRIX 1
|
|
|
|
# elif defined(TRU64) || defined(__OSF1__)
|
|
# define OS OS_OSF1
|
|
# define IS_OSF1 1
|
|
|
|
# elif defined(__OS400__)
|
|
# define OS OS_OS400
|
|
# define IS_OS400 1
|
|
|
|
# elif defined(__minix__)
|
|
# define OS OS_MINIX
|
|
# define IS_MINIX 1
|
|
|
|
# elif defined(__gnu_hurd__)
|
|
# define OS OS_HURD
|
|
# define IS_HURD 1
|
|
|
|
# elif defined(__HAIKU__)
|
|
# define OS OS_HAIKU
|
|
# define IS_HAIKU 1
|
|
|
|
# elif defined(__SYLLABLE__)
|
|
# define OS OS_SYLLABLE
|
|
# define IS_SYLLABLE 1
|
|
|
|
# elif defined(SKYOS)
|
|
# define OS OS_SKYOS
|
|
# define IS_SKYOS 1
|
|
|
|
# elif defined(_SORTIX_SOURCE)
|
|
# define OS OS_SORTIX
|
|
# define IS_SORTIX 1
|
|
|
|
# elif defined(__MINT__)
|
|
# define OS OS_MINT
|
|
# define IS_MINT 1
|
|
|
|
# elif defined(__AROS__)
|
|
# define OS OS_AROS
|
|
# define IS_AROS 1
|
|
|
|
# elif defined(__rtems__)
|
|
# define OS OS_RTEMS
|
|
# define IS_RTEMS 1
|
|
|
|
# elif defined(__riscos__)
|
|
# define OS OS_RISCOS
|
|
# define IS_RISCOS 1
|
|
|
|
# elif defined(__redox__)
|
|
# define OS OS_REDOX
|
|
# define IS_REDOX 1
|
|
|
|
# elif defined(__QNX__) || defined(__QNXNTO__)
|
|
# define OS OS_QNX
|
|
# define IS_QNX 1
|
|
|
|
# elif defined(__VXWORKS__)
|
|
# define OS OS_VXWORKS
|
|
# define IS_VXWORKS 1
|
|
|
|
# elif defined(__Lynx__)
|
|
# define OS OS_LYNXOS
|
|
# define IS_LYNXOS 1
|
|
|
|
# elif defined(__OS9000)
|
|
# define OS OS_OS9
|
|
# define IS_OS9 1
|
|
|
|
# elif defined(EPLAN9)
|
|
# define OS OS_PLAN9
|
|
# define IS_PLAN9 1
|
|
|
|
# endif
|
|
|
|
|
|
/* XXX: COMP may now not resolve, because autoconf may
|
|
* detect GCC. This is done in the hopes that all
|
|
* COMP detections, and indeed both OS & COMP detechtions
|
|
* will eventualy be done automatically.
|
|
*
|
|
* This means, the former "#if !defined(COMP)" will
|
|
* temporarily have to also check the HAVE_[compiler]
|
|
* #defines until all compilers are checked by autoconf,
|
|
* at which point this can be removed completely.
|
|
*
|
|
* PH - 20010311
|
|
*/
|
|
# if !defined(COMP) && !defined(HAVE_GCC)
|
|
# error COMP definition did not resolve. Check "platform.h".
|
|
# endif
|
|
|
|
//=============================================================================
|
|
// Platform Macros (a.k.a. "IS_" macros)
|
|
//
|
|
// These macros are the "worker bees" of platform.h. Programmers should use
|
|
// these macros rather than comparing PLATFORM to the unique IDs by hand.
|
|
//
|
|
// NOTE: Wherever possible, let autotools figure this out & define it in config.h
|
|
// rather than hardcoding it here. If autotools misdefines something, use
|
|
// core/fixups.h, which is guaranteed to be (re)included right after config.h
|
|
//
|
|
// NB: Programmers are STRONGLY ENCOURAGED not to use the OS detection macros
|
|
// or compiler detection marcros directly. Instead they should create
|
|
// macros specific to the task at hand. For example Win32 and Solaris support
|
|
// extended permissions for their files. Rather than check IS_WIN32 || IS_SOLARIS,
|
|
// create a new macro called "HAS_EXTENDED_FILE_PERMISSIONS" and use that.
|
|
//
|
|
// One case where it is reasonable to use the IS_WIN32 or IS_UNIX is when
|
|
// you need to protect a #include that is specific to a platform.
|
|
//
|
|
// Example usage:
|
|
//
|
|
// #ifdef WORDS_BIGENDIAN
|
|
// int network_order = machine_order;
|
|
// #else
|
|
// int network_order = swap(machine_order);
|
|
// #endif
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
// complier detection
|
|
# define IS_KAI \
|
|
(COMP == COMP_KAI_GCC || COMP == COMP_KAI_SUNPRO || COMP == COMP_KAI_GLIBC || COMP == COMP_KAI_VISUALAGE || \
|
|
COMP == COMP_KAI_HPANSIC || COMP == COMP_KAI_IRIX || COMP == COMP_KAI_OSF1ALPHA)
|
|
# define IS_MSVC (COMP == COMP_MSVC)
|
|
# define IS_SUNPRO (COMP == COMP_SUNPRO)
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// Unicode
|
|
# define SUPPORTS_UNICODE IS_WIN32 // The OS supports Unicode
|
|
|
|
// KAI 3.4 uses a much improved stl
|
|
# define IS_KAI_3_4 (IS_KAI && (COMP == COMP_KAI_IRIX || COMP == COMP_KAI_OSF1ALPHA || COMP == COMP_KAI_GLIBC))
|
|
|
|
// Used in twlocale
|
|
# define USE_STD_CPP_LOCALE_WORKAROUND \
|
|
(IS_SUNPRO || (IS_KAI && !IS_KAI_3_4)) // TODO:BAM -- name this something more general.
|
|
# define USE_CLIB_LOCALE (!HAVE_LOCALE || HAVE_GCC || IS_KAI)
|
|
# define USES_CLIB_DATE_FUNCTION \
|
|
(USE_CLIB_LOCALE || IS_SUNPRO || \
|
|
IS_MSVC) // if we use clib, can't use C++ time_put, and SUNPRO and MSVC add characters
|
|
//#define USE_CLIB_LOCALE (IS_ALPHA || IS_IRIX || (IS_KAI && !IS_KAI_3_4))
|
|
|
|
// Threading API
|
|
# define SUPPORTS_WIN32_THREADS IS_WIN32
|
|
# define SUPPORTS_POSIX_THREADS (HAVE_PTHREAD_GETSPECIFIC)
|
|
|
|
// Miscellaneous
|
|
# define SUPPORTS_C_FILE_IO (HAVE_FOPEN && HAVE_FREAD && HAVE_FCLOSE)
|
|
# define SUPPORTS_POSIX_FILE_IO (HAVE_OPEN && HAVE_READ && HAVE_CLOSE)
|
|
|
|
# define WCHAR_IS_16_BITS IS_WIN32
|
|
# define WCHAR_IS_32_BITS IS_UNIX
|
|
# define WCHAR_REP_IS_UCS2 IS_WIN32
|
|
|
|
# define SUPPORTS_POSIX_FORK_EXEC (HAVE_FORK && HAVE_EXECVE)
|
|
// msystem+mpopen fail on Syllable, so use the libc equivalents until we figure out why.
|
|
// TODO: Figure out why.
|
|
# define USES_MPOPEN (SUPPORTS_POSIX_FORK_EXEC && !IS_SYLLABLE)
|
|
# define USES_MSYSTEM (SUPPORTS_POSIX_FORK_EXEC && !IS_SYLLABLE)
|
|
# define SUPPORTS_WCHART IS_WIN32 // TODO: Remove after getting new ver of KAI
|
|
# define USES_GLIBC ((COMP == COMP_KAI_GLIBC) || HAVE_GCC)
|
|
# define SUPPORTS_MEMBER_TEMPLATES (!IS_SUNPRO)
|
|
# define SUPPORTS_EXPLICIT_TEMPLATE_FUNC_INST (!IS_SUNPRO)
|
|
|
|
# define SUPPORTS_POSIX_SIGNALS (!IS_DOS_DJGPP)
|
|
# define SUPPORTS_NETWORKING (HAVE_SOCKET && !IS_SORTIX && !IS_DOS_DJGPP && !IS_REDOX)
|
|
# define SUPPORTS_SYSLOG (HAVE_SYSLOG && !IS_SKYOS && !IS_RISCOS)
|
|
# define NEEDS_SWAB_IMPL (IS_CYGWIN || IS_SYLLABLE || IS_ANDROID || IS_SORTIX)
|
|
# define USES_MBLEN (!IS_ANDROID && !IS_AROS)
|
|
# define USES_DEVICE_PATH (IS_AROS || IS_DOS_DJGPP || IS_WIN32 || IS_RISCOS || IS_REDOX)
|
|
# define ICONV_CONST_SOURCE (IS_MINIX)
|
|
# define SUPPORTS_DIRECT_IO (IS_LINUX)
|
|
|
|
// HP-UX does have posix_fadvise(), but sys/fcntl.h neglects to wrap it in extern "C" on
|
|
// at least some flavors of the OS. (see https://community.hpe.com/t5/Languages-and-Scripting/Bacula-try-to-compile-on-hpux11-31/m-p/6843389 )
|
|
// The thread indicates this problem can be fixed by editing sys/fcntl.h, and then the !IS_HPUX below
|
|
// can be removed. This is left as an exercise for the reader.
|
|
# define SUPPORTS_POSIX_FADVISE (HAVE_POSIX_FADVISE && !IS_HPUX)
|
|
|
|
# define READ_TAKES_CHAR_PTR (IS_VXWORKS)
|
|
# define BCOPY_TAKES_CHAR_PTR (IS_VXWORKS)
|
|
|
|
// Linux is the only platform where direct i/o hashing has been tested & works properly so far.
|
|
|
|
# define SUPPORTS_TERMIOS (HAVE_TERMIOS_H && (!IS_RTEMS && !IS_REDOX))
|
|
// RTEMS errors are probably just a buildsys issue & this will change or go away.
|
|
// Redox will probably implement this in the future.
|
|
|
|
# define CAN_UNLINK_WHILE_OPEN (!IS_AROS && !IS_RISCOS && !IS_REDOX && !IS_DOS_DJGPP)
|
|
|
|
# define SUPPORTS_DOUBLE_SLASH_PATH (IS_CYGWIN)
|
|
// POSIX standard says paths beginning with 2 slashes are "implementation defined"
|
|
// (see http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11 )
|
|
// The only platform OST is known to work on (afaik) that actually defines a double-slash behavior is Cygwin
|
|
// which uses this syntax for UNC paths. So we'll allow leading double slashes there, but
|
|
// continue removing them on all other platforms for now.
|
|
// Other platform known to use this include IBM z/OS and the ancient Apollo Domain/OS.
|
|
//
|
|
|
|
# define USE_DEV_URANDOM (HAVE_DEV_URANDOM && ENABLE_DEV_URANDOM)
|
|
|
|
// Platforms where we might encounter AS/400 native objects,
|
|
// which are only sometimes readable via ordinary file API
|
|
# define SUPPORTS_NATIVE_OBJECTS (IS_AIX || IS_OS400)
|
|
|
|
// On most platforms, uname() returns 0 on success, like every other syscall out there.
|
|
// However the POSIX standard merely says uname() returns some nonnegative value on success, probably
|
|
// so certain vendors could be POSIX-compliant without changing anything. Solaris seems to return 1
|
|
// on success, for example. If any other examples crop up, add them here.
|
|
#if IS_SOLARIS
|
|
# define UNAME_SUCCESS_POSIX 1
|
|
#else
|
|
# define UNAME_SUCCESS_ZERO
|
|
#endif
|
|
|
|
|
|
//=============================================================================
|
|
// Miscellaneous
|
|
//
|
|
// Put all items that are not an "IS_" macro here.
|
|
|
|
# if IS_BYTE_ALIGNED
|
|
# define BYTE_ALIGN 8
|
|
# else
|
|
# error Unknown Byte alignment
|
|
# endif
|
|
|
|
// A scalar that matches the sizeof a pointer
|
|
typedef unsigned long ptr_size_type; // true for all of our current platforms
|
|
// TODO: I would like to use a XXXX_t like name
|
|
|
|
// Check integer representation
|
|
# if !(USES_2S_COMPLEMENT)
|
|
# error "Tripwire will only work on a 2's complement CPU. Check \"platform.h\"."
|
|
# endif
|
|
|
|
|
|
#endif // __PLATFORM_H
|