/* src/vm/os.hpp - system (OS) functions Copyright (C) 2007, 2008, 2009, 2010, 2011 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO Copyright (C) 2008 Theobroma Systems Ltd. This file is part of CACAO. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _OS_HPP #define _OS_HPP #include "config.h" // NOTE: In this file we check for all system headers, because we wrap // all system calls into inline functions for better portability. // Please don't include CACAO headers here as this header should be a // very low-level one. #if defined(HAVE_DIRENT_H) # include #endif #if defined(HAVE_DLFCN_H) # include #endif #if defined(HAVE_ERRNO_H) # include #endif #if defined(HAVE_EXECINFO_H) # include #endif #if defined(HAVE_FCNTL_H) # include #endif #if defined(ENABLE_JRE_LAYOUT) # if defined(HAVE_LIBGEN_H) # include # endif #endif #if defined(HAVE_SIGNAL_H) # include #endif #if defined(HAVE_STDARG_H) # include #endif #if defined(HAVE_STDINT_H) # include #endif #if defined(HAVE_STDIO_H) # include #endif #if defined(HAVE_STDLIB_H) # include #endif #if defined(HAVE_STRING_H) # include #endif #if defined(HAVE_UNISTD_H) # include #endif #if defined(__DARWIN__) # if defined(HAVE_MACH_MACH_H) # include # endif #endif #if defined(HAVE_SYS_LOADAVG_H) # include #endif #if defined(HAVE_SYS_MMAN_H) # include #endif #if defined(HAVE_SYS_SOCKET_H) # include #endif #if defined(HAVE_SYS_STAT_H) # include #endif #if defined(HAVE_SYS_TYPES_H) # include #endif #if defined(HAVE_SYS_UTSNAME_H) # include #endif #ifdef __cplusplus // Class wrapping system (OS) functions. class os { public: // Inline functions. static inline void abort(); static inline int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen); static inline int access(const char *pathname, int mode); static inline int atoi(const char* nptr); static inline int backtrace(void** array, int size); static inline char** backtrace_symbols(void* const* array, int size) throw (); static inline void* calloc(size_t nmemb, size_t size); static inline int close(int fd); static inline int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen); #if defined(ENABLE_JRE_LAYOUT) static inline char* dirname(char* path); #endif static inline int dlclose(void* handle); static inline char* dlerror(void); static inline void* dlopen(const char* filename, int flag); static inline void* dlsym(void* handle, const char* symbol); static inline int fclose(FILE* fp); static inline FILE* fopen(const char* path, const char* mode); static inline int vfprintf ( FILE * stream, const char * format, va_list arg ); static inline size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream); static inline void free(void* ptr); static inline char* getcwd(char* buf, size_t size); static inline char* getenv(const char* name); static inline int gethostname(char* name, size_t len); static inline int getloadavg(double loadavg[], int nelem); static inline int getpagesize(void); static inline pid_t getpid(void); static inline int getsockname(int s, struct sockaddr* name, socklen_t* namelen); static inline int getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen); static inline int listen(int sockfd, int backlog); static inline void* malloc(size_t size); static inline void* memcpy(void* dest, const void* src, size_t n); static inline void* memset(void* s, int c, size_t n); static inline int mprotect(void* addr, size_t len, int prot); static inline ssize_t readlink(const char* path, char* buf, size_t bufsiz); static inline int scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*)); static inline ssize_t send(int s, const void* buf, size_t len, int flags); static inline int setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen); static inline int shutdown(int s, int how); static inline int socket(int domain, int type, int protocol); static inline int stat(const char* path, struct stat* buf); #if defined(__SOLARIS__) static inline int str2sig(const char* str, int* signum); #endif static inline char* strcat(char* dest, const char* src); static inline int strcmp(const char* s1, const char* s2); static inline char* strcpy(char* dest, const char* src); static inline char* strdup(const char* s); static inline size_t strlen(const char* s); static inline char* strerror(int errnum); // Convenience functions. static void abort(const char* text, ...); static void abort_errnum(int errnum, const char* text, ...); static void abort_errno(const char* text, ...); static char* getcwd(void); static void* mmap_anonymous(void *addr, size_t len, int prot, int flags); static void print_backtrace(); static int processors_online(); // Template helper template static int call_scandir(int (*scandir)(const char *, struct dirent ***, _F1, _F2), const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *)); }; inline void os::abort(void) { #if defined(HAVE_ABORT) ::abort(); #else # error abort not available #endif } inline int os::accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen) { #if defined(HAVE_ACCEPT) return ::accept(sockfd, addr, addrlen); #else # error accept not available #endif } inline int os::access(const char* pathname, int mode) { #if defined(HAVE_ACCESS) return ::access(pathname, mode); #else # error access not available #endif } inline int os::atoi(const char* nptr) { #if defined(HAVE_ATOI) return ::atoi(nptr); #else # error atoi not available #endif } inline int os::backtrace(void** array, int size) { #if defined(HAVE_BACKTRACE) return ::backtrace(array, size); #else fprintf(stderr, "os::backtrace: Not available."); return 0; #endif } inline char** os::backtrace_symbols(void* const* array, int size) throw () { #if defined(HAVE_BACKTRACE_SYMBOLS) return ::backtrace_symbols(array, size); #else fprintf(stderr, "os::backtrace_symbols: Not available."); return NULL; #endif } inline void* os::calloc(size_t nmemb, size_t size) { #if defined(HAVE_CALLOC) return ::calloc(nmemb, size); #else # error calloc not available #endif } inline int os::close(int fd) { #if defined(HAVE_CLOSE) return ::close(fd); #else # error close not available #endif } inline int os::connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen) { #if defined(HAVE_CONNECT) return ::connect(sockfd, serv_addr, addrlen); #else # error connect not available #endif } #if defined(ENABLE_JRE_LAYOUT) inline char* os::dirname(char* path) { #if defined(HAVE_DIRNAME) return ::dirname(path); #else # error dirname not available #endif } #endif inline int os::dlclose(void* handle) { #if defined(HAVE_DLCLOSE) return ::dlclose(handle); #else # error dlclose not available #endif } inline char* os::dlerror(void) { #if defined(HAVE_DLERROR) // At least FreeBSD defines dlerror() to return a const char*, so // we simply cast it. return (char*) ::dlerror(); #else # error dlerror not available #endif } inline void* os::dlopen(const char* filename, int flag) { #if defined(HAVE_DLOPEN) return ::dlopen(filename, flag); #else # error dlopen not available #endif } inline void* os::dlsym(void* handle, const char* symbol) { #if defined(HAVE_DLSYM) return ::dlsym(handle, symbol); #else # error dlsym not available #endif } inline int os::fclose(FILE* fp) { #if defined(HAVE_FCLOSE) return ::fclose(fp); #else # error fclose not available #endif } inline FILE* os::fopen(const char* path, const char* mode) { #if defined(HAVE_FOPEN) return ::fopen(path, mode); #else # error fopen not available #endif } //fprintf is mandatory and can't be replaced with an equivalent fast wrapper #if !defined (HAVE_FPRINTF) #error fprintf not available #endif inline int os::vfprintf ( FILE * stream, const char * format, va_list arg ) { #if defined(HAVE_VFPRINTF) int result = ::vfprintf(stream, format, arg); return result; #else # error vfprintf not available #endif } inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { #if defined(HAVE_FREAD) return ::fread(ptr, size, nmemb, stream); #else # error fread not available #endif } inline void os::free(void* ptr) { #if defined(HAVE_FREE) ::free(ptr); #else # error free not available #endif } inline static int system_fsync(int fd) { #if defined(HAVE_FSYNC) return fsync(fd); #else # error fsync not available #endif } inline static int system_ftruncate(int fd, off_t length) { #if defined(HAVE_FTRUNCATE) return ftruncate(fd, length); #else # error ftruncate not available #endif } inline char* os::getcwd(char* buf, size_t size) { #if defined(HAVE_GETCWD) return ::getcwd(buf, size); #else # error getcwd not available #endif } inline char* os::getenv(const char* name) { #if defined(HAVE_GETENV) return ::getenv(name); #else # error getenv not available #endif } inline int os::gethostname(char* name, size_t len) { #if defined(HAVE_GETHOSTNAME) return ::gethostname(name, len); #else # error gethostname not available #endif } inline int os::getloadavg(double loadavg[], int nelem) { #if defined(HAVE_GETLOADAVG) return ::getloadavg(loadavg, nelem); #else # error getloadavg not available #endif } inline int os::getpagesize(void) { #if defined(HAVE_GETPAGESIZE) return ::getpagesize(); #else # error getpagesize not available #endif } inline pid_t os::getpid(void) { #if defined(HAVE_GETPID) return ::getpid(); #else # error getpid not available #endif } inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen) { #if defined(HAVE_GETSOCKNAME) return ::getsockname(s, name, namelen); #else # error getsockname not available #endif } inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen) { #if defined(HAVE_GETSOCKOPT) return ::getsockopt(s, level, optname, optval, optlen); #else # error getsockopt not available #endif } inline int os::listen(int sockfd, int backlog) { #if defined(HAVE_LISTEN) return ::listen(sockfd, backlog); #else # error listen not available #endif } inline static off_t system_lseek(int fildes, off_t offset, int whence) { #if defined(HAVE_LSEEK) return lseek(fildes, offset, whence); #else # error lseek not available #endif } inline void* os::malloc(size_t size) { #if defined(HAVE_MALLOC) return ::malloc(size); #else # error malloc not available #endif } inline void* os::memcpy(void* dest, const void* src, size_t n) { #if defined(HAVE_MEMCPY) return ::memcpy(dest, src, n); #else # error memcpy not available #endif } inline void* os::memset(void* s, int c, size_t n) { #if defined(HAVE_MEMSET) return ::memset(s, c, n); #else # error memset not available #endif } inline int os::mprotect(void* addr, size_t len, int prot) { #if defined(HAVE_MPROTECT) return ::mprotect(addr, len, prot); #else # error mprotect not available #endif } inline static int system_open(const char *pathname, int flags, mode_t mode) { #if defined(HAVE_OPEN) return open(pathname, flags, mode); #else # error open not available #endif } inline static ssize_t system_read(int fd, void *buf, size_t count) { #if defined(HAVE_READ) return read(fd, buf, count); #else # error read not available #endif } inline ssize_t os::readlink(const char* path, char* buf, size_t bufsiz) { #if defined(HAVE_READLINK) return ::readlink(path, buf, bufsiz); #else # error readlink not available #endif } inline static void *system_realloc(void *ptr, size_t size) { #if defined(HAVE_REALLOC) return realloc(ptr, size); #else # error realloc not available #endif } template inline int os::call_scandir(int (*scandir)(const char *, struct dirent ***, _F1, _F2), const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *)) { return scandir(dir, namelist, (_F1) filter, (_F2) compar); } inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *)) { #if defined(HAVE_SCANDIR) return call_scandir(::scandir, dir, namelist, filter, compar); #else # error scandir not available #endif } inline ssize_t os::send(int s, const void* buf, size_t len, int flags) { // TODO Should be restartable on Linux and interruptible on Solaris. #if defined(HAVE_SEND) return ::send(s, buf, len, flags); #else # error send not available #endif } inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen) { #if defined(HAVE_SETSOCKOPT) return ::setsockopt(s, level, optname, optval, optlen); #else # error setsockopt not available #endif } inline int os::shutdown(int s, int how) { #if defined(HAVE_SHUTDOWN) return ::shutdown(s, how); #else # error shutdown not available #endif } inline int os::socket(int domain, int type, int protocol) { #if defined(HAVE_SOCKET) return ::socket(domain, type, protocol); #else # error socket not available #endif } inline int os::stat(const char* path, struct stat* buf) { #if defined(HAVE_STAT) return ::stat(path, buf); #else # error stat not available #endif } #if defined(__SOLARIS__) inline int os::str2sig(const char* str, int* signum) { #if defined(HAVE_STR2SIG) return ::str2sig(str, signum); #else # error str2sig not available #endif } #endif inline char* os::strcat(char* dest, const char* src) { #if defined(HAVE_STRCAT) return ::strcat(dest, src); #else # error strcat not available #endif } inline int os::strcmp(const char* s1, const char* s2) { #if defined(HAVE_STRCMP) return ::strcmp(s1, s2); #else # error strcmp not available #endif } inline char* os::strcpy(char* dest, const char* src) { #if defined(HAVE_STRCPY) return ::strcpy(dest, src); #else # error strcpy not available #endif } inline char* os::strdup(const char* s) { #if defined(HAVE_STRDUP) return ::strdup(s); #else # error strdup not available #endif } inline char* os::strerror(int errnum) { #if defined(HAVE_STRERROR) return ::strerror(errnum); #else # error strerror not available #endif } inline size_t os::strlen(const char* s) { #if defined(HAVE_STRLEN) return ::strlen(s); #else # error strlen not available #endif } inline static ssize_t system_write(int fd, const void *buf, size_t count) { #if defined(HAVE_WRITE) return write(fd, buf, count); #else # error write not available #endif } #else void* os_mmap_anonymous(void *addr, size_t len, int prot, int flags); int os_atoi(const char* nptr); int os_getpagesize(void); void* os_memcpy(void* dest, const void* src, size_t n); void* os_memset(void* s, int c, size_t n); char* os_strdup(const char* s); int os_strlen(const char* s); #endif #endif // _OS_HPP /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: * mode: c++ * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 * End: * vim:noexpandtab:sw=4:ts=4: */