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