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