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