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