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