reduce dependency on ghcconfig.h
[haskell-directory.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 #include "HsBaseConfig.h"
13
14 /* ultra-evil... */
15 #undef PACKAGE_BUGREPORT
16 #undef PACKAGE_NAME
17 #undef PACKAGE_STRING
18 #undef PACKAGE_TARNAME
19 #undef PACKAGE_VERSION
20
21 /* Needed to get the macro version of errno on some OSs (eg. Solaris).
22    We must do this, because these libs are only compiled once, but
23    must work in both single-threaded and multi-threaded programs. */
24 #define _REENTRANT 1
25
26 #include "HsFFI.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <math.h>
31
32 #if HAVE_SYS_TYPES_H
33 #include <sys/types.h>
34 #endif
35 #if HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 #if HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 #if HAVE_FCNTL_H
42 # include <fcntl.h>
43 #endif
44 #if HAVE_TERMIOS_H
45 #include <termios.h>
46 #endif
47 #if HAVE_SIGNAL_H
48 #include <signal.h>
49 /* Ultra-ugly: OpenBSD uses broken macros for sigemptyset and sigfillset (missing casts) */
50 #if __OpenBSD__
51 #undef sigemptyset
52 #undef sigfillset
53 #endif
54 #endif
55 #if HAVE_ERRNO_H
56 #include <errno.h>
57 #endif
58 #if HAVE_STRING_H
59 #include <string.h>
60 #endif
61 #if HAVE_DIRENT_H
62 #include <dirent.h>
63 #endif
64 #if HAVE_UTIME_H
65 #include <utime.h>
66 #endif
67 #if HAVE_SYS_UTSNAME_H
68 #include <sys/utsname.h>
69 #endif
70 #if HAVE_GETTIMEOFDAY
71 #  if HAVE_SYS_TIME_H
72 #   include <sys/time.h>
73 #  endif
74 #elif HAVE_GETCLOCK
75 # if HAVE_SYS_TIMERS_H
76 #  define POSIX_4D9 1
77 #  include <sys/timers.h>
78 # endif
79 #endif
80 #if HAVE_TIME_H
81 #include <time.h>
82 #endif
83 #if HAVE_SYS_TIMEB_H
84 #include <sys/timeb.h>
85 #endif
86 #if HAVE_WINDOWS_H
87 #include <windows.h>
88 #endif
89 #if HAVE_SYS_TIMES_H
90 #include <sys/times.h>
91 #endif
92 #if HAVE_WINSOCK_H && defined(mingw32_HOST_OS)
93 #include <winsock.h>
94 #endif
95 #if HAVE_LIMITS_H
96 #include <limits.h>
97 #endif
98 #if HAVE_WCTYPE_H
99 #include <wctype.h>
100 #endif
101 #if HAVE_INTTYPES_H
102 # include <inttypes.h>
103 #elif HAVE_STDINT_H
104 # include <stdint.h>
105 #endif
106
107 #if !defined(mingw32_HOST_OS) && !defined(irix_HOST_OS)
108 # if HAVE_SYS_RESOURCE_H
109 #  include <sys/resource.h>
110 # endif
111 #endif
112
113 #ifdef hpux_HOST_OS
114 #include <sys/syscall.h>
115 #define getrusage(a, b)  syscall(SYS_GETRUSAGE, a, b)
116 #define HAVE_GETRUSAGE
117 #endif
118
119 /* For System */
120 #if HAVE_SYS_WAIT_H
121 #include <sys/wait.h>
122 #endif
123 #if HAVE_VFORK_H
124 #include <vfork.h>
125 #endif
126 #include "lockFile.h"
127 #include "dirUtils.h"
128 #include "WCsubst.h"
129
130 #include "runProcess.h"
131
132 #if defined(mingw32_HOST_OS)
133 #include <io.h>
134 #include <fcntl.h>
135 #include "timeUtils.h"
136 #include <shlobj.h>
137 #include <share.h>
138 #endif
139
140 #if HAVE_SYS_SELECT_H
141 #include <sys/select.h>
142 #endif
143
144 /* in inputReady.c */
145 int inputReady(int fd, int msecs, int isSock);
146
147 /* in Signals.c */
148 extern HsInt nocldstop;
149
150 #if !defined(mingw32_HOST_OS)
151 /* in execvpe.c */
152 extern int execvpe(char *name, char *const argv[], char **envp);
153 extern void pPrPr_disableITimers (void);
154 #endif
155
156 /* -----------------------------------------------------------------------------
157    64-bit operations, defined in longlong.c
158    -------------------------------------------------------------------------- */
159
160 #ifdef SUPPORT_LONG_LONGS
161
162 StgInt stg_gtWord64 (StgWord64, StgWord64);
163 StgInt stg_geWord64 (StgWord64, StgWord64);
164 StgInt stg_eqWord64 (StgWord64, StgWord64);
165 StgInt stg_neWord64 (StgWord64, StgWord64);
166 StgInt stg_ltWord64 (StgWord64, StgWord64);
167 StgInt stg_leWord64 (StgWord64, StgWord64);
168
169 StgInt stg_gtInt64 (StgInt64, StgInt64);
170 StgInt stg_geInt64 (StgInt64, StgInt64);
171 StgInt stg_eqInt64 (StgInt64, StgInt64);
172 StgInt stg_neInt64 (StgInt64, StgInt64);
173 StgInt stg_ltInt64 (StgInt64, StgInt64);
174 StgInt stg_leInt64 (StgInt64, StgInt64);
175
176 StgWord64 stg_remWord64  (StgWord64, StgWord64);
177 StgWord64 stg_quotWord64 (StgWord64, StgWord64);
178
179 StgInt64 stg_remInt64    (StgInt64, StgInt64);
180 StgInt64 stg_quotInt64   (StgInt64, StgInt64);
181 StgInt64 stg_negateInt64 (StgInt64);
182 StgInt64 stg_plusInt64   (StgInt64, StgInt64);
183 StgInt64 stg_minusInt64  (StgInt64, StgInt64);
184 StgInt64 stg_timesInt64  (StgInt64, StgInt64);
185
186 StgWord64 stg_and64  (StgWord64, StgWord64);
187 StgWord64 stg_or64   (StgWord64, StgWord64);
188 StgWord64 stg_xor64  (StgWord64, StgWord64);
189 StgWord64 stg_not64  (StgWord64);
190
191 StgWord64 stg_uncheckedShiftL64   (StgWord64, StgInt);
192 StgWord64 stg_uncheckedShiftRL64  (StgWord64, StgInt);
193 StgInt64  stg_uncheckedIShiftL64  (StgInt64, StgInt);
194 StgInt64  stg_uncheckedIShiftRL64 (StgInt64, StgInt);
195 StgInt64  stg_uncheckedIShiftRA64 (StgInt64, StgInt);
196
197 StgInt64  stg_intToInt64    (StgInt);
198 StgInt    stg_int64ToInt    (StgInt64);
199 StgWord64 stg_int64ToWord64 (StgInt64);
200
201 StgWord64 stg_wordToWord64  (StgWord);
202 StgWord   stg_word64ToWord  (StgWord64);
203 StgInt64  stg_word64ToInt64 (StgWord64);
204
205 StgInt64  stg_integerToInt64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da);
206 StgWord64 stg_integerToWord64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da);
207
208 #endif /* SUPPORT_LONG_LONGS */
209
210 /* -----------------------------------------------------------------------------
211    INLINE functions.
212
213    These functions are given as inlines here for when compiling via C,
214    but we also generate static versions into the cbits library for
215    when compiling to native code.
216    -------------------------------------------------------------------------- */
217
218 #ifndef INLINE
219 # if defined(_MSC_VER)
220 #  define INLINE extern __inline
221 # elif defined(__GNUC__)
222 #  define INLINE extern inline
223 # else
224 #  define INLINE inline
225 # endif
226 #endif
227
228 INLINE int __hscore_get_errno(void) { return errno; }
229 INLINE void __hscore_set_errno(int e) { errno = e; }
230
231 #if !defined(_MSC_VER)
232 INLINE int __hscore_s_isreg(m)  { return S_ISREG(m);  }
233 INLINE int __hscore_s_isdir(m)  { return S_ISDIR(m);  }
234 INLINE int __hscore_s_isfifo(m) { return S_ISFIFO(m); }
235 INLINE int __hscore_s_isblk(m)  { return S_ISBLK(m);  }
236 INLINE int __hscore_s_ischr(m)  { return S_ISCHR(m);  }
237 #ifdef S_ISSOCK
238 INLINE int __hscore_s_issock(m) { return S_ISSOCK(m); }
239 #endif
240 #endif
241
242 #if !defined(mingw32_HOST_OS) && !defined(_MSC_VER)
243 INLINE int
244 __hscore_sigemptyset( sigset_t *set )
245 { return sigemptyset(set); }
246
247 INLINE int
248 __hscore_sigfillset( sigset_t *set )
249 { return sigfillset(set); }
250
251 INLINE int
252 __hscore_sigaddset( sigset_t * set, int s )
253 { return sigaddset(set,s); }
254
255 INLINE int
256 __hscore_sigdelset( sigset_t * set, int s )
257 { return sigdelset(set,s); }
258
259 INLINE int
260 __hscore_sigismember( sigset_t * set, int s )
261 { return sigismember(set,s); }
262 #endif
263
264 INLINE void *
265 __hscore_memcpy_dst_off( char *dst, int dst_off, char *src, size_t sz )
266 { return memcpy(dst+dst_off, src, sz); }
267
268 INLINE void *
269 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
270 { return memcpy(dst, src+src_off, sz); }
271
272 INLINE HsBool
273 __hscore_supportsTextMode()
274 {
275 #if defined(mingw32_HOST_OS)
276   return HS_BOOL_FALSE;
277 #else
278   return HS_BOOL_TRUE;
279 #endif
280 }
281
282 INLINE HsInt
283 __hscore_bufsiz()
284 {
285   return BUFSIZ;
286 }
287
288 INLINE HsInt
289 __hscore_seek_cur()
290 {
291   return SEEK_CUR;
292 }
293
294 INLINE HsInt
295 __hscore_o_binary()
296 {
297 #if defined(_MSC_VER)
298   return O_BINARY;
299 #else
300   return CONST_O_BINARY;
301 #endif
302 }
303
304 INLINE int
305 __hscore_o_rdonly()
306 {
307 #ifdef O_RDONLY
308   return O_RDONLY;
309 #else
310   return 0;
311 #endif
312 }
313
314 INLINE int
315 __hscore_o_wronly( void )
316 {
317 #ifdef O_WRONLY
318   return O_WRONLY;
319 #else
320   return 0;
321 #endif
322 }
323
324 INLINE int
325 __hscore_o_rdwr( void )
326 {
327 #ifdef O_RDWR
328   return O_RDWR;
329 #else
330   return 0;
331 #endif
332 }
333
334 INLINE int
335 __hscore_o_append( void )
336 {
337 #ifdef O_APPEND
338   return O_APPEND;
339 #else
340   return 0;
341 #endif
342 }
343
344 INLINE int
345 __hscore_o_creat( void )
346 {
347 #ifdef O_CREAT
348   return O_CREAT;
349 #else
350   return 0;
351 #endif
352 }
353
354 INLINE int
355 __hscore_o_excl( void )
356 {
357 #ifdef O_EXCL
358   return O_EXCL;
359 #else
360   return 0;
361 #endif
362 }
363
364 INLINE int
365 __hscore_o_trunc( void )
366 {
367 #ifdef O_TRUNC
368   return O_TRUNC;
369 #else
370   return 0;
371 #endif
372 }
373
374 INLINE int
375 __hscore_o_noctty( void )
376 {
377 #ifdef O_NOCTTY
378   return O_NOCTTY;
379 #else
380   return 0;
381 #endif
382 }
383
384 INLINE int
385 __hscore_o_nonblock( void )
386 {
387 #ifdef O_NONBLOCK
388   return O_NONBLOCK;
389 #else
390   return 0;
391 #endif
392 }
393
394 INLINE HsInt
395 __hscore_seek_set( void )
396 {
397   return SEEK_SET;
398 }
399
400 INLINE HsInt
401 __hscore_seek_end( void )
402 {
403   return SEEK_END;
404 }
405
406 INLINE int
407 __hscore_ftruncate( int fd, off_t where )
408 {
409 #if defined(HAVE_FTRUNCATE)
410   return ftruncate(fd,where);
411 #elif defined(HAVE__CHSIZE)
412   return _chsize(fd,where);
413 #else
414 #error at least ftruncate or _chsize functions are required to build
415 #endif
416 }
417
418 INLINE HsInt
419 __hscore_setmode( HsInt fd, HsBool toBin )
420 {
421 #if defined(mingw32_HOST_OS) || defined(_MSC_VER)
422   return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
423 #else
424   return 0;
425 #endif
426 }
427
428 #if __GLASGOW_HASKELL__
429
430 INLINE HsInt
431 __hscore_PrelHandle_write( HsInt fd, HsAddr ptr, HsInt off, int sz )
432 {
433   return write(fd,(char *)ptr + off, sz);
434 }
435
436 INLINE HsInt
437 __hscore_PrelHandle_read( HsInt fd, HsAddr ptr, HsInt off, int sz )
438 {
439   return read(fd,(char *)ptr + off, sz);
440
441 }
442
443 #if defined(mingw32_HOST_OS) || defined(_MSC_VER)
444 INLINE HsInt
445 __hscore_PrelHandle_send( HsInt fd, HsAddr ptr, HsInt off, int sz )
446 {
447     return send(fd,(char *)ptr + off, sz, 0);
448 }
449
450 INLINE HsInt
451 __hscore_PrelHandle_recv( HsInt fd, HsAddr ptr, HsInt off, int sz )
452 {
453     return recv(fd,(char *)ptr + off, sz, 0);
454 }
455 #endif
456
457 #endif /* __GLASGOW_HASKELL__ */
458
459 INLINE HsInt
460 __hscore_mkdir( HsAddr pathName, HsInt mode )
461 {
462 #if defined(mingw32_HOST_OS) || defined(_MSC_VER)
463   return mkdir(pathName);
464 #else
465   return mkdir(pathName,mode);
466 #endif
467 }
468
469 INLINE HsInt
470 __hscore_lstat( HsAddr fname, HsAddr st )
471 {
472 #if HAVE_LSTAT
473   return lstat((const char*)fname, (struct stat*)st);
474 #else
475   return stat((const char*)fname, (struct stat*)st);
476 #endif
477 }
478
479 #ifdef PATH_MAX
480 /* A size that will contain many path names, but not necessarily all
481  * (PATH_MAX is not defined on systems with unlimited path length,
482  * e.g. the Hurd).
483  */
484 INLINE HsInt __hscore_long_path_size() { return PATH_MAX; }
485 #else
486 INLINE HsInt __hscore_long_path_size() { return 4096; }
487 #endif
488
489 #ifdef R_OK
490 INLINE mode_t __hscore_R_OK() { return R_OK; }
491 #endif
492 #ifdef W_OK
493 INLINE mode_t __hscore_W_OK() { return W_OK; }
494 #endif
495 #ifdef X_OK
496 INLINE mode_t __hscore_X_OK() { return X_OK; }
497 #endif
498
499 #ifdef S_IRUSR
500 INLINE mode_t __hscore_S_IRUSR() { return S_IRUSR; }
501 #endif
502 #ifdef S_IWUSR
503 INLINE mode_t __hscore_S_IWUSR() { return S_IWUSR; }
504 #endif
505 #ifdef S_IXUSR
506 INLINE mode_t __hscore_S_IXUSR() { return S_IXUSR; }
507 #endif
508
509 INLINE HsAddr
510 __hscore_d_name( struct dirent* d )
511 {
512   return (HsAddr)(d->d_name);
513 }
514
515 INLINE HsInt
516 __hscore_end_of_dir( void )
517 {
518   return READDIR_ERRNO_EOF;
519 }
520
521 INLINE void
522 __hscore_free_dirent(HsAddr dEnt)
523 {
524 #if HAVE_READDIR_R
525   free(dEnt);
526 #endif
527 }
528
529 INLINE HsInt
530 __hscore_sizeof_stat( void )
531 {
532   return sizeof(struct stat);
533 }
534
535 INLINE time_t __hscore_st_mtime ( struct stat* st ) { return st->st_mtime; }
536 INLINE off_t  __hscore_st_size  ( struct stat* st ) { return st->st_size; }
537 #if !defined(_MSC_VER)
538 INLINE mode_t __hscore_st_mode  ( struct stat* st ) { return st->st_mode; }
539 #endif
540
541 #if HAVE_TERMIOS_H
542 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
543
544 INLINE void
545 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
546
547 INLINE unsigned char*
548 __hscore_ptr_c_cc( struct termios* ts )
549 { return (unsigned char*) &ts->c_cc; }
550
551 INLINE HsInt
552 __hscore_sizeof_termios( void )
553 {
554 #ifndef mingw32_HOST_OS
555   return sizeof(struct termios);
556 #else
557   return 0;
558 #endif
559 }
560 #endif
561
562 #if !defined(mingw32_HOST_OS) && !defined(_MSC_VER)
563 INLINE HsInt
564 __hscore_sizeof_sigset_t( void )
565 {
566   return sizeof(sigset_t);
567 }
568 #endif
569
570 INLINE int
571 __hscore_echo( void )
572 {
573 #ifdef ECHO
574   return ECHO;
575 #else
576   return 0;
577 #endif
578
579 }
580
581 INLINE int
582 __hscore_tcsanow( void )
583 {
584 #ifdef TCSANOW
585   return TCSANOW;
586 #else
587   return 0;
588 #endif
589
590 }
591
592 INLINE int
593 __hscore_icanon( void )
594 {
595 #ifdef ICANON
596   return ICANON;
597 #else
598   return 0;
599 #endif
600 }
601
602 INLINE int __hscore_vmin( void )
603 {
604 #ifdef VMIN
605   return VMIN;
606 #else
607   return 0;
608 #endif
609 }
610
611 INLINE int __hscore_vtime( void )
612 {
613 #ifdef VTIME
614   return VTIME;
615 #else
616   return 0;
617 #endif
618 }
619
620 INLINE int __hscore_sigttou( void )
621 {
622 #ifdef SIGTTOU
623   return SIGTTOU;
624 #else
625   return 0;
626 #endif
627 }
628
629 INLINE int __hscore_sig_block( void )
630 {
631 #ifdef SIG_BLOCK
632   return SIG_BLOCK;
633 #else
634   return 0;
635 #endif
636 }
637
638 INLINE int __hscore_sig_setmask( void )
639 {
640 #ifdef SIG_SETMASK
641   return SIG_SETMASK;
642 #else
643   return 0;
644 #endif
645 }
646
647 INLINE int
648 __hscore_f_getfl( void )
649 {
650 #ifdef F_GETFL
651   return F_GETFL;
652 #else
653   return 0;
654 #endif
655 }
656
657 INLINE int
658 __hscore_f_setfl( void )
659 {
660 #ifdef F_SETFL
661   return F_SETFL;
662 #else
663   return 0;
664 #endif
665 }
666
667 // defined in rts/RtsStartup.c.
668 extern void* __hscore_get_saved_termios(int fd);
669 extern void __hscore_set_saved_termios(int fd, void* ts);
670
671 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
672
673 INLINE int __hscore_open(char *file, int how, mode_t mode) {
674 #ifdef mingw32_HOST_OS
675         if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
676           return _sopen(file,how,_SH_DENYRW,mode);
677         else
678           return _sopen(file,how,_SH_DENYWR,mode);
679 #else
680         return open(file,how,mode);
681 #endif
682 }
683
684 // These are wrapped because on some OSs (eg. Linux) they are
685 // macros which redirect to the 64-bit-off_t versions when large file
686 // support is enabled.
687 //
688 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
689         return (lseek(fd,off,whence));
690 }
691
692 INLINE int __hscore_stat(char *file, struct stat *buf) {
693         return (stat(file,buf));
694 }
695
696 INLINE int __hscore_fstat(int fd, struct stat *buf) {
697         return (fstat(fd,buf));
698 }
699
700 // select-related stuff
701
702 #if !defined(mingw32_HOST_OS)
703 INLINE int  hsFD_SETSIZE(void) { return FD_SETSIZE; }
704 INLINE void hsFD_CLR(int fd, fd_set *fds) { FD_CLR(fd, fds); }
705 INLINE int  hsFD_ISSET(int fd, fd_set *fds) { return FD_ISSET(fd, fds); }
706 INLINE void hsFD_SET(int fd, fd_set *fds) { FD_SET(fd, fds); }
707 INLINE int  sizeof_fd_set(void) { return sizeof(fd_set); }
708 extern void hsFD_ZERO(fd_set *fds);
709 #endif
710
711 // gettimeofday()-related
712
713 #if !defined(mingw32_HOST_OS)
714 #define TICK_FREQ  50
715
716 INLINE HsInt sizeofTimeVal(void) { return sizeof(struct timeval); }
717
718 INLINE HsInt getTicksOfDay(void)
719 {
720     struct timeval tv;
721     gettimeofday(&tv, (struct timezone *) NULL);
722     return (tv.tv_sec * TICK_FREQ +
723             tv.tv_usec * TICK_FREQ / 1000000);
724 }
725
726 INLINE void setTimevalTicks(struct timeval *p, HsInt ticks)
727 {
728     p->tv_sec  = ticks / TICK_FREQ;
729     p->tv_usec = (ticks % TICK_FREQ) * (1000000 / TICK_FREQ);
730 }
731 #endif /* !defined(mingw32_HOST_OS) */
732
733 // Directory-related
734
735 #if defined(mingw32_HOST_OS)
736
737 /* Make sure we've got the reqd CSIDL_ constants in scope;
738  * w32api header files are lagging a bit in defining the full set.
739  */
740 #if !defined(CSIDL_APPDATA)
741 #define CSIDL_APPDATA 0x001a
742 #endif
743 #if !defined(CSIDL_PERSONAL)
744 #define CSIDL_PERSONAL 0x0005
745 #endif
746 #if !defined(CSIDL_PROFILE)
747 #define CSIDL_PROFILE 0x0028
748 #endif
749 #if !defined(CSIDL_WINDOWS)
750 #define CSIDL_WINDOWS 0x0024
751 #endif
752
753 INLINE int __hscore_CSIDL_PROFILE()  { return CSIDL_PROFILE;  }
754 INLINE int __hscore_CSIDL_APPDATA()  { return CSIDL_APPDATA;  }
755 INLINE int __hscore_CSIDL_WINDOWS()  { return CSIDL_WINDOWS;  }
756 INLINE int __hscore_CSIDL_PERSONAL() { return CSIDL_PERSONAL; }
757 #endif
758
759 #if defined(mingw32_HOST_OS)
760 INLINE unsigned int __hscore_get_osver(void) { return _osver; }
761 #endif
762
763 /* ToDo: write a feature test that doesn't assume 'environ' to
764  *    be in scope at link-time. */
765 extern char** environ;
766 INLINE char **__hscore_environ() { return environ; }
767
768 /* lossless conversions between pointers and integral types */
769 INLINE void *    __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
770 INLINE void *    __hscore_from_intptr (intptr_t n)  { return (void *)n; }
771 INLINE uintptr_t __hscore_to_uintptr  (void *p)     { return (uintptr_t)p; }
772 INLINE intptr_t  __hscore_to_intptr   (void *p)     { return (intptr_t)p; }
773
774 #endif /* __HSBASE_H__ */
775