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