* configure.ac: Added check for sys/loadavg.h (for OpenSolaris).
[cacao.git] / src / vm / os.hpp
1 /* src/vm/os.hpp - system (OS) functions
2
3    Copyright (C) 2007, 2008, 2009
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5    Copyright (C) 2008 Theobroma Systems Ltd.
6
7    This file is part of CACAO.
8
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.
13
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.
18
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
22    02110-1301, USA.
23
24 */
25
26
27 #ifndef _OS_HPP
28 #define _OS_HPP
29
30 #include "config.h"
31
32 // NOTE: In this file we check for all system headers, because we wrap
33 // all system calls into inline functions for better portability.
34
35 // Please don't include CACAO headers here as this header should be a
36 // very low-level one.
37
38 #if defined(HAVE_DIRENT_H)
39 # include <dirent.h>
40 #endif
41
42 #if defined(HAVE_DLFCN_H)
43 # include <dlfcn.h>
44 #endif
45
46 #if defined(HAVE_ERRNO_H)
47 # include <errno.h>
48 #endif
49
50 #if defined(HAVE_EXECINFO_H)
51 # include <execinfo.h>
52 #endif
53
54 #if defined(HAVE_FCNTL_H)
55 # include <fcntl.h>
56 #endif
57
58 #if defined(ENABLE_JRE_LAYOUT)
59 # if defined(HAVE_LIBGEN_H)
60 #  include <libgen.h>
61 # endif
62 #endif
63
64 #if defined(HAVE_SIGNAL_H)
65 # include <signal.h>
66 #endif
67
68 #if defined(HAVE_STDARG_H)
69 # include <stdarg.h>
70 #endif
71
72 #if defined(HAVE_STDINT_H)
73 # include <stdint.h>
74 #endif
75
76 #if defined(HAVE_STDIO_H)
77 # include <stdio.h>
78 #endif
79
80 #if defined(HAVE_STDLIB_H)
81 # include <stdlib.h>
82 #endif
83
84 #if defined(HAVE_STRING_H)
85 # include <string.h>
86 #endif
87
88 #if defined(HAVE_UNISTD_H)
89 # include <unistd.h>
90 #endif
91
92 #if defined(HAVE_SYS_LOADAVG_H)
93 # include <sys/loadavg.h>
94 #endif
95
96 #if defined(HAVE_SYS_MMAN_H)
97 # include <sys/mman.h>
98 #endif
99
100 #if defined(HAVE_SYS_SOCKET_H)
101 # include <sys/socket.h>
102 #endif
103
104 #if defined(HAVE_SYS_STAT_H)
105 # include <sys/stat.h>
106 #endif
107
108 #if defined(HAVE_SYS_TYPES_H)
109 # include <sys/types.h>
110 #endif
111
112
113 #ifdef __cplusplus
114
115 // Class wrapping system (OS) functions.
116 class os {
117 public:
118         // Inline functions.
119         static inline void    abort();
120         static inline int     accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
121         static inline int     access(const char *pathname, int mode);
122         static inline int     atoi(const char* nptr);
123         static inline int     backtrace(void** array, int size);
124         static inline char**  backtrace_symbols(void* const* array, int size) throw ();
125         static inline void*   calloc(size_t nmemb, size_t size);
126         static inline int     close(int fd);
127         static inline int     connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen);
128 #if defined(ENABLE_JRE_LAYOUT)
129         static inline char*   dirname(char* path);
130 #endif
131         static inline int     dlclose(void* handle);
132         static inline char*   dlerror(void);
133         static inline void*   dlopen(const char* filename, int flag);
134         static inline void*   dlsym(void* handle, const char* symbol);
135         static inline int     fclose(FILE* fp);
136         static inline FILE*   fopen(const char* path, const char* mode);
137         static inline int     fprintf(FILE* stream, const char* format, ...);
138         static inline size_t  fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
139         static inline void    free(void* ptr);
140         static inline char*   getenv(const char* name);
141         static inline int     gethostname(char* name, size_t len);
142         static inline int     getloadavg(double loadavg[], int nelem);
143         static inline int     getpagesize(void);
144         static inline int     getsockname(int s, struct sockaddr* name, socklen_t* namelen);
145         static inline int     getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
146         static inline int     listen(int sockfd, int backlog);
147         static inline void*   malloc(size_t size);
148         static inline void*   memcpy(void* dest, const void* src, size_t n);
149         static inline void*   memset(void* s, int c, size_t n);
150         static inline int     mprotect(void* addr, size_t len, int prot);
151         static inline ssize_t readlink(const char* path, char* buf, size_t bufsiz);
152         static inline int     scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
153         static inline ssize_t send(int s, const void* buf, size_t len, int flags);
154         static inline int     setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen);
155         static inline int     shutdown(int s, int how);
156         static inline int     socket(int domain, int type, int protocol);
157         static inline int     stat(const char* path, struct stat* buf);
158 #if defined(__SOLARIS__)
159         static inline int     str2sig(const char* str, int* signum);
160 #endif
161         static inline char*   strcat(char* dest, const char* src);
162         static inline int     strcmp(const char* s1, const char* s2);
163         static inline char*   strcpy(char* dest, const char* src);
164         static inline char*   strdup(const char* s);
165         static inline size_t  strlen(const char* s);
166         static inline char*   strerror(int errnum);
167
168         // Convenience functions.
169         static void  abort(const char* text, ...);
170         static void  abort_errnum(int errnum, const char* text, ...);
171         static void  abort_errno(const char* text, ...);
172         static void* mmap_anonymous(void *addr, size_t len, int prot, int flags);
173         static void  print_backtrace();
174         static int   processors_online();
175
176         // Template helper
177         template<class F1, class F2>
178         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 *));
179 };
180
181
182 inline void os::abort(void)
183 {
184 #if defined(HAVE_ABORT)
185         ::abort();
186 #else
187 # error abort not available
188 #endif
189 }
190
191 inline int os::accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
192 {
193 #if defined(HAVE_ACCEPT)
194         return ::accept(sockfd, addr, addrlen);
195 #else
196 # error accept not available
197 #endif
198 }
199
200 inline int os::access(const char* pathname, int mode)
201 {
202 #if defined(HAVE_ACCESS)
203         return ::access(pathname, mode);
204 #else
205 # error access not available
206 #endif
207 }
208
209 inline int os::atoi(const char* nptr)
210 {
211 #if defined(HAVE_ATOI)
212         return ::atoi(nptr);
213 #else
214 # error atoi not available
215 #endif
216 }
217
218 inline int os::backtrace(void** array, int size)
219 {
220 #if defined(HAVE_BACKTRACE)
221         return ::backtrace(array, size);
222 #else
223         fprintf(stderr, "os::backtrace: Not available.");
224         return 0;
225 #endif
226 }
227
228 inline char** os::backtrace_symbols(void* const* array, int size) throw ()
229 {
230 #if defined(HAVE_BACKTRACE_SYMBOLS)
231         return ::backtrace_symbols(array, size);
232 #else
233         fprintf(stderr, "os::backtrace_symbols: Not available.");
234         return NULL;
235 #endif
236 }
237
238 inline void* os::calloc(size_t nmemb, size_t size)
239 {
240 #if defined(HAVE_CALLOC)
241         return ::calloc(nmemb, size);
242 #else
243 # error calloc not available
244 #endif
245 }
246
247 inline int os::close(int fd)
248 {
249 #if defined(HAVE_CLOSE)
250         return ::close(fd);
251 #else
252 # error close not available
253 #endif
254 }
255
256 inline int os::connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen)
257 {
258 #if defined(HAVE_CONNECT)
259         return ::connect(sockfd, serv_addr, addrlen);
260 #else
261 # error connect not available
262 #endif
263 }
264
265 #if defined(ENABLE_JRE_LAYOUT)
266 inline char* os::dirname(char* path)
267 {
268 #if defined(HAVE_DIRNAME)
269         return ::dirname(path);
270 #else
271 # error dirname not available
272 #endif
273 }
274 #endif
275
276 inline int os::dlclose(void* handle)
277 {
278 #if defined(HAVE_DLCLOSE)
279         return ::dlclose(handle);
280 #else
281 # error dlclose not available
282 #endif
283 }
284
285 inline char* os::dlerror(void)
286 {
287 #if defined(HAVE_DLERROR)
288         // At least FreeBSD defines dlerror() to return a const char*, so
289         // we simply cast it.
290         return (char*) ::dlerror();
291 #else
292 # error dlerror not available
293 #endif
294 }
295
296 inline void* os::dlopen(const char* filename, int flag)
297 {
298 #if defined(HAVE_DLOPEN)
299         return ::dlopen(filename, flag);
300 #else
301 # error dlopen not available
302 #endif
303 }
304
305 inline void* os::dlsym(void* handle, const char* symbol)
306 {
307 #if defined(HAVE_DLSYM)
308         return ::dlsym(handle, symbol);
309 #else
310 # error dlsym not available
311 #endif
312 }
313
314 inline int os::fclose(FILE* fp)
315 {
316 #if defined(HAVE_FCLOSE)
317         return ::fclose(fp);
318 #else
319 # error fclose not available
320 #endif
321 }
322
323 inline FILE* os::fopen(const char* path, const char* mode)
324 {
325 #if defined(HAVE_FOPEN)
326         return ::fopen(path, mode);
327 #else
328 # error fopen not available
329 #endif
330 }
331
332 inline int os::fprintf(FILE* stream, const char* format, ...)
333 {
334 #if defined(HAVE_FPRINTF)
335         va_list ap;
336         va_start(ap, format);
337         int result = ::vfprintf(stream, format, ap);
338         va_end(ap);
339         return result;
340 #else
341 # error fprintf not available
342 #endif
343 }
344
345 inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
346 {
347 #if defined(HAVE_FREAD)
348         return ::fread(ptr, size, nmemb, stream);
349 #else
350 # error fread not available
351 #endif
352 }
353
354 inline void os::free(void* ptr)
355 {
356 #if defined(HAVE_FREE)
357         ::free(ptr);
358 #else
359 # error free not available
360 #endif
361 }
362
363 inline static int system_fsync(int fd)
364 {
365 #if defined(HAVE_FSYNC)
366         return fsync(fd);
367 #else
368 # error fsync not available
369 #endif
370 }
371
372 inline static int system_ftruncate(int fd, off_t length)
373 {
374 #if defined(HAVE_FTRUNCATE)
375         return ftruncate(fd, length);
376 #else
377 # error ftruncate not available
378 #endif
379 }
380
381 inline char* os::getenv(const char* name)
382 {
383 #if defined(HAVE_GETENV)
384         return ::getenv(name);
385 #else
386 # error getenv not available
387 #endif
388 }
389
390 inline int os::gethostname(char* name, size_t len)
391 {
392 #if defined(HAVE_GETHOSTNAME)
393         return ::gethostname(name, len);
394 #else
395 # error gethostname not available
396 #endif
397 }
398
399 inline int os::getloadavg(double loadavg[], int nelem)
400 {
401 #if defined(HAVE_GETLOADAVG)
402         return ::getloadavg(loadavg, nelem);
403 #else
404 # error getloadavg not available
405 #endif
406 }
407
408 inline int os::getpagesize(void)
409 {
410 #if defined(HAVE_GETPAGESIZE)
411         return ::getpagesize();
412 #else
413 # error getpagesize not available
414 #endif
415 }
416
417 inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen)
418 {
419 #if defined(HAVE_GETSOCKNAME)
420         return ::getsockname(s, name, namelen);
421 #else
422 # error getsockname not available
423 #endif
424 }
425
426 inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
427 {
428 #if defined(HAVE_GETSOCKOPT)
429         return ::getsockopt(s, level, optname, optval, optlen);
430 #else
431 # error getsockopt not available
432 #endif
433 }
434
435 inline int os::listen(int sockfd, int backlog)
436 {
437 #if defined(HAVE_LISTEN)
438         return ::listen(sockfd, backlog);
439 #else
440 # error listen not available
441 #endif
442 }
443
444 inline static off_t system_lseek(int fildes, off_t offset, int whence)
445 {
446 #if defined(HAVE_LSEEK)
447         return lseek(fildes, offset, whence);
448 #else
449 # error lseek not available
450 #endif
451 }
452
453 inline void* os::malloc(size_t size)
454 {
455 #if defined(HAVE_MALLOC)
456         return ::malloc(size);
457 #else
458 # error malloc not available
459 #endif
460 }
461
462 inline void* os::memcpy(void* dest, const void* src, size_t n)
463 {
464 #if defined(HAVE_MEMCPY)
465         return ::memcpy(dest, src, n);
466 #else
467 # error memcpy not available
468 #endif
469 }
470
471 inline void* os::memset(void* s, int c, size_t n)
472 {
473 #if defined(HAVE_MEMSET)
474         return ::memset(s, c, n);
475 #else
476 # error memset not available
477 #endif
478 }
479
480 inline int os::mprotect(void* addr, size_t len, int prot)
481 {
482 #if defined(HAVE_MPROTECT)
483         return ::mprotect(addr, len, prot);
484 #else
485 # error mprotect not available
486 #endif
487 }
488
489 inline static int system_open(const char *pathname, int flags, mode_t mode)
490 {
491 #if defined(HAVE_OPEN)
492         return open(pathname, flags, mode);
493 #else
494 # error open not available
495 #endif
496 }
497
498 inline static ssize_t system_read(int fd, void *buf, size_t count)
499 {
500 #if defined(HAVE_READ)
501         return read(fd, buf, count);
502 #else
503 # error read not available
504 #endif
505 }
506
507 inline ssize_t os::readlink(const char* path, char* buf, size_t bufsiz)
508 {
509 #if defined(HAVE_READLINK)
510         return ::readlink(path, buf, bufsiz);
511 #else
512 # error readlink not available
513 #endif
514 }
515
516 inline static void *system_realloc(void *ptr, size_t size)
517 {
518 #if defined(HAVE_REALLOC)
519         return realloc(ptr, size);
520 #else
521 # error realloc not available
522 #endif
523 }
524
525 template<class F1, class F2>
526 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 *))
527 {
528         return scandir(dir, namelist, (F1) filter, (F2) compar);
529 }
530
531 inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
532 {
533 #if defined(HAVE_SCANDIR)
534         return call_scandir(::scandir, dir, namelist, filter, compar);
535 #else
536 # error scandir not available
537 #endif
538 }
539
540 inline ssize_t os::send(int s, const void* buf, size_t len, int flags)
541 {
542         // TODO Should be restartable on Linux and interruptible on Solaris.
543 #if defined(HAVE_SEND)
544         return ::send(s, buf, len, flags);
545 #else
546 # error send not available
547 #endif
548 }
549
550 inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
551 {
552 #if defined(HAVE_SETSOCKOPT)
553         return ::setsockopt(s, level, optname, optval, optlen);
554 #else
555 # error setsockopt not available
556 #endif
557 }
558
559 inline int os::shutdown(int s, int how)
560 {
561 #if defined(HAVE_SHUTDOWN)
562         return ::shutdown(s, how);
563 #else
564 # error shutdown not available
565 #endif
566 }
567
568 inline int os::socket(int domain, int type, int protocol)
569 {
570 #if defined(HAVE_SOCKET)
571         return ::socket(domain, type, protocol);
572 #else
573 # error socket not available
574 #endif
575 }
576
577 inline int os::stat(const char* path, struct stat* buf)
578 {
579 #if defined(HAVE_STAT)
580         return ::stat(path, buf);
581 #else
582 # error stat not available
583 #endif
584 }
585
586 #if defined(__SOLARIS__)
587 inline int os::str2sig(const char* str, int* signum)
588 {
589 #if defined(HAVE_STR2SIG)
590         return ::str2sig(str, signum);
591 #else
592 # error str2sig not available
593 #endif
594 }
595 #endif
596
597 inline char* os::strcat(char* dest, const char* src)
598 {
599 #if defined(HAVE_STRCAT)
600         return ::strcat(dest, src);
601 #else
602 # error strcat not available
603 #endif
604 }
605
606 inline int os::strcmp(const char* s1, const char* s2)
607 {
608 #if defined(HAVE_STRCMP)
609         return ::strcmp(s1, s2);
610 #else
611 # error strcmp not available
612 #endif
613 }
614
615 inline char* os::strcpy(char* dest, const char* src)
616 {
617 #if defined(HAVE_STRCPY)
618         return ::strcpy(dest, src);
619 #else
620 # error strcpy not available
621 #endif
622 }
623
624 inline char* os::strdup(const char* s)
625 {
626 #if defined(HAVE_STRDUP)
627         return ::strdup(s);
628 #else
629 # error strdup not available
630 #endif
631 }
632
633 inline char* os::strerror(int errnum)
634 {
635 #if defined(HAVE_STRERROR)
636         return ::strerror(errnum);
637 #else
638 # error strerror not available
639 #endif
640 }
641
642 inline size_t os::strlen(const char* s)
643 {
644 #if defined(HAVE_STRLEN)
645         return ::strlen(s);
646 #else
647 # error strlen not available
648 #endif
649 }
650
651 inline static ssize_t system_write(int fd, const void *buf, size_t count)
652 {
653 #if defined(HAVE_WRITE)
654         return write(fd, buf, count);
655 #else
656 # error write not available
657 #endif
658 }
659
660 #else
661
662 void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
663
664 void   os_abort(void);
665 int    os_access(const char* pathname, int mode);
666 int    os_atoi(const char* nptr);
667 void*  os_calloc(size_t nmemb, size_t size);
668 char*  os_dirname(char* path);
669 char*  os_dlerror(void);
670 void*  os_dlsym(void* handle, const char* symbol);
671 int    os_fclose(FILE* fp);
672 FILE*  os_fopen(const char* path, const char* mode);
673 size_t os_fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
674 void   os_free(void* ptr);
675 int    os_getpagesize(void);
676 void*  os_memcpy(void* dest, const void* src, size_t n);
677 void*  os_memset(void* s, int c, size_t n);
678 int    os_mprotect(void* addr, size_t len, int prot);
679 int    os_scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
680 int    os_stat(const char* path, struct stat* buf);
681 char*  os_strcat(char* dest, const char* src);
682 char*  os_strcpy(char* dest, const char* src);
683 char*  os_strdup(const char* s);
684 int    os_strlen(const char* s);
685
686 #endif
687
688 #endif // _OS_HPP
689
690
691 /*
692  * These are local overrides for various environment variables in Emacs.
693  * Please do not remove this and leave it at the end of the file, where
694  * Emacs will automagically detect them.
695  * ---------------------------------------------------------------------
696  * Local variables:
697  * mode: c++
698  * indent-tabs-mode: t
699  * c-basic-offset: 4
700  * tab-width: 4
701  * End:
702  * vim:noexpandtab:sw=4:ts=4:
703  */