Updates to follow the RTS tidyup
[ghc-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 #endif
205
206 // This is used by dph:Data.Array.Parallel.Arr.BUArr, and shouldn't be
207 INLINE void *
208 __hscore_memcpy_dst_off( char *dst, int dst_off, char *src, size_t sz )
209 { return memcpy(dst+dst_off, src, sz); }
210
211 INLINE void *
212 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
213 { return memcpy(dst, src+src_off, sz); }
214
215 INLINE HsInt
216 __hscore_bufsiz()
217 {
218   return BUFSIZ;
219 }
220
221 INLINE int
222 __hscore_seek_cur()
223 {
224   return SEEK_CUR;
225 }
226
227 INLINE int
228 __hscore_o_binary()
229 {
230 #if defined(_MSC_VER)
231   return O_BINARY;
232 #else
233   return CONST_O_BINARY;
234 #endif
235 }
236
237 INLINE int
238 __hscore_o_rdonly()
239 {
240 #ifdef O_RDONLY
241   return O_RDONLY;
242 #else
243   return 0;
244 #endif
245 }
246
247 INLINE int
248 __hscore_o_wronly( void )
249 {
250 #ifdef O_WRONLY
251   return O_WRONLY;
252 #else
253   return 0;
254 #endif
255 }
256
257 INLINE int
258 __hscore_o_rdwr( void )
259 {
260 #ifdef O_RDWR
261   return O_RDWR;
262 #else
263   return 0;
264 #endif
265 }
266
267 INLINE int
268 __hscore_o_append( void )
269 {
270 #ifdef O_APPEND
271   return O_APPEND;
272 #else
273   return 0;
274 #endif
275 }
276
277 INLINE int
278 __hscore_o_creat( void )
279 {
280 #ifdef O_CREAT
281   return O_CREAT;
282 #else
283   return 0;
284 #endif
285 }
286
287 INLINE int
288 __hscore_o_excl( void )
289 {
290 #ifdef O_EXCL
291   return O_EXCL;
292 #else
293   return 0;
294 #endif
295 }
296
297 INLINE int
298 __hscore_o_trunc( void )
299 {
300 #ifdef O_TRUNC
301   return O_TRUNC;
302 #else
303   return 0;
304 #endif
305 }
306
307 INLINE int
308 __hscore_o_noctty( void )
309 {
310 #ifdef O_NOCTTY
311   return O_NOCTTY;
312 #else
313   return 0;
314 #endif
315 }
316
317 INLINE int
318 __hscore_o_nonblock( void )
319 {
320 #ifdef O_NONBLOCK
321   return O_NONBLOCK;
322 #else
323   return 0;
324 #endif
325 }
326
327 INLINE int
328 __hscore_seek_set( void )
329 {
330   return SEEK_SET;
331 }
332
333 INLINE int
334 __hscore_seek_end( void )
335 {
336   return SEEK_END;
337 }
338
339 INLINE int
340 __hscore_ftruncate( int fd, off_t where )
341 {
342 #if defined(HAVE_FTRUNCATE)
343   return ftruncate(fd,where);
344 #elif defined(HAVE__CHSIZE)
345   return _chsize(fd,where);
346 #else
347 // ToDo: we should use _chsize_s() on Windows which allows a 64-bit
348 // offset, but it doesn't seem to be available from mingw at this time 
349 // --SDM (01/2008)
350 #error at least ftruncate or _chsize functions are required to build
351 #endif
352 }
353
354 INLINE int
355 __hscore_setmode( int fd, HsBool toBin )
356 {
357 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
358   return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
359 #else
360   return 0;
361 #endif
362 }
363
364 #if __GLASGOW_HASKELL__
365
366 #endif /* __GLASGOW_HASKELL__ */
367
368 #if defined(__MINGW32__)
369 // We want the versions of stat/fstat/lseek that use 64-bit offsets,
370 // and you have to ask for those explicitly.  Unfortunately there
371 // doesn't seem to be a 64-bit version of truncate/ftruncate, so while
372 // hFileSize and hSeek will work with large files, hSetFileSize will not.
373 typedef struct _stati64 struct_stat;
374 typedef off64_t stsize_t;
375 #else
376 typedef struct stat struct_stat;
377 typedef off_t stsize_t;
378 #endif
379
380 INLINE HsInt
381 __hscore_sizeof_stat( void )
382 {
383   return sizeof(struct_stat);
384 }
385
386 INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; }
387 INLINE stsize_t __hscore_st_size  ( struct_stat* st ) { return st->st_size; }
388 #if !defined(_MSC_VER)
389 INLINE mode_t __hscore_st_mode  ( struct_stat* st ) { return st->st_mode; }
390 INLINE dev_t  __hscore_st_dev  ( struct_stat* st ) { return st->st_dev; }
391 INLINE ino_t  __hscore_st_ino  ( struct_stat* st ) { return st->st_ino; }
392 #endif
393
394 #if defined(__MINGW32__)
395 INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
396         return _wstati64(file,buf);
397 }
398
399 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
400         return _fstati64(fd,buf);
401 }
402 INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
403 {
404         return _wstati64(fname,buf);
405 }
406 #else
407 INLINE int __hscore_stat(char *file, struct_stat *buf) {
408         return stat(file,buf);
409 }
410
411 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
412         return fstat(fd,buf);
413 }
414
415 INLINE int __hscore_lstat( const char *fname, struct stat *buf )
416 {
417 #if HAVE_LSTAT
418   return lstat(fname, buf);
419 #else
420   return stat(fname, buf);
421 #endif
422 }
423 #endif
424
425 #if HAVE_TERMIOS_H
426 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
427
428 INLINE void
429 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
430
431 INLINE unsigned char*
432 __hscore_ptr_c_cc( struct termios* ts )
433 { return (unsigned char*) &ts->c_cc; }
434
435 INLINE HsInt
436 __hscore_sizeof_termios( void )
437 {
438 #ifndef __MINGW32__
439   return sizeof(struct termios);
440 #else
441   return 0;
442 #endif
443 }
444 #endif
445
446 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
447 INLINE HsInt
448 __hscore_sizeof_sigset_t( void )
449 {
450   return sizeof(sigset_t);
451 }
452 #endif
453
454 INLINE int
455 __hscore_echo( void )
456 {
457 #ifdef ECHO
458   return ECHO;
459 #else
460   return 0;
461 #endif
462
463 }
464
465 INLINE int
466 __hscore_tcsanow( void )
467 {
468 #ifdef TCSANOW
469   return TCSANOW;
470 #else
471   return 0;
472 #endif
473
474 }
475
476 INLINE int
477 __hscore_icanon( void )
478 {
479 #ifdef ICANON
480   return ICANON;
481 #else
482   return 0;
483 #endif
484 }
485
486 INLINE int __hscore_vmin( void )
487 {
488 #ifdef VMIN
489   return VMIN;
490 #else
491   return 0;
492 #endif
493 }
494
495 INLINE int __hscore_vtime( void )
496 {
497 #ifdef VTIME
498   return VTIME;
499 #else
500   return 0;
501 #endif
502 }
503
504 INLINE int __hscore_sigttou( void )
505 {
506 #ifdef SIGTTOU
507   return SIGTTOU;
508 #else
509   return 0;
510 #endif
511 }
512
513 INLINE int __hscore_sig_block( void )
514 {
515 #ifdef SIG_BLOCK
516   return SIG_BLOCK;
517 #else
518   return 0;
519 #endif
520 }
521
522 INLINE int __hscore_sig_setmask( void )
523 {
524 #ifdef SIG_SETMASK
525   return SIG_SETMASK;
526 #else
527   return 0;
528 #endif
529 }
530
531 #ifndef __MINGW32__
532 INLINE size_t __hscore_sizeof_siginfo_t (void)
533 {
534     return sizeof(siginfo_t);
535 }
536 #endif
537
538 INLINE int
539 __hscore_f_getfl( void )
540 {
541 #ifdef F_GETFL
542   return F_GETFL;
543 #else
544   return 0;
545 #endif
546 }
547
548 INLINE int
549 __hscore_f_setfl( void )
550 {
551 #ifdef F_SETFL
552   return F_SETFL;
553 #else
554   return 0;
555 #endif
556 }
557
558 INLINE int
559 __hscore_f_setfd( void )
560 {
561 #ifdef F_SETFD
562   return F_SETFD;
563 #else
564   return 0;
565 #endif
566 }
567
568 INLINE long
569 __hscore_fd_cloexec( void )
570 {
571 #ifdef FD_CLOEXEC
572   return FD_CLOEXEC;
573 #else
574   return 0;
575 #endif
576 }
577
578 // defined in rts/RtsStartup.c.
579 extern void* __hscore_get_saved_termios(int fd);
580 extern void __hscore_set_saved_termios(int fd, void* ts);
581
582 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
583
584 #ifdef __MINGW32__
585 INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
586         if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
587           return _wsopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
588           // _O_NOINHERIT: see #2650
589         else
590           return _wsopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
591           // _O_NOINHERIT: see #2650
592 }
593 #else
594 INLINE int __hscore_open(char *file, int how, mode_t mode) {
595         return open(file,how,mode);
596 }
597 #endif
598
599 // These are wrapped because on some OSs (eg. Linux) they are
600 // macros which redirect to the 64-bit-off_t versions when large file
601 // support is enabled.
602 //
603 #if defined(__MINGW32__)
604 INLINE off64_t __hscore_lseek(int fd, off64_t off, int whence) {
605         return (_lseeki64(fd,off,whence));
606 }
607 #else
608 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
609         return (lseek(fd,off,whence));
610 }
611 #endif
612
613 // select-related stuff
614
615 #if !defined(__MINGW32__)
616 INLINE int  hsFD_SETSIZE(void) { return FD_SETSIZE; }
617 INLINE int  hsFD_ISSET(int fd, fd_set *fds) { return FD_ISSET(fd, fds); }
618 INLINE void hsFD_SET(int fd, fd_set *fds) { FD_SET(fd, fds); }
619 INLINE HsInt sizeof_fd_set(void) { return sizeof(fd_set); }
620 extern void hsFD_ZERO(fd_set *fds);
621 #endif
622
623 // gettimeofday()-related
624
625 #if !defined(__MINGW32__)
626
627 INLINE HsInt sizeofTimeVal(void) { return sizeof(struct timeval); }
628
629 INLINE HsWord64 getUSecOfDay(void)
630 {
631     struct timeval tv;
632     gettimeofday(&tv, (struct timezone *) NULL);
633     // Don't forget to cast *before* doing the arithmetic, otherwise
634     // the arithmetic happens at the type of tv_sec, which is probably
635     // only 'int'.
636     return ((HsWord64)tv.tv_sec * 1000000 + (HsWord64)tv.tv_usec);
637 }
638
639 INLINE void setTimevalTicks(struct timeval *p, HsWord64 usecs)
640 {
641     p->tv_sec  = usecs / 1000000;
642     p->tv_usec = usecs % 1000000;
643 }
644 #endif /* !defined(__MINGW32__) */
645
646 /* ToDo: write a feature test that doesn't assume 'environ' to
647  *    be in scope at link-time. */
648 extern char** environ;
649 INLINE char **__hscore_environ() { return environ; }
650
651 /* lossless conversions between pointers and integral types */
652 INLINE void *    __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
653 INLINE void *    __hscore_from_intptr (intptr_t n)  { return (void *)n; }
654 INLINE uintptr_t __hscore_to_uintptr  (void *p)     { return (uintptr_t)p; }
655 INLINE intptr_t  __hscore_to_intptr   (void *p)     { return (intptr_t)p; }
656
657 void errorBelch2(const char*s, char *t);
658 void debugBelch2(const char*s, char *t);
659
660 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
661
662 INLINE int fcntl_read(int fd, int cmd) {
663     return fcntl(fd, cmd);
664 }
665 INLINE int fcntl_write(int fd, int cmd, long arg) {
666     return fcntl(fd, cmd, arg);
667 }
668 INLINE int fcntl_lock(int fd, int cmd, struct flock *lock) {
669     return fcntl(fd, cmd, lock);
670 }
671
672 #endif
673
674 #endif /* __HSBASE_H__ */
675