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