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