ccabc1e1f9a95e581f6d59fb2a274782d95ce621
[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_DIRENT_H
66 #include <dirent.h>
67 #endif
68 #if HAVE_UTIME_H
69 #include <utime.h>
70 #endif
71 #if HAVE_SYS_UTSNAME_H
72 #include <sys/utsname.h>
73 #endif
74 #if HAVE_GETTIMEOFDAY
75 #  if HAVE_SYS_TIME_H
76 #   include <sys/time.h>
77 #  endif
78 #elif HAVE_GETCLOCK
79 # if HAVE_SYS_TIMERS_H
80 #  define POSIX_4D9 1
81 #  include <sys/timers.h>
82 # endif
83 #endif
84 #if HAVE_TIME_H
85 #include <time.h>
86 #endif
87 #if HAVE_SYS_TIMEB_H
88 #include <sys/timeb.h>
89 #endif
90 #if HAVE_WINDOWS_H
91 #include <windows.h>
92 #endif
93 #if HAVE_SYS_TIMES_H
94 #include <sys/times.h>
95 #endif
96 #if HAVE_WINSOCK_H && defined(__MINGW32__)
97 #include <winsock.h>
98 #endif
99 #if HAVE_LIMITS_H
100 #include <limits.h>
101 #endif
102 #if HAVE_WCTYPE_H
103 #include <wctype.h>
104 #endif
105 #if HAVE_INTTYPES_H
106 # include <inttypes.h>
107 #elif HAVE_STDINT_H
108 # include <stdint.h>
109 #endif
110
111 #if !defined(__MINGW32__) && !defined(irix_HOST_OS)
112 # if HAVE_SYS_RESOURCE_H
113 #  include <sys/resource.h>
114 # endif
115 #endif
116
117 #if !HAVE_GETRUSAGE && HAVE_SYS_SYSCALL_H
118 # include <sys/syscall.h>
119 # if defined(SYS_GETRUSAGE)     /* hpux_HOST_OS */
120 #  define getrusage(a, b)  syscall(SYS_GETRUSAGE, a, b)
121 #  define HAVE_GETRUSAGE 1
122 # endif
123 #endif
124
125 /* For System */
126 #if HAVE_SYS_WAIT_H
127 #include <sys/wait.h>
128 #endif
129 #if HAVE_VFORK_H
130 #include <vfork.h>
131 #endif
132 #include "dirUtils.h"
133 #include "WCsubst.h"
134
135 #if defined(__MINGW32__)
136 /* in Win32Utils.c */
137 extern void maperrno (void);
138 extern HsWord64 getUSecOfDay(void);
139 #endif
140
141 #if defined(__MINGW32__)
142 #include <io.h>
143 #include <fcntl.h>
144 #include <shlobj.h>
145 #include <share.h>
146 #endif
147
148 #if HAVE_SYS_SELECT_H
149 #include <sys/select.h>
150 #endif
151
152 /* in inputReady.c */
153 extern int fdReady(int fd, int write, int msecs, int isSock);
154
155 /* in Signals.c */
156 extern HsInt nocldstop;
157
158 /* -----------------------------------------------------------------------------
159    64-bit operations, defined in longlong.c
160    -------------------------------------------------------------------------- */
161
162 #ifdef SUPPORT_LONG_LONGS
163
164 HsBool hs_gtWord64 (HsWord64, HsWord64);
165 HsBool hs_geWord64 (HsWord64, HsWord64);
166 HsBool hs_eqWord64 (HsWord64, HsWord64);
167 HsBool hs_neWord64 (HsWord64, HsWord64);
168 HsBool hs_ltWord64 (HsWord64, HsWord64);
169 HsBool hs_leWord64 (HsWord64, HsWord64);
170
171 HsBool hs_gtInt64 (HsInt64, HsInt64);
172 HsBool hs_geInt64 (HsInt64, HsInt64);
173 HsBool hs_eqInt64 (HsInt64, HsInt64);
174 HsBool hs_neInt64 (HsInt64, HsInt64);
175 HsBool hs_ltInt64 (HsInt64, HsInt64);
176 HsBool hs_leInt64 (HsInt64, HsInt64);
177
178 HsWord64 hs_remWord64  (HsWord64, HsWord64);
179 HsWord64 hs_quotWord64 (HsWord64, HsWord64);
180
181 HsInt64 hs_remInt64    (HsInt64, HsInt64);
182 HsInt64 hs_quotInt64   (HsInt64, HsInt64);
183 HsInt64 hs_negateInt64 (HsInt64);
184 HsInt64 hs_plusInt64   (HsInt64, HsInt64);
185 HsInt64 hs_minusInt64  (HsInt64, HsInt64);
186 HsInt64 hs_timesInt64  (HsInt64, HsInt64);
187
188 HsWord64 hs_and64  (HsWord64, HsWord64);
189 HsWord64 hs_or64   (HsWord64, HsWord64);
190 HsWord64 hs_xor64  (HsWord64, HsWord64);
191 HsWord64 hs_not64  (HsWord64);
192
193 HsWord64 hs_uncheckedShiftL64   (HsWord64, HsInt);
194 HsWord64 hs_uncheckedShiftRL64  (HsWord64, HsInt);
195 HsInt64  hs_uncheckedIShiftL64  (HsInt64, HsInt);
196 HsInt64  hs_uncheckedIShiftRA64 (HsInt64, HsInt);
197 HsInt64  hs_uncheckedIShiftRL64 (HsInt64, HsInt);
198
199 HsInt64  hs_intToInt64    (HsInt);
200 HsInt    hs_int64ToInt    (HsInt64);
201 HsWord64 hs_int64ToWord64 (HsInt64);
202 HsWord64 hs_wordToWord64  (HsWord);
203 HsWord   hs_word64ToWord  (HsWord64);
204 HsInt64  hs_word64ToInt64 (HsWord64);
205
206 #endif /* SUPPORT_LONG_LONGS */
207
208 /* -----------------------------------------------------------------------------
209    INLINE functions.
210
211    These functions are given as inlines here for when compiling via C,
212    but we also generate static versions into the cbits library for
213    when compiling to native code.
214    -------------------------------------------------------------------------- */
215
216 #ifndef INLINE
217 # if defined(_MSC_VER)
218 #  define INLINE extern __inline
219 # else
220 #  define INLINE static inline
221 # endif
222 #endif
223
224 INLINE int __hscore_get_errno(void) { return errno; }
225 INLINE void __hscore_set_errno(int e) { errno = e; }
226
227 #if !defined(_MSC_VER)
228 INLINE int __hscore_s_isreg(mode_t m)  { return S_ISREG(m);  }
229 INLINE int __hscore_s_isdir(mode_t m)  { return S_ISDIR(m);  }
230 INLINE int __hscore_s_isfifo(mode_t m) { return S_ISFIFO(m); }
231 INLINE int __hscore_s_isblk(mode_t m)  { return S_ISBLK(m);  }
232 INLINE int __hscore_s_ischr(mode_t m)  { return S_ISCHR(m);  }
233 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
234 INLINE int __hscore_s_issock(mode_t m) { return S_ISSOCK(m); }
235 #endif
236 #endif
237
238 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
239 INLINE int
240 __hscore_sigemptyset( sigset_t *set )
241 { return sigemptyset(set); }
242
243 INLINE int
244 __hscore_sigfillset( sigset_t *set )
245 { return sigfillset(set); }
246
247 INLINE int
248 __hscore_sigaddset( sigset_t * set, int s )
249 { return sigaddset(set,s); }
250
251 INLINE int
252 __hscore_sigdelset( sigset_t * set, int s )
253 { return sigdelset(set,s); }
254
255 INLINE int
256 __hscore_sigismember( sigset_t * set, int s )
257 { return sigismember(set,s); }
258 #endif
259
260 // This is used by dph:Data.Array.Parallel.Arr.BUArr, and shouldn't be
261 INLINE void *
262 __hscore_memcpy_dst_off( char *dst, int dst_off, char *src, size_t sz )
263 { return memcpy(dst+dst_off, src, sz); }
264
265 INLINE void *
266 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
267 { return memcpy(dst, src+src_off, sz); }
268
269 INLINE HsInt
270 __hscore_bufsiz()
271 {
272   return BUFSIZ;
273 }
274
275 INLINE int
276 __hscore_seek_cur()
277 {
278   return SEEK_CUR;
279 }
280
281 INLINE int
282 __hscore_o_binary()
283 {
284 #if defined(_MSC_VER)
285   return O_BINARY;
286 #else
287   return CONST_O_BINARY;
288 #endif
289 }
290
291 INLINE int
292 __hscore_o_rdonly()
293 {
294 #ifdef O_RDONLY
295   return O_RDONLY;
296 #else
297   return 0;
298 #endif
299 }
300
301 INLINE int
302 __hscore_o_wronly( void )
303 {
304 #ifdef O_WRONLY
305   return O_WRONLY;
306 #else
307   return 0;
308 #endif
309 }
310
311 INLINE int
312 __hscore_o_rdwr( void )
313 {
314 #ifdef O_RDWR
315   return O_RDWR;
316 #else
317   return 0;
318 #endif
319 }
320
321 INLINE int
322 __hscore_o_append( void )
323 {
324 #ifdef O_APPEND
325   return O_APPEND;
326 #else
327   return 0;
328 #endif
329 }
330
331 INLINE int
332 __hscore_o_creat( void )
333 {
334 #ifdef O_CREAT
335   return O_CREAT;
336 #else
337   return 0;
338 #endif
339 }
340
341 INLINE int
342 __hscore_o_excl( void )
343 {
344 #ifdef O_EXCL
345   return O_EXCL;
346 #else
347   return 0;
348 #endif
349 }
350
351 INLINE int
352 __hscore_o_trunc( void )
353 {
354 #ifdef O_TRUNC
355   return O_TRUNC;
356 #else
357   return 0;
358 #endif
359 }
360
361 INLINE int
362 __hscore_o_noctty( void )
363 {
364 #ifdef O_NOCTTY
365   return O_NOCTTY;
366 #else
367   return 0;
368 #endif
369 }
370
371 INLINE int
372 __hscore_o_nonblock( void )
373 {
374 #ifdef O_NONBLOCK
375   return O_NONBLOCK;
376 #else
377   return 0;
378 #endif
379 }
380
381 INLINE int
382 __hscore_seek_set( void )
383 {
384   return SEEK_SET;
385 }
386
387 INLINE int
388 __hscore_seek_end( void )
389 {
390   return SEEK_END;
391 }
392
393 INLINE int
394 __hscore_ftruncate( int fd, off_t where )
395 {
396 #if defined(HAVE_FTRUNCATE)
397   return ftruncate(fd,where);
398 #elif defined(HAVE__CHSIZE)
399   return _chsize(fd,where);
400 #else
401 // ToDo: we should use _chsize_s() on Windows which allows a 64-bit
402 // offset, but it doesn't seem to be available from mingw at this time 
403 // --SDM (01/2008)
404 #error at least ftruncate or _chsize functions are required to build
405 #endif
406 }
407
408 INLINE int
409 __hscore_setmode( int fd, HsBool toBin )
410 {
411 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
412   return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
413 #else
414   return 0;
415 #endif
416 }
417
418 #if __GLASGOW_HASKELL__
419
420 INLINE int
421 __hscore_PrelHandle_write( int fd, void *ptr, HsInt off, int sz )
422 {
423   return write(fd,(char *)ptr + off, sz);
424 }
425
426 INLINE int
427 __hscore_PrelHandle_read( int fd, void *ptr, HsInt off, int sz )
428 {
429   return read(fd,(char *)ptr + off, sz);
430
431 }
432
433 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
434 INLINE int
435 __hscore_PrelHandle_send( int fd, void *ptr, HsInt off, int sz )
436 {
437     return send(fd,(char *)ptr + off, sz, 0);
438 }
439
440 INLINE int
441 __hscore_PrelHandle_recv( int fd, void *ptr, HsInt off, int sz )
442 {
443     return recv(fd,(char *)ptr + off, sz, 0);
444 }
445 #endif
446
447 #endif /* __GLASGOW_HASKELL__ */
448
449 INLINE int
450 __hscore_mkdir( char *pathName, int mode )
451 {
452 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
453   return mkdir(pathName);
454 #else
455   return mkdir(pathName,mode);
456 #endif
457 }
458
459 INLINE char *
460 __hscore_d_name( struct dirent* d )
461 {
462   return (d->d_name);
463 }
464
465 INLINE int
466 __hscore_end_of_dir( void )
467 {
468   return READDIR_ERRNO_EOF;
469 }
470
471 INLINE void
472 __hscore_free_dirent(struct dirent *dEnt)
473 {
474 #if HAVE_READDIR_R
475   free(dEnt);
476 #endif
477 }
478
479 #if defined(__MINGW32__)
480 // We want the versions of stat/fstat/lseek that use 64-bit offsets,
481 // and you have to ask for those explicitly.  Unfortunately there
482 // doesn't seem to be a 64-bit version of truncate/ftruncate, so while
483 // hFileSize and hSeek will work with large files, hSetFileSize will not.
484 typedef struct _stati64 struct_stat;
485 typedef off64_t stsize_t;
486 #else
487 typedef struct stat struct_stat;
488 typedef off_t stsize_t;
489 #endif
490
491 INLINE HsInt
492 __hscore_sizeof_stat( void )
493 {
494   return sizeof(struct_stat);
495 }
496
497 INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; }
498 INLINE stsize_t __hscore_st_size  ( struct_stat* st ) { return st->st_size; }
499 #if !defined(_MSC_VER)
500 INLINE mode_t __hscore_st_mode  ( struct_stat* st ) { return st->st_mode; }
501 INLINE dev_t  __hscore_st_dev  ( struct_stat* st ) { return st->st_dev; }
502 INLINE ino_t  __hscore_st_ino  ( struct_stat* st ) { return st->st_ino; }
503 #endif
504
505 #if defined(__MINGW32__)
506 INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
507         return _wstati64(file,buf);
508 }
509
510 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
511         return _fstati64(fd,buf);
512 }
513 INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
514 {
515         return _wstati64(fname,buf);
516 }
517 #else
518 INLINE int __hscore_stat(char *file, struct_stat *buf) {
519         return stat(file,buf);
520 }
521
522 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
523         return fstat(fd,buf);
524 }
525
526 INLINE int __hscore_lstat( const char *fname, struct stat *buf )
527 {
528 #if HAVE_LSTAT
529   return lstat(fname, buf);
530 #else
531   return stat(fname, buf);
532 #endif
533 }
534 #endif
535
536 #if HAVE_TERMIOS_H
537 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
538
539 INLINE void
540 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
541
542 INLINE unsigned char*
543 __hscore_ptr_c_cc( struct termios* ts )
544 { return (unsigned char*) &ts->c_cc; }
545
546 INLINE HsInt
547 __hscore_sizeof_termios( void )
548 {
549 #ifndef __MINGW32__
550   return sizeof(struct termios);
551 #else
552   return 0;
553 #endif
554 }
555 #endif
556
557 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
558 INLINE HsInt
559 __hscore_sizeof_sigset_t( void )
560 {
561   return sizeof(sigset_t);
562 }
563 #endif
564
565 INLINE int
566 __hscore_echo( void )
567 {
568 #ifdef ECHO
569   return ECHO;
570 #else
571   return 0;
572 #endif
573
574 }
575
576 INLINE int
577 __hscore_tcsanow( void )
578 {
579 #ifdef TCSANOW
580   return TCSANOW;
581 #else
582   return 0;
583 #endif
584
585 }
586
587 INLINE int
588 __hscore_icanon( void )
589 {
590 #ifdef ICANON
591   return ICANON;
592 #else
593   return 0;
594 #endif
595 }
596
597 INLINE int __hscore_vmin( void )
598 {
599 #ifdef VMIN
600   return VMIN;
601 #else
602   return 0;
603 #endif
604 }
605
606 INLINE int __hscore_vtime( void )
607 {
608 #ifdef VTIME
609   return VTIME;
610 #else
611   return 0;
612 #endif
613 }
614
615 INLINE int __hscore_sigttou( void )
616 {
617 #ifdef SIGTTOU
618   return SIGTTOU;
619 #else
620   return 0;
621 #endif
622 }
623
624 INLINE int __hscore_sig_block( void )
625 {
626 #ifdef SIG_BLOCK
627   return SIG_BLOCK;
628 #else
629   return 0;
630 #endif
631 }
632
633 INLINE int __hscore_sig_setmask( void )
634 {
635 #ifdef SIG_SETMASK
636   return SIG_SETMASK;
637 #else
638   return 0;
639 #endif
640 }
641
642 #ifndef __MINGW32__
643 INLINE size_t __hscore_sizeof_siginfo_t (void)
644 {
645     return sizeof(siginfo_t);
646 }
647 #endif
648
649 INLINE int
650 __hscore_f_getfl( void )
651 {
652 #ifdef F_GETFL
653   return F_GETFL;
654 #else
655   return 0;
656 #endif
657 }
658
659 INLINE int
660 __hscore_f_setfl( void )
661 {
662 #ifdef F_SETFL
663   return F_SETFL;
664 #else
665   return 0;
666 #endif
667 }
668
669 INLINE int
670 __hscore_f_setfd( void )
671 {
672 #ifdef F_SETFD
673   return F_SETFD;
674 #else
675   return 0;
676 #endif
677 }
678
679 INLINE long
680 __hscore_fd_cloexec( void )
681 {
682 #ifdef FD_CLOEXEC
683   return FD_CLOEXEC;
684 #else
685   return 0;
686 #endif
687 }
688
689 // defined in rts/RtsStartup.c.
690 extern void* __hscore_get_saved_termios(int fd);
691 extern void __hscore_set_saved_termios(int fd, void* ts);
692
693 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
694
695 #ifdef __MINGW32__
696 INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
697         if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
698           return _wsopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
699           // _O_NOINHERIT: see #2650
700         else
701           return _wsopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
702           // _O_NOINHERIT: see #2650
703 }
704 #else
705 INLINE int __hscore_open(char *file, int how, mode_t mode) {
706         return open(file,how,mode);
707 }
708 #endif
709
710 // These are wrapped because on some OSs (eg. Linux) they are
711 // macros which redirect to the 64-bit-off_t versions when large file
712 // support is enabled.
713 //
714 #if defined(__MINGW32__)
715 INLINE off64_t __hscore_lseek(int fd, off64_t off, int whence) {
716         return (_lseeki64(fd,off,whence));
717 }
718 #else
719 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
720         return (lseek(fd,off,whence));
721 }
722 #endif
723
724 // select-related stuff
725
726 #if !defined(__MINGW32__)
727 INLINE int  hsFD_SETSIZE(void) { return FD_SETSIZE; }
728 INLINE int  hsFD_ISSET(int fd, fd_set *fds) { return FD_ISSET(fd, fds); }
729 INLINE void hsFD_SET(int fd, fd_set *fds) { FD_SET(fd, fds); }
730 INLINE HsInt sizeof_fd_set(void) { return sizeof(fd_set); }
731 extern void hsFD_ZERO(fd_set *fds);
732 #endif
733
734 // gettimeofday()-related
735
736 #if !defined(__MINGW32__)
737
738 INLINE HsInt sizeofTimeVal(void) { return sizeof(struct timeval); }
739
740 INLINE HsWord64 getUSecOfDay(void)
741 {
742     struct timeval tv;
743     gettimeofday(&tv, (struct timezone *) NULL);
744     // Don't forget to cast *before* doing the arithmetic, otherwise
745     // the arithmetic happens at the type of tv_sec, which is probably
746     // only 'int'.
747     return ((HsWord64)tv.tv_sec * 1000000 + (HsWord64)tv.tv_usec);
748 }
749
750 INLINE void setTimevalTicks(struct timeval *p, HsWord64 usecs)
751 {
752     p->tv_sec  = usecs / 1000000;
753     p->tv_usec = usecs % 1000000;
754 }
755 #endif /* !defined(__MINGW32__) */
756
757 /* ToDo: write a feature test that doesn't assume 'environ' to
758  *    be in scope at link-time. */
759 extern char** environ;
760 INLINE char **__hscore_environ() { return environ; }
761
762 /* lossless conversions between pointers and integral types */
763 INLINE void *    __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
764 INLINE void *    __hscore_from_intptr (intptr_t n)  { return (void *)n; }
765 INLINE uintptr_t __hscore_to_uintptr  (void *p)     { return (uintptr_t)p; }
766 INLINE intptr_t  __hscore_to_intptr   (void *p)     { return (intptr_t)p; }
767
768 void errorBelch2(const char*s, char *t);
769 void debugBelch2(const char*s, char *t);
770
771 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
772
773 INLINE int fcntl_read(int fd, int cmd) {
774     return fcntl(fd, cmd);
775 }
776 INLINE int fcntl_write(int fd, int cmd, long arg) {
777     return fcntl(fd, cmd, arg);
778 }
779 INLINE int fcntl_lock(int fd, int cmd, struct flock *lock) {
780     return fcntl(fd, cmd, lock);
781 }
782
783 #endif
784
785 #endif /* __HSBASE_H__ */
786