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