d45ee99799cb33273658ad41a5424b7cd9999c07
[packages/base.git] / include / HsBase.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The University of Glasgow 2001-2004
4 *
5 * Definitions for package `base' which are visible in Haskell land.
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #ifndef __HSBASE_H__
10 #define __HSBASE_H__
11
12 #ifdef __NHC__
13 # include "Nhc98BaseConfig.h"
14 #else
15 #include "HsBaseConfig.h"
16 #endif
17
18 /* ultra-evil... */
19 #undef PACKAGE_BUGREPORT
20 #undef PACKAGE_NAME
21 #undef PACKAGE_STRING
22 #undef PACKAGE_TARNAME
23 #undef PACKAGE_VERSION
24
25 /* Needed to get the macro version of errno on some OSs (eg. Solaris).
26 We must do this, because these libs are only compiled once, but
27 must work in both single-threaded and multi-threaded programs. */
28 #define _REENTRANT 1
29
30 #include "HsFFI.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <math.h>
35
36 #if HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
39 #if HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #if HAVE_SYS_STAT_H
43 #include <sys/stat.h>
44 #endif
45 #if HAVE_FCNTL_H
46 # include <fcntl.h>
47 #endif
48 #if HAVE_TERMIOS_H
49 #include <termios.h>
50 #endif
51 #if HAVE_SIGNAL_H
52 #include <signal.h>
53 /* Ultra-ugly: OpenBSD uses broken macros for sigemptyset and sigfillset (missing casts) */
54 #if __OpenBSD__
55 #undef sigemptyset
56 #undef sigfillset
57 #endif
58 #endif
59 #if HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #if HAVE_STRING_H
63 #include <string.h>
64 #endif
65 #if HAVE_UTIME_H
66 #include <utime.h>
67 #endif
68 #if HAVE_SYS_UTSNAME_H
69 #include <sys/utsname.h>
70 #endif
71 #if HAVE_GETTIMEOFDAY
72 # if HAVE_SYS_TIME_H
73 # include <sys/time.h>
74 # endif
75 #elif HAVE_GETCLOCK
76 # if HAVE_SYS_TIMERS_H
77 # define POSIX_4D9 1
78 # include <sys/timers.h>
79 # endif
80 #endif
81 #if HAVE_TIME_H
82 #include <time.h>
83 #endif
84 #if HAVE_SYS_TIMEB_H
85 #include <sys/timeb.h>
86 #endif
87 #if HAVE_WINDOWS_H
88 #include <windows.h>
89 #endif
90 #if HAVE_SYS_TIMES_H
91 #include <sys/times.h>
92 #endif
93 #if HAVE_WINSOCK_H && defined(__MINGW32__)
94 #include <winsock.h>
95 #endif
96 #if HAVE_LIMITS_H
97 #include <limits.h>
98 #endif
99 #if HAVE_WCTYPE_H
100 #include <wctype.h>
101 #endif
102 #if HAVE_INTTYPES_H
103 # include <inttypes.h>
104 #elif HAVE_STDINT_H
105 # include <stdint.h>
106 #endif
107
108 #if !defined(__MINGW32__) && !defined(irix_HOST_OS)
109 # if HAVE_SYS_RESOURCE_H
110 # include <sys/resource.h>
111 # endif
112 #endif
113
114 #if !HAVE_GETRUSAGE && HAVE_SYS_SYSCALL_H
115 # include <sys/syscall.h>
116 # if defined(SYS_GETRUSAGE) /* hpux_HOST_OS */
117 # define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
118 # define HAVE_GETRUSAGE 1
119 # endif
120 #endif
121
122 /* For System */
123 #if HAVE_SYS_WAIT_H
124 #include <sys/wait.h>
125 #endif
126 #if HAVE_VFORK_H
127 #include <vfork.h>
128 #endif
129 #include "WCsubst.h"
130
131 #if defined(__MINGW32__)
132 /* in Win32Utils.c */
133 extern void maperrno (void);
134 extern HsWord64 getUSecOfDay(void);
135 #endif
136
137 #if defined(__MINGW32__)
138 #include <io.h>
139 #include <fcntl.h>
140 #include <shlobj.h>
141 #include <share.h>
142 #endif
143
144 #if HAVE_SYS_SELECT_H
145 #include <sys/select.h>
146 #endif
147
148 /* in inputReady.c */
149 extern int fdReady(int fd, int write, int msecs, int isSock);
150
151 /* in Signals.c */
152 extern HsInt nocldstop;
153
154 /* -----------------------------------------------------------------------------
155 INLINE functions.
156
157 These functions are given as inlines here for when compiling via C,
158 but we also generate static versions into the cbits library for
159 when compiling to native code.
160 -------------------------------------------------------------------------- */
161
162 #ifndef INLINE
163 # if defined(_MSC_VER)
164 # define INLINE extern __inline
165 # else
166 # define INLINE static inline
167 # endif
168 #endif
169
170 INLINE int __hscore_get_errno(void) { return errno; }
171 INLINE void __hscore_set_errno(int e) { errno = e; }
172
173 #if !defined(_MSC_VER)
174 INLINE int __hscore_s_isreg(mode_t m) { return S_ISREG(m); }
175 INLINE int __hscore_s_isdir(mode_t m) { return S_ISDIR(m); }
176 INLINE int __hscore_s_isfifo(mode_t m) { return S_ISFIFO(m); }
177 INLINE int __hscore_s_isblk(mode_t m) { return S_ISBLK(m); }
178 INLINE int __hscore_s_ischr(mode_t m) { return S_ISCHR(m); }
179 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
180 INLINE int __hscore_s_issock(mode_t m) { return S_ISSOCK(m); }
181 #endif
182 #endif
183
184 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
185 INLINE int
186 __hscore_sigemptyset( sigset_t *set )
187 { return sigemptyset(set); }
188
189 INLINE int
190 __hscore_sigfillset( sigset_t *set )
191 { return sigfillset(set); }
192
193 INLINE int
194 __hscore_sigaddset( sigset_t * set, int s )
195 { return sigaddset(set,s); }
196
197 INLINE int
198 __hscore_sigdelset( sigset_t * set, int s )
199 { return sigdelset(set,s); }
200
201 INLINE int
202 __hscore_sigismember( sigset_t * set, int s )
203 { return sigismember(set,s); }
204
205 INLINE int
206 __hscore_utime( const char *file, const struct utimbuf *timep )
207 { return utime(file,timep); }
208 #endif
209
210 INLINE void *
211 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
212 { return memcpy(dst, src+src_off, sz); }
213
214 INLINE HsInt
215 __hscore_bufsiz(void)
216 {
217 return BUFSIZ;
218 }
219
220 INLINE int
221 __hscore_seek_cur(void)
222 {
223 return SEEK_CUR;
224 }
225
226 INLINE int
227 __hscore_o_binary(void)
228 {
229 #if defined(_MSC_VER)
230 return O_BINARY;
231 #else
232 return CONST_O_BINARY;
233 #endif
234 }
235
236 INLINE int
237 __hscore_o_rdonly(void)
238 {
239 #ifdef O_RDONLY
240 return O_RDONLY;
241 #else
242 return 0;
243 #endif
244 }
245
246 INLINE int
247 __hscore_o_wronly( void )
248 {
249 #ifdef O_WRONLY
250 return O_WRONLY;
251 #else
252 return 0;
253 #endif
254 }
255
256 INLINE int
257 __hscore_o_rdwr( void )
258 {
259 #ifdef O_RDWR
260 return O_RDWR;
261 #else
262 return 0;
263 #endif
264 }
265
266 INLINE int
267 __hscore_o_append( void )
268 {
269 #ifdef O_APPEND
270 return O_APPEND;
271 #else
272 return 0;
273 #endif
274 }
275
276 INLINE int
277 __hscore_o_creat( void )
278 {
279 #ifdef O_CREAT
280 return O_CREAT;
281 #else
282 return 0;
283 #endif
284 }
285
286 INLINE int
287 __hscore_o_excl( void )
288 {
289 #ifdef O_EXCL
290 return O_EXCL;
291 #else
292 return 0;
293 #endif
294 }
295
296 INLINE int
297 __hscore_o_trunc( void )
298 {
299 #ifdef O_TRUNC
300 return O_TRUNC;
301 #else
302 return 0;
303 #endif
304 }
305
306 INLINE int
307 __hscore_o_noctty( void )
308 {
309 #ifdef O_NOCTTY
310 return O_NOCTTY;
311 #else
312 return 0;
313 #endif
314 }
315
316 INLINE int
317 __hscore_o_nonblock( void )
318 {
319 #ifdef O_NONBLOCK
320 return O_NONBLOCK;
321 #else
322 return 0;
323 #endif
324 }
325
326 INLINE int
327 __hscore_seek_set( void )
328 {
329 return SEEK_SET;
330 }
331
332 INLINE int
333 __hscore_seek_end( void )
334 {
335 return SEEK_END;
336 }
337
338 INLINE int
339 __hscore_ftruncate( int fd, off_t where )
340 {
341 #if defined(HAVE_FTRUNCATE)
342 return ftruncate(fd,where);
343 #elif defined(HAVE__CHSIZE)
344 return _chsize(fd,where);
345 #else
346 // ToDo: we should use _chsize_s() on Windows which allows a 64-bit
347 // offset, but it doesn't seem to be available from mingw at this time
348 // --SDM (01/2008)
349 #error at least ftruncate or _chsize functions are required to build
350 #endif
351 }
352
353 INLINE int
354 __hscore_setmode( int fd, HsBool toBin )
355 {
356 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
357 return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
358 #else
359 return 0;
360 #endif
361 }
362
363 #if __GLASGOW_HASKELL__
364
365 #endif /* __GLASGOW_HASKELL__ */
366
367 #if defined(__MINGW32__)
368 // We want the versions of stat/fstat/lseek that use 64-bit offsets,
369 // and you have to ask for those explicitly. Unfortunately there
370 // doesn't seem to be a 64-bit version of truncate/ftruncate, so while
371 // hFileSize and hSeek will work with large files, hSetFileSize will not.
372 typedef struct _stati64 struct_stat;
373 typedef off64_t stsize_t;
374 #else
375 typedef struct stat struct_stat;
376 typedef off_t stsize_t;
377 #endif
378
379 INLINE HsInt
380 __hscore_sizeof_stat( void )
381 {
382 return sizeof(struct_stat);
383 }
384
385 INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; }
386 INLINE stsize_t __hscore_st_size ( struct_stat* st ) { return st->st_size; }
387 #if !defined(_MSC_VER)
388 INLINE mode_t __hscore_st_mode ( struct_stat* st ) { return st->st_mode; }
389 INLINE dev_t __hscore_st_dev ( struct_stat* st ) { return st->st_dev; }
390 INLINE ino_t __hscore_st_ino ( struct_stat* st ) { return st->st_ino; }
391 #endif
392
393 #if defined(__MINGW32__)
394 INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
395 return _wstati64(file,buf);
396 }
397
398 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
399 return _fstati64(fd,buf);
400 }
401 INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
402 {
403 return _wstati64(fname,buf);
404 }
405 #else
406 INLINE int __hscore_stat(char *file, struct_stat *buf) {
407 return stat(file,buf);
408 }
409
410 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
411 return fstat(fd,buf);
412 }
413
414 INLINE int __hscore_lstat( const char *fname, struct stat *buf )
415 {
416 #if HAVE_LSTAT
417 return lstat(fname, buf);
418 #else
419 return stat(fname, buf);
420 #endif
421 }
422 #endif
423
424 #if HAVE_TERMIOS_H
425 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
426
427 INLINE void
428 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
429
430 INLINE unsigned char*
431 __hscore_ptr_c_cc( struct termios* ts )
432 { return (unsigned char*) &ts->c_cc; }
433
434 INLINE HsInt
435 __hscore_sizeof_termios( void )
436 {
437 #ifndef __MINGW32__
438 return sizeof(struct termios);
439 #else
440 return 0;
441 #endif
442 }
443 #endif
444
445 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
446 INLINE HsInt
447 __hscore_sizeof_sigset_t( void )
448 {
449 return sizeof(sigset_t);
450 }
451 #endif
452
453 INLINE int
454 __hscore_echo( void )
455 {
456 #ifdef ECHO
457 return ECHO;
458 #else
459 return 0;
460 #endif
461
462 }
463
464 INLINE int
465 __hscore_tcsanow( void )
466 {
467 #ifdef TCSANOW
468 return TCSANOW;
469 #else
470 return 0;
471 #endif
472
473 }
474
475 INLINE int
476 __hscore_icanon( void )
477 {
478 #ifdef ICANON
479 return ICANON;
480 #else
481 return 0;
482 #endif
483 }
484
485 INLINE int __hscore_vmin( void )
486 {
487 #ifdef VMIN
488 return VMIN;
489 #else
490 return 0;
491 #endif
492 }
493
494 INLINE int __hscore_vtime( void )
495 {
496 #ifdef VTIME
497 return VTIME;
498 #else
499 return 0;
500 #endif
501 }
502
503 INLINE int __hscore_sigttou( void )
504 {
505 #ifdef SIGTTOU
506 return SIGTTOU;
507 #else
508 return 0;
509 #endif
510 }
511
512 INLINE int __hscore_sig_block( void )
513 {
514 #ifdef SIG_BLOCK
515 return SIG_BLOCK;
516 #else
517 return 0;
518 #endif
519 }
520
521 INLINE int __hscore_sig_setmask( void )
522 {
523 #ifdef SIG_SETMASK
524 return SIG_SETMASK;
525 #else
526 return 0;
527 #endif
528 }
529
530 #ifndef __MINGW32__
531 INLINE size_t __hscore_sizeof_siginfo_t (void)
532 {
533 return sizeof(siginfo_t);
534 }
535 #endif
536
537 INLINE int
538 __hscore_f_getfl( void )
539 {
540 #ifdef F_GETFL
541 return F_GETFL;
542 #else
543 return 0;
544 #endif
545 }
546
547 INLINE int
548 __hscore_f_setfl( void )
549 {
550 #ifdef F_SETFL
551 return F_SETFL;
552 #else
553 return 0;
554 #endif
555 }
556
557 INLINE int
558 __hscore_f_setfd( void )
559 {
560 #ifdef F_SETFD
561 return F_SETFD;
562 #else
563 return 0;
564 #endif
565 }
566
567 INLINE long
568 __hscore_fd_cloexec( void )
569 {
570 #ifdef FD_CLOEXEC
571 return FD_CLOEXEC;
572 #else
573 return 0;
574 #endif
575 }
576
577 // defined in rts/RtsStartup.c.
578 extern void* __hscore_get_saved_termios(int fd);
579 extern void __hscore_set_saved_termios(int fd, void* ts);
580
581 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
582
583 #ifdef __MINGW32__
584 INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
585 if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
586 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
587 // _O_NOINHERIT: see #2650
588 else
589 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
590 // _O_NOINHERIT: see #2650
591 }
592 #else
593 INLINE int __hscore_open(char *file, int how, mode_t mode) {
594 return open(file,how,mode);
595 }
596 #endif
597
598 // These are wrapped because on some OSs (eg. Linux) they are
599 // macros which redirect to the 64-bit-off_t versions when large file
600 // support is enabled.
601 //
602 #if defined(__MINGW32__)
603 INLINE off64_t __hscore_lseek(int fd, off64_t off, int whence) {
604 return (_lseeki64(fd,off,whence));
605 }
606 #else
607 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
608 return (lseek(fd,off,whence));
609 }
610 #endif
611
612 // select-related stuff
613
614 #if !defined(__MINGW32__)
615 INLINE int hsFD_SETSIZE(void) { return FD_SETSIZE; }
616 INLINE int hsFD_ISSET(int fd, fd_set *fds) { return FD_ISSET(fd, fds); }
617 INLINE void hsFD_SET(int fd, fd_set *fds) { FD_SET(fd, fds); }
618 INLINE HsInt sizeof_fd_set(void) { return sizeof(fd_set); }
619 extern void hsFD_ZERO(fd_set *fds);
620 #endif
621
622 INLINE int __hscore_select(int nfds, fd_set *readfds, fd_set *writefds,
623 fd_set *exceptfds, struct timeval *timeout) {
624 return (select(nfds,readfds,writefds,exceptfds,timeout));
625 }
626
627 // gettimeofday()-related
628
629 #if !defined(__MINGW32__)
630 INLINE int __hsbase_gettimeofday(struct timeval *tv, struct timezone *tz) {
631 return gettimeofday(tv, tz);
632 }
633 #endif /* !defined(__MINGW32__) */
634
635 #if darwin_HOST_OS
636 // You should not access _environ directly on Darwin in a bundle/shared library.
637 // See #2458 and http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man7/environ.7.html
638 #include <crt_externs.h>
639 INLINE char **__hscore_environ(void) { return *(_NSGetEnviron()); }
640 #else
641 /* ToDo: write a feature test that doesn't assume 'environ' to
642 * be in scope at link-time. */
643 extern char** environ;
644 INLINE char **__hscore_environ(void) { return environ; }
645 #endif
646
647 /* lossless conversions between pointers and integral types */
648 INLINE void * __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
649 INLINE void * __hscore_from_intptr (intptr_t n) { return (void *)n; }
650 INLINE uintptr_t __hscore_to_uintptr (void *p) { return (uintptr_t)p; }
651 INLINE intptr_t __hscore_to_intptr (void *p) { return (intptr_t)p; }
652
653 void errorBelch2(const char*s, char *t);
654 void debugBelch2(const char*s, char *t);
655
656 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
657
658 INLINE int fcntl_read(int fd, int cmd) {
659 return fcntl(fd, cmd);
660 }
661 INLINE int fcntl_write(int fd, int cmd, long arg) {
662 return fcntl(fd, cmd, arg);
663 }
664 INLINE int fcntl_lock(int fd, int cmd, struct flock *lock) {
665 return fcntl(fd, cmd, lock);
666 }
667
668 #endif
669
670 #if !defined(mingw32_HOST_OS) && !defined(cygwin32_HOST_OS)
671 #if defined(HAVE_GETRUSAGE) && ! irix_HOST_OS && ! solaris2_HOST_OS
672 INLINE int __hsbase_getrusage(int who, struct rusage *rusage) {
673 return getrusage(who, rusage);
674 }
675 #endif
676 #endif
677
678 #endif /* __HSBASE_H__ */
679