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