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