Fix typo.
[cacao.git] / src / vm / os.hpp
index af24817284543eb8f2971e1bf12ff1dbac9bac11..1f924680d4aefa6917e4f69f2f59f21dc3a0b471 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/os.hpp - system (OS) functions
 
-   Copyright (C) 2007, 2008
+   Copyright (C) 2007, 2008, 2009, 2010, 2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2008 Theobroma Systems Ltd.
 
 
 #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 <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 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);
+       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 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);
+       static inline int     str2sig(const char* str, int* signum);
 #endif
-       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*   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();
-};
-
 
-// Includes.
-#include "toolbox/logging.h"
+       // 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 *));
+};
 
 
 inline void os::abort(void)
@@ -200,7 +233,7 @@ inline int os::backtrace(void** array, int size)
 #if defined(HAVE_BACKTRACE)
        return ::backtrace(array, size);
 #else
-       log_println("os::backtrace: Not available.");
+       fprintf(stderr, "os::backtrace: Not available.");
        return 0;
 #endif
 }
@@ -210,7 +243,7 @@ inline char** os::backtrace_symbols(void* const* array, int size) throw ()
 #if defined(HAVE_BACKTRACE_SYMBOLS)
        return ::backtrace_symbols(array, size);
 #else
-       log_println("os::backtrace_symbols: Not available.");
+       fprintf(stderr, "os::backtrace_symbols: Not available.");
        return NULL;
 #endif
 }
@@ -265,7 +298,9 @@ inline int os::dlclose(void* handle)
 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
@@ -307,6 +342,21 @@ inline FILE* os::fopen(const char* path, const char* mode)
 #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)
@@ -343,6 +393,24 @@ inline static int system_ftruncate(int fd, off_t length)
 #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)
@@ -352,6 +420,15 @@ inline int os::gethostname(char* name, size_t len)
 #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)
@@ -361,6 +438,15 @@ inline int os::getpagesize(void)
 #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)
@@ -451,6 +537,15 @@ inline static ssize_t system_read(int fd, void *buf, size_t count)
 #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)
@@ -460,30 +555,31 @@ inline static void *system_realloc(void *ptr, size_t size)
 #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)
@@ -540,6 +636,15 @@ 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)
@@ -589,27 +694,10 @@ inline static ssize_t system_write(int fd, const void *buf, size_t count)
 
 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);