/* src/vm/os.hpp - system (OS) functions
- Copyright (C) 2007, 2008
+ Copyright (C) 2007, 2008, 2009, 2010
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+ Copyright (C) 2008 Theobroma Systems Ltd.
This file is part of CACAO.
#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. */
+// 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 <dirent.h>
# include <errno.h>
#endif
+#if defined(HAVE_EXECINFO_H)
+# include <execinfo.h>
+#endif
+
#if defined(HAVE_FCNTL_H)
# include <fcntl.h>
#endif
# include <signal.h>
#endif
+#if defined(HAVE_STDARG_H)
+# include <stdarg.h>
+#endif
+
#if defined(HAVE_STDINT_H)
# include <stdint.h>
#endif
# include <unistd.h>
#endif
+#if defined(__DARWIN__)
+# if defined(HAVE_MACH_MACH_H)
+# include <mach/mach.h>
+# endif
+#endif
+
+#if defined(HAVE_SYS_LOADAVG_H)
+# include <sys/loadavg.h>
+#endif
+
#if defined(HAVE_SYS_MMAN_H)
# include <sys/mman.h>
#endif
# include <sys/types.h>
#endif
+#if defined(HAVE_SYS_UTSNAME_H)
+# include <sys/utsname.h>
+#endif
+
#ifdef __cplusplus
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 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);
+ 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 size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
- static inline void free(void* ptr);
- static inline int gethostname(char* name, size_t len);
- static inline int getpagesize(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 int scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
- 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);
- static inline int str2sig(const char* str, int* signum);
- static inline char* strcat(char* dest, const char* src);
- 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);
-
+ 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 fprintf(FILE* stream, const char* format, ...);
+ 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 int processors_online(void);
+ static void print_backtrace();
+ static int processors_online();
+
+ // Template helper
+ template<class _F1, class _F2>
+ 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 *));
};
#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)
inline char* os::dlerror(void)
{
#if defined(HAVE_DLERROR)
- return ::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
#endif
}
+inline int os::fprintf(FILE* stream, const char* format, ...)
+{
+#if defined(HAVE_FPRINTF)
+ va_list ap;
+ va_start(ap, format);
+ int result = ::vfprintf(stream, format, ap);
+ va_end(ap);
+ return result;
+#else
+# error fprintf not available
+#endif
+}
+
inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
{
#if defined(HAVE_FREAD)
#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)
#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)
#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)
#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)
#endif
}
+template<class _F1, class _F2>
+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 *))
-/*
-#elif defined(__SOLARIS__)
-inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const struct dirent **, const struct dirent **))
-#elif defined(__IRIX__)
-inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(dirent_t *), int(*compar)(dirent_t **, dirent_t **))
-#else
-inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(struct dirent *), int(*compar)(const void *, const void *))
-#endif
-*/
{
#if defined(HAVE_SCANDIR)
-# if defined(__LINUX__)
- return ::scandir(dir, namelist, filter, compar);
-#elif defined(__SOLARIS__)
- return ::scandir(dir, namelist, filter, (int (*)(const dirent**, const dirent**)) compar);
-# else
- return ::scandir(dir, namelist, (int (*)(struct dirent*)) filter, compar);
-# endif
+ 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)
#endif
}
+#if defined(__SOLARIS__)
inline int os::str2sig(const char* str, int* signum)
{
#if defined(HAVE_STR2SIG)
# error str2sig not available
#endif
}
+#endif
inline char* os::strcat(char* dest, const char* src)
{
#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)
void* os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
-void os_abort(void);
-int os_access(const char* pathname, int mode);
int os_atoi(const char* nptr);
-void* os_calloc(size_t nmemb, size_t size);
-char* os_dirname(char* path);
-int os_dlclose(void* handle);
-char* os_dlerror(void);
-void* os_dlopen(const char* filename, int flag);
-void* os_dlsym(void* handle, const char* symbol);
-int os_fclose(FILE* fp);
-FILE* os_fopen(const char* path, const char* mode);
-size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
-void os_free(void* ptr);
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);
-int os_mprotect(void* addr, size_t len, int prot);
-int os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
-int os_stat(const char* path, struct stat* buf);
-char* os_strcat(char* dest, const char* src);
-char* os_strcpy(char* dest, const char* src);
char* os_strdup(const char* s);
int os_strlen(const char* s);