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