1 /* src/vm/os.hpp - system (OS) functions
3 Copyright (C) 2007, 2008, 2009, 2010, 2011
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 Copyright (C) 2008 Theobroma Systems Ltd.
7 This file is part of CACAO.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2, or (at
12 your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 // NOTE: In this file we check for all system headers, because we wrap
33 // all system calls into inline functions for better portability.
35 // Please don't include CACAO headers here as this header should be a
36 // very low-level one.
38 #if defined(HAVE_DIRENT_H)
42 #if defined(HAVE_DLFCN_H)
46 #if defined(HAVE_ERRNO_H)
50 #if defined(HAVE_EXECINFO_H)
51 # include <execinfo.h>
54 #if defined(HAVE_FCNTL_H)
58 #if defined(ENABLE_JRE_LAYOUT)
59 # if defined(HAVE_LIBGEN_H)
64 #if defined(HAVE_SIGNAL_H)
68 #if defined(HAVE_STDARG_H)
72 #if defined(HAVE_STDINT_H)
76 #if defined(HAVE_STDIO_H)
80 #if defined(HAVE_STDLIB_H)
84 #if defined(HAVE_STRING_H)
88 #if defined(HAVE_UNISTD_H)
92 #if defined(__DARWIN__)
93 # if defined(HAVE_MACH_MACH_H)
94 # include <mach/mach.h>
98 #if defined(HAVE_SYS_LOADAVG_H)
99 # include <sys/loadavg.h>
102 #if defined(HAVE_SYS_MMAN_H)
103 # include <sys/mman.h>
106 #if defined(HAVE_SYS_SOCKET_H)
107 # include <sys/socket.h>
110 #if defined(HAVE_SYS_STAT_H)
111 # include <sys/stat.h>
114 #if defined(HAVE_SYS_TYPES_H)
115 # include <sys/types.h>
118 #if defined(HAVE_SYS_UTSNAME_H)
119 # include <sys/utsname.h>
125 // Class wrapping system (OS) functions.
129 static inline void abort();
130 static inline int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
131 static inline int access(const char *pathname, int mode);
132 static inline int atoi(const char* nptr);
133 static inline int backtrace(void** array, int size);
134 static inline char** backtrace_symbols(void* const* array, int size) throw ();
135 static inline void* calloc(size_t nmemb, size_t size);
136 static inline int close(int fd);
137 static inline int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);
138 #if defined(ENABLE_JRE_LAYOUT)
139 static inline char* dirname(char* path);
141 static inline int dlclose(void* handle);
142 static inline char* dlerror(void);
143 static inline void* dlopen(const char* filename, int flag);
144 static inline void* dlsym(void* handle, const char* symbol);
145 static inline int fclose(FILE* fp);
146 static inline FILE* fopen(const char* path, const char* mode);
147 static inline int vfprintf ( FILE * stream, const char * format, va_list arg );
148 static inline size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
149 static inline void free(void* ptr);
150 static inline char* getcwd(char* buf, size_t size);
151 static inline char* getenv(const char* name);
152 static inline int gethostname(char* name, size_t len);
153 static inline int getloadavg(double loadavg[], int nelem);
154 static inline int getpagesize(void);
155 static inline pid_t getpid(void);
156 static inline int getsockname(int s, struct sockaddr* name, socklen_t* namelen);
157 static inline int getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
158 static inline int listen(int sockfd, int backlog);
159 static inline void* malloc(size_t size);
160 static inline void* memcpy(void* dest, const void* src, size_t n);
161 static inline void* memset(void* s, int c, size_t n);
162 static inline int mprotect(void* addr, size_t len, int prot);
163 static inline ssize_t readlink(const char* path, char* buf, size_t bufsiz);
164 static inline int scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
165 static inline ssize_t send(int s, const void* buf, size_t len, int flags);
166 static inline int setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen);
167 static inline int shutdown(int s, int how);
168 static inline int socket(int domain, int type, int protocol);
169 static inline int stat(const char* path, struct stat* buf);
170 #if defined(__SOLARIS__)
171 static inline int str2sig(const char* str, int* signum);
173 static inline char* strcat(char* dest, const char* src);
174 static inline int strcmp(const char* s1, const char* s2);
175 static inline char* strcpy(char* dest, const char* src);
176 static inline char* strdup(const char* s);
177 static inline size_t strlen(const char* s);
178 static inline char* strerror(int errnum);
180 // Convenience functions.
181 static void abort(const char* text, ...);
182 static void abort_errnum(int errnum, const char* text, ...);
183 static void abort_errno(const char* text, ...);
184 static char* getcwd(void);
185 static void* mmap_anonymous(void *addr, size_t len, int prot, int flags);
186 static void print_backtrace();
187 static int processors_online();
190 template<class _F1, class _F2>
191 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 *));
195 inline void os::abort(void)
197 #if defined(HAVE_ABORT)
200 # error abort not available
204 inline int os::accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
206 #if defined(HAVE_ACCEPT)
207 return ::accept(sockfd, addr, addrlen);
209 # error accept not available
213 inline int os::access(const char* pathname, int mode)
215 #if defined(HAVE_ACCESS)
216 return ::access(pathname, mode);
218 # error access not available
222 inline int os::atoi(const char* nptr)
224 #if defined(HAVE_ATOI)
227 # error atoi not available
231 inline int os::backtrace(void** array, int size)
233 #if defined(HAVE_BACKTRACE)
234 return ::backtrace(array, size);
236 fprintf(stderr, "os::backtrace: Not available.");
241 inline char** os::backtrace_symbols(void* const* array, int size) throw ()
243 #if defined(HAVE_BACKTRACE_SYMBOLS)
244 return ::backtrace_symbols(array, size);
246 fprintf(stderr, "os::backtrace_symbols: Not available.");
251 inline void* os::calloc(size_t nmemb, size_t size)
253 #if defined(HAVE_CALLOC)
254 return ::calloc(nmemb, size);
256 # error calloc not available
260 inline int os::close(int fd)
262 #if defined(HAVE_CLOSE)
265 # error close not available
269 inline int os::connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen)
271 #if defined(HAVE_CONNECT)
272 return ::connect(sockfd, serv_addr, addrlen);
274 # error connect not available
278 #if defined(ENABLE_JRE_LAYOUT)
279 inline char* os::dirname(char* path)
281 #if defined(HAVE_DIRNAME)
282 return ::dirname(path);
284 # error dirname not available
289 inline int os::dlclose(void* handle)
291 #if defined(HAVE_DLCLOSE)
292 return ::dlclose(handle);
294 # error dlclose not available
298 inline char* os::dlerror(void)
300 #if defined(HAVE_DLERROR)
301 // At least FreeBSD defines dlerror() to return a const char*, so
302 // we simply cast it.
303 return (char*) ::dlerror();
305 # error dlerror not available
309 inline void* os::dlopen(const char* filename, int flag)
311 #if defined(HAVE_DLOPEN)
312 return ::dlopen(filename, flag);
314 # error dlopen not available
318 inline void* os::dlsym(void* handle, const char* symbol)
320 #if defined(HAVE_DLSYM)
321 return ::dlsym(handle, symbol);
323 # error dlsym not available
327 inline int os::fclose(FILE* fp)
329 #if defined(HAVE_FCLOSE)
332 # error fclose not available
336 inline FILE* os::fopen(const char* path, const char* mode)
338 #if defined(HAVE_FOPEN)
339 return ::fopen(path, mode);
341 # error fopen not available
345 //fprintf is mandatory and can't be replaced with an equivalent fast wrapper
346 #if !defined (HAVE_FPRINTF)
347 #error fprintf not available
350 inline int os::vfprintf ( FILE * stream, const char * format, va_list arg )
352 #if defined(HAVE_VFPRINTF)
353 int result = ::vfprintf(stream, format, arg);
356 # error vfprintf not available
360 inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
362 #if defined(HAVE_FREAD)
363 return ::fread(ptr, size, nmemb, stream);
365 # error fread not available
369 inline void os::free(void* ptr)
371 #if defined(HAVE_FREE)
374 # error free not available
378 inline static int system_fsync(int fd)
380 #if defined(HAVE_FSYNC)
383 # error fsync not available
387 inline static int system_ftruncate(int fd, off_t length)
389 #if defined(HAVE_FTRUNCATE)
390 return ftruncate(fd, length);
392 # error ftruncate not available
396 inline char* os::getcwd(char* buf, size_t size)
398 #if defined(HAVE_GETCWD)
399 return ::getcwd(buf, size);
401 # error getcwd not available
405 inline char* os::getenv(const char* name)
407 #if defined(HAVE_GETENV)
408 return ::getenv(name);
410 # error getenv not available
414 inline int os::gethostname(char* name, size_t len)
416 #if defined(HAVE_GETHOSTNAME)
417 return ::gethostname(name, len);
419 # error gethostname not available
423 inline int os::getloadavg(double loadavg[], int nelem)
425 #if defined(HAVE_GETLOADAVG)
426 return ::getloadavg(loadavg, nelem);
428 # error getloadavg not available
432 inline int os::getpagesize(void)
434 #if defined(HAVE_GETPAGESIZE)
435 return ::getpagesize();
437 # error getpagesize not available
441 inline pid_t os::getpid(void)
443 #if defined(HAVE_GETPID)
446 # error getpid not available
450 inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen)
452 #if defined(HAVE_GETSOCKNAME)
453 return ::getsockname(s, name, namelen);
455 # error getsockname not available
459 inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
461 #if defined(HAVE_GETSOCKOPT)
462 return ::getsockopt(s, level, optname, optval, optlen);
464 # error getsockopt not available
468 inline int os::listen(int sockfd, int backlog)
470 #if defined(HAVE_LISTEN)
471 return ::listen(sockfd, backlog);
473 # error listen not available
477 inline static off_t system_lseek(int fildes, off_t offset, int whence)
479 #if defined(HAVE_LSEEK)
480 return lseek(fildes, offset, whence);
482 # error lseek not available
486 inline void* os::malloc(size_t size)
488 #if defined(HAVE_MALLOC)
489 return ::malloc(size);
491 # error malloc not available
495 inline void* os::memcpy(void* dest, const void* src, size_t n)
497 #if defined(HAVE_MEMCPY)
498 return ::memcpy(dest, src, n);
500 # error memcpy not available
504 inline void* os::memset(void* s, int c, size_t n)
506 #if defined(HAVE_MEMSET)
507 return ::memset(s, c, n);
509 # error memset not available
513 inline int os::mprotect(void* addr, size_t len, int prot)
515 #if defined(HAVE_MPROTECT)
516 return ::mprotect(addr, len, prot);
518 # error mprotect not available
522 inline static int system_open(const char *pathname, int flags, mode_t mode)
524 #if defined(HAVE_OPEN)
525 return open(pathname, flags, mode);
527 # error open not available
531 inline static ssize_t system_read(int fd, void *buf, size_t count)
533 #if defined(HAVE_READ)
534 return read(fd, buf, count);
536 # error read not available
540 inline ssize_t os::readlink(const char* path, char* buf, size_t bufsiz)
542 #if defined(HAVE_READLINK)
543 return ::readlink(path, buf, bufsiz);
545 # error readlink not available
549 inline static void *system_realloc(void *ptr, size_t size)
551 #if defined(HAVE_REALLOC)
552 return realloc(ptr, size);
554 # error realloc not available
558 template<class _F1, class _F2>
559 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 *))
561 return scandir(dir, namelist, (_F1) filter, (_F2) compar);
564 inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
566 #if defined(HAVE_SCANDIR)
567 return call_scandir(::scandir, dir, namelist, filter, compar);
569 # error scandir not available
573 inline ssize_t os::send(int s, const void* buf, size_t len, int flags)
575 // TODO Should be restartable on Linux and interruptible on Solaris.
576 #if defined(HAVE_SEND)
577 return ::send(s, buf, len, flags);
579 # error send not available
583 inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
585 #if defined(HAVE_SETSOCKOPT)
586 return ::setsockopt(s, level, optname, optval, optlen);
588 # error setsockopt not available
592 inline int os::shutdown(int s, int how)
594 #if defined(HAVE_SHUTDOWN)
595 return ::shutdown(s, how);
597 # error shutdown not available
601 inline int os::socket(int domain, int type, int protocol)
603 #if defined(HAVE_SOCKET)
604 return ::socket(domain, type, protocol);
606 # error socket not available
610 inline int os::stat(const char* path, struct stat* buf)
612 #if defined(HAVE_STAT)
613 return ::stat(path, buf);
615 # error stat not available
619 #if defined(__SOLARIS__)
620 inline int os::str2sig(const char* str, int* signum)
622 #if defined(HAVE_STR2SIG)
623 return ::str2sig(str, signum);
625 # error str2sig not available
630 inline char* os::strcat(char* dest, const char* src)
632 #if defined(HAVE_STRCAT)
633 return ::strcat(dest, src);
635 # error strcat not available
639 inline int os::strcmp(const char* s1, const char* s2)
641 #if defined(HAVE_STRCMP)
642 return ::strcmp(s1, s2);
644 # error strcmp not available
648 inline char* os::strcpy(char* dest, const char* src)
650 #if defined(HAVE_STRCPY)
651 return ::strcpy(dest, src);
653 # error strcpy not available
657 inline char* os::strdup(const char* s)
659 #if defined(HAVE_STRDUP)
662 # error strdup not available
666 inline char* os::strerror(int errnum)
668 #if defined(HAVE_STRERROR)
669 return ::strerror(errnum);
671 # error strerror not available
675 inline size_t os::strlen(const char* s)
677 #if defined(HAVE_STRLEN)
680 # error strlen not available
684 inline static ssize_t system_write(int fd, const void *buf, size_t count)
686 #if defined(HAVE_WRITE)
687 return write(fd, buf, count);
689 # error write not available
695 void* os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
697 int os_atoi(const char* nptr);
698 int os_getpagesize(void);
699 void* os_memcpy(void* dest, const void* src, size_t n);
700 void* os_memset(void* s, int c, size_t n);
701 char* os_strdup(const char* s);
702 int os_strlen(const char* s);
710 * These are local overrides for various environment variables in Emacs.
711 * Please do not remove this and leave it at the end of the file, where
712 * Emacs will automagically detect them.
713 * ---------------------------------------------------------------------
716 * indent-tabs-mode: t
720 * vim:noexpandtab:sw=4:ts=4: