* src/vm/os.hpp (call_scandir): Rename template arguments because of a
[cacao.git] / src / vm / os.hpp
1 /* src/vm/os.hpp - system (OS) functions
2
3    Copyright (C) 2007, 2008, 2009, 2010
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     fprintf(FILE* stream, const char* format, ...);
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 inline int os::fprintf(FILE* stream, const char* format, ...)
346 {
347 #if defined(HAVE_FPRINTF)
348         va_list ap;
349         va_start(ap, format);
350         int result = ::vfprintf(stream, format, ap);
351         va_end(ap);
352         return result;
353 #else
354 # error fprintf not available
355 #endif
356 }
357
358 inline size_t os::fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
359 {
360 #if defined(HAVE_FREAD)
361         return ::fread(ptr, size, nmemb, stream);
362 #else
363 # error fread not available
364 #endif
365 }
366
367 inline void os::free(void* ptr)
368 {
369 #if defined(HAVE_FREE)
370         ::free(ptr);
371 #else
372 # error free not available
373 #endif
374 }
375
376 inline static int system_fsync(int fd)
377 {
378 #if defined(HAVE_FSYNC)
379         return fsync(fd);
380 #else
381 # error fsync not available
382 #endif
383 }
384
385 inline static int system_ftruncate(int fd, off_t length)
386 {
387 #if defined(HAVE_FTRUNCATE)
388         return ftruncate(fd, length);
389 #else
390 # error ftruncate not available
391 #endif
392 }
393
394 inline char* os::getcwd(char* buf, size_t size)
395 {
396 #if defined(HAVE_GETCWD)
397         return ::getcwd(buf, size);
398 #else
399 # error getcwd not available
400 #endif
401 }
402
403 inline char* os::getenv(const char* name)
404 {
405 #if defined(HAVE_GETENV)
406         return ::getenv(name);
407 #else
408 # error getenv not available
409 #endif
410 }
411
412 inline int os::gethostname(char* name, size_t len)
413 {
414 #if defined(HAVE_GETHOSTNAME)
415         return ::gethostname(name, len);
416 #else
417 # error gethostname not available
418 #endif
419 }
420
421 inline int os::getloadavg(double loadavg[], int nelem)
422 {
423 #if defined(HAVE_GETLOADAVG)
424         return ::getloadavg(loadavg, nelem);
425 #else
426 # error getloadavg not available
427 #endif
428 }
429
430 inline int os::getpagesize(void)
431 {
432 #if defined(HAVE_GETPAGESIZE)
433         return ::getpagesize();
434 #else
435 # error getpagesize not available
436 #endif
437 }
438
439 inline pid_t os::getpid(void)
440 {
441 #if defined(HAVE_GETPID)
442         return ::getpid();
443 #else
444 # error getpid not available
445 #endif
446 }
447
448 inline int os::getsockname(int s, struct sockaddr* name, socklen_t* namelen)
449 {
450 #if defined(HAVE_GETSOCKNAME)
451         return ::getsockname(s, name, namelen);
452 #else
453 # error getsockname not available
454 #endif
455 }
456
457 inline int os::getsockopt(int s, int level, int optname, void* optval, socklen_t* optlen)
458 {
459 #if defined(HAVE_GETSOCKOPT)
460         return ::getsockopt(s, level, optname, optval, optlen);
461 #else
462 # error getsockopt not available
463 #endif
464 }
465
466 inline int os::listen(int sockfd, int backlog)
467 {
468 #if defined(HAVE_LISTEN)
469         return ::listen(sockfd, backlog);
470 #else
471 # error listen not available
472 #endif
473 }
474
475 inline static off_t system_lseek(int fildes, off_t offset, int whence)
476 {
477 #if defined(HAVE_LSEEK)
478         return lseek(fildes, offset, whence);
479 #else
480 # error lseek not available
481 #endif
482 }
483
484 inline void* os::malloc(size_t size)
485 {
486 #if defined(HAVE_MALLOC)
487         return ::malloc(size);
488 #else
489 # error malloc not available
490 #endif
491 }
492
493 inline void* os::memcpy(void* dest, const void* src, size_t n)
494 {
495 #if defined(HAVE_MEMCPY)
496         return ::memcpy(dest, src, n);
497 #else
498 # error memcpy not available
499 #endif
500 }
501
502 inline void* os::memset(void* s, int c, size_t n)
503 {
504 #if defined(HAVE_MEMSET)
505         return ::memset(s, c, n);
506 #else
507 # error memset not available
508 #endif
509 }
510
511 inline int os::mprotect(void* addr, size_t len, int prot)
512 {
513 #if defined(HAVE_MPROTECT)
514         return ::mprotect(addr, len, prot);
515 #else
516 # error mprotect not available
517 #endif
518 }
519
520 inline static int system_open(const char *pathname, int flags, mode_t mode)
521 {
522 #if defined(HAVE_OPEN)
523         return open(pathname, flags, mode);
524 #else
525 # error open not available
526 #endif
527 }
528
529 inline static ssize_t system_read(int fd, void *buf, size_t count)
530 {
531 #if defined(HAVE_READ)
532         return read(fd, buf, count);
533 #else
534 # error read not available
535 #endif
536 }
537
538 inline ssize_t os::readlink(const char* path, char* buf, size_t bufsiz)
539 {
540 #if defined(HAVE_READLINK)
541         return ::readlink(path, buf, bufsiz);
542 #else
543 # error readlink not available
544 #endif
545 }
546
547 inline static void *system_realloc(void *ptr, size_t size)
548 {
549 #if defined(HAVE_REALLOC)
550         return realloc(ptr, size);
551 #else
552 # error realloc not available
553 #endif
554 }
555
556 template<class _F1, class _F2>
557 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 *))
558 {
559         return scandir(dir, namelist, (_F1) filter, (_F2) compar);
560 }
561
562 inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(const struct dirent *), int(*compar)(const void *, const void *))
563 {
564 #if defined(HAVE_SCANDIR)
565         return call_scandir(::scandir, dir, namelist, filter, compar);
566 #else
567 # error scandir not available
568 #endif
569 }
570
571 inline ssize_t os::send(int s, const void* buf, size_t len, int flags)
572 {
573         // TODO Should be restartable on Linux and interruptible on Solaris.
574 #if defined(HAVE_SEND)
575         return ::send(s, buf, len, flags);
576 #else
577 # error send not available
578 #endif
579 }
580
581 inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
582 {
583 #if defined(HAVE_SETSOCKOPT)
584         return ::setsockopt(s, level, optname, optval, optlen);
585 #else
586 # error setsockopt not available
587 #endif
588 }
589
590 inline int os::shutdown(int s, int how)
591 {
592 #if defined(HAVE_SHUTDOWN)
593         return ::shutdown(s, how);
594 #else
595 # error shutdown not available
596 #endif
597 }
598
599 inline int os::socket(int domain, int type, int protocol)
600 {
601 #if defined(HAVE_SOCKET)
602         return ::socket(domain, type, protocol);
603 #else
604 # error socket not available
605 #endif
606 }
607
608 inline int os::stat(const char* path, struct stat* buf)
609 {
610 #if defined(HAVE_STAT)
611         return ::stat(path, buf);
612 #else
613 # error stat not available
614 #endif
615 }
616
617 #if defined(__SOLARIS__)
618 inline int os::str2sig(const char* str, int* signum)
619 {
620 #if defined(HAVE_STR2SIG)
621         return ::str2sig(str, signum);
622 #else
623 # error str2sig not available
624 #endif
625 }
626 #endif
627
628 inline char* os::strcat(char* dest, const char* src)
629 {
630 #if defined(HAVE_STRCAT)
631         return ::strcat(dest, src);
632 #else
633 # error strcat not available
634 #endif
635 }
636
637 inline int os::strcmp(const char* s1, const char* s2)
638 {
639 #if defined(HAVE_STRCMP)
640         return ::strcmp(s1, s2);
641 #else
642 # error strcmp not available
643 #endif
644 }
645
646 inline char* os::strcpy(char* dest, const char* src)
647 {
648 #if defined(HAVE_STRCPY)
649         return ::strcpy(dest, src);
650 #else
651 # error strcpy not available
652 #endif
653 }
654
655 inline char* os::strdup(const char* s)
656 {
657 #if defined(HAVE_STRDUP)
658         return ::strdup(s);
659 #else
660 # error strdup not available
661 #endif
662 }
663
664 inline char* os::strerror(int errnum)
665 {
666 #if defined(HAVE_STRERROR)
667         return ::strerror(errnum);
668 #else
669 # error strerror not available
670 #endif
671 }
672
673 inline size_t os::strlen(const char* s)
674 {
675 #if defined(HAVE_STRLEN)
676         return ::strlen(s);
677 #else
678 # error strlen not available
679 #endif
680 }
681
682 inline static ssize_t system_write(int fd, const void *buf, size_t count)
683 {
684 #if defined(HAVE_WRITE)
685         return write(fd, buf, count);
686 #else
687 # error write not available
688 #endif
689 }
690
691 #else
692
693 void*  os_mmap_anonymous(void *addr, size_t len, int prot, int flags);
694
695 int    os_atoi(const char* nptr);
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 char*  os_strdup(const char* s);
700 int    os_strlen(const char* s);
701
702 #endif
703
704 #endif // _OS_HPP
705
706
707 /*
708  * These are local overrides for various environment variables in Emacs.
709  * Please do not remove this and leave it at the end of the file, where
710  * Emacs will automagically detect them.
711  * ---------------------------------------------------------------------
712  * Local variables:
713  * mode: c++
714  * indent-tabs-mode: t
715  * c-basic-offset: 4
716  * tab-width: 4
717  * End:
718  * vim:noexpandtab:sw=4:ts=4:
719  */