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