Remove some antiquated C constructs
[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 #ifdef __NHC__
13 # include "Nhc98BaseConfig.h"
14 #else
15 #include "HsBaseConfig.h"
16 #endif
17
18 /* ultra-evil... */
19 #undef PACKAGE_BUGREPORT
20 #undef PACKAGE_NAME
21 #undef PACKAGE_STRING
22 #undef PACKAGE_TARNAME
23 #undef PACKAGE_VERSION
24
25 /* Needed to get the macro version of errno on some OSs (eg. Solaris).
26 We must do this, because these libs are only compiled once, but
27 must work in both single-threaded and multi-threaded programs. */
28 #define _REENTRANT 1
29
30 #include "HsFFI.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <math.h>
35
36 #if HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
39 #if HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #if HAVE_SYS_STAT_H
43 #include <sys/stat.h>
44 #endif
45 #if HAVE_FCNTL_H
46 # include <fcntl.h>
47 #endif
48 #if HAVE_TERMIOS_H
49 #include <termios.h>
50 #endif
51 #if HAVE_SIGNAL_H
52 #include <signal.h>
53 /* Ultra-ugly: OpenBSD uses broken macros for sigemptyset and sigfillset (missing casts) */
54 #if __OpenBSD__
55 #undef sigemptyset
56 #undef sigfillset
57 #endif
58 #endif
59 #if HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #if HAVE_STRING_H
63 #include <string.h>
64 #endif
65 #if HAVE_UTIME_H
66 #include <utime.h>
67 #endif
68 #if HAVE_SYS_UTSNAME_H
69 #include <sys/utsname.h>
70 #endif
71 #if HAVE_GETTIMEOFDAY
72 # if HAVE_SYS_TIME_H
73 # include <sys/time.h>
74 # endif
75 #elif HAVE_GETCLOCK
76 # if HAVE_SYS_TIMERS_H
77 # define POSIX_4D9 1
78 # include <sys/timers.h>
79 # endif
80 #endif
81 #if HAVE_TIME_H
82 #include <time.h>
83 #endif
84 #if HAVE_SYS_TIMEB_H
85 #include <sys/timeb.h>
86 #endif
87 #if HAVE_WINDOWS_H
88 #include <windows.h>
89 #endif
90 #if HAVE_SYS_TIMES_H
91 #include <sys/times.h>
92 #endif
93 #if HAVE_WINSOCK_H && defined(__MINGW32__)
94 #include <winsock.h>
95 #endif
96 #if HAVE_LIMITS_H
97 #include <limits.h>
98 #endif
99 #if HAVE_WCTYPE_H
100 #include <wctype.h>
101 #endif
102 #if HAVE_INTTYPES_H
103 # include <inttypes.h>
104 #elif HAVE_STDINT_H
105 # include <stdint.h>
106 #endif
107
108 #if !defined(__MINGW32__) && !defined(irix_HOST_OS)
109 # if HAVE_SYS_RESOURCE_H
110 # include <sys/resource.h>
111 # endif
112 #endif
113
114 #if !HAVE_GETRUSAGE && HAVE_SYS_SYSCALL_H
115 # include <sys/syscall.h>
116 # if defined(SYS_GETRUSAGE) /* hpux_HOST_OS */
117 # define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
118 # define HAVE_GETRUSAGE 1
119 # endif
120 #endif
121
122 /* For System */
123 #if HAVE_SYS_WAIT_H
124 #include <sys/wait.h>
125 #endif
126 #if HAVE_VFORK_H
127 #include <vfork.h>
128 #endif
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 INLINE functions.
156
157 These functions are given as inlines here for when compiling via C,
158 but we also generate static versions into the cbits library for
159 when compiling to native code.
160 -------------------------------------------------------------------------- */
161
162 #ifndef INLINE
163 # if defined(_MSC_VER)
164 # define INLINE extern __inline
165 # else
166 # define INLINE static inline
167 # endif
168 #endif
169
170 INLINE int __hscore_get_errno(void) { return errno; }
171 INLINE void __hscore_set_errno(int e) { errno = e; }
172
173 #if !defined(_MSC_VER)
174 INLINE int __hscore_s_isreg(mode_t m) { return S_ISREG(m); }
175 INLINE int __hscore_s_isdir(mode_t m) { return S_ISDIR(m); }
176 INLINE int __hscore_s_isfifo(mode_t m) { return S_ISFIFO(m); }
177 INLINE int __hscore_s_isblk(mode_t m) { return S_ISBLK(m); }
178 INLINE int __hscore_s_ischr(mode_t m) { return S_ISCHR(m); }
179 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
180 INLINE int __hscore_s_issock(mode_t m) { return S_ISSOCK(m); }
181 #endif
182 #endif
183
184 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
185 INLINE int
186 __hscore_sigemptyset( sigset_t *set )
187 { return sigemptyset(set); }
188
189 INLINE int
190 __hscore_sigfillset( sigset_t *set )
191 { return sigfillset(set); }
192
193 INLINE int
194 __hscore_sigaddset( sigset_t * set, int s )
195 { return sigaddset(set,s); }
196
197 INLINE int
198 __hscore_sigdelset( sigset_t * set, int s )
199 { return sigdelset(set,s); }
200
201 INLINE int
202 __hscore_sigismember( sigset_t * set, int s )
203 { return sigismember(set,s); }
204
205 INLINE int
206 __hscore_utime( const char *file, const struct utimbuf *timep )
207 { return utime(file,timep); }
208 #endif
209
210 // This is used by dph:Data.Array.Parallel.Arr.BUArr, and shouldn't be
211 INLINE void *
212 __hscore_memcpy_dst_off( char *dst, int dst_off, char *src, size_t sz )
213 { return memcpy(dst+dst_off, src, sz); }
214
215 INLINE void *
216 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
217 { return memcpy(dst, src+src_off, sz); }
218
219 INLINE HsInt
220 __hscore_bufsiz(void)
221 {
222 return BUFSIZ;
223 }
224
225 INLINE int
226 __hscore_seek_cur(void)
227 {
228 return SEEK_CUR;
229 }
230
231 INLINE int
232 __hscore_o_binary(void)
233 {
234 #if defined(_MSC_VER)
235 return O_BINARY;
236 #else
237 return CONST_O_BINARY;
238 #endif
239 }
240
241 INLINE int
242 __hscore_o_rdonly(void)
243 {
244 #ifdef O_RDONLY
245 return O_RDONLY;
246 #else
247 return 0;
248 #endif
249 }
250
251 INLINE int
252 __hscore_o_wronly( void )
253 {
254 #ifdef O_WRONLY
255 return O_WRONLY;
256 #else
257 return 0;
258 #endif
259 }
260
261 INLINE int
262 __hscore_o_rdwr( void )
263 {
264 #ifdef O_RDWR
265 return O_RDWR;
266 #else
267 return 0;
268 #endif
269 }
270
271 INLINE int
272 __hscore_o_append( void )
273 {
274 #ifdef O_APPEND
275 return O_APPEND;
276 #else
277 return 0;
278 #endif
279 }
280
281 INLINE int
282 __hscore_o_creat( void )
283 {
284 #ifdef O_CREAT
285 return O_CREAT;
286 #else
287 return 0;
288 #endif
289 }
290
291 INLINE int
292 __hscore_o_excl( void )
293 {
294 #ifdef O_EXCL
295 return O_EXCL;
296 #else
297 return 0;
298 #endif
299 }
300
301 INLINE int
302 __hscore_o_trunc( void )
303 {
304 #ifdef O_TRUNC
305 return O_TRUNC;
306 #else
307 return 0;
308 #endif
309 }
310
311 INLINE int
312 __hscore_o_noctty( void )
313 {
314 #ifdef O_NOCTTY
315 return O_NOCTTY;
316 #else
317 return 0;
318 #endif
319 }
320
321 INLINE int
322 __hscore_o_nonblock( void )
323 {
324 #ifdef O_NONBLOCK
325 return O_NONBLOCK;
326 #else
327 return 0;
328 #endif
329 }
330
331 INLINE int
332 __hscore_seek_set( void )
333 {
334 return SEEK_SET;
335 }
336
337 INLINE int
338 __hscore_seek_end( void )
339 {
340 return SEEK_END;
341 }
342
343 INLINE int
344 __hscore_ftruncate( int fd, off_t where )
345 {
346 #if defined(HAVE_FTRUNCATE)
347 return ftruncate(fd,where);
348 #elif defined(HAVE__CHSIZE)
349 return _chsize(fd,where);
350 #else
351 // ToDo: we should use _chsize_s() on Windows which allows a 64-bit
352 // offset, but it doesn't seem to be available from mingw at this time
353 // --SDM (01/2008)
354 #error at least ftruncate or _chsize functions are required to build
355 #endif
356 }
357
358 INLINE int
359 __hscore_setmode( int fd, HsBool toBin )
360 {
361 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
362 return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
363 #else
364 return 0;
365 #endif
366 }
367
368 #if __GLASGOW_HASKELL__
369
370 #endif /* __GLASGOW_HASKELL__ */
371
372 #if defined(__MINGW32__)
373 // We want the versions of stat/fstat/lseek that use 64-bit offsets,
374 // and you have to ask for those explicitly. Unfortunately there
375 // doesn't seem to be a 64-bit version of truncate/ftruncate, so while
376 // hFileSize and hSeek will work with large files, hSetFileSize will not.
377 typedef struct _stati64 struct_stat;
378 typedef off64_t stsize_t;
379 #else
380 typedef struct stat struct_stat;
381 typedef off_t stsize_t;
382 #endif
383
384 INLINE HsInt
385 __hscore_sizeof_stat( void )
386 {
387 return sizeof(struct_stat);
388 }
389
390 INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; }
391 INLINE stsize_t __hscore_st_size ( struct_stat* st ) { return st->st_size; }
392 #if !defined(_MSC_VER)
393 INLINE mode_t __hscore_st_mode ( struct_stat* st ) { return st->st_mode; }
394 INLINE dev_t __hscore_st_dev ( struct_stat* st ) { return st->st_dev; }
395 INLINE ino_t __hscore_st_ino ( struct_stat* st ) { return st->st_ino; }
396 #endif
397
398 #if defined(__MINGW32__)
399 INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
400 return _wstati64(file,buf);
401 }
402
403 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
404 return _fstati64(fd,buf);
405 }
406 INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
407 {
408 return _wstati64(fname,buf);
409 }
410 #else
411 INLINE int __hscore_stat(char *file, struct_stat *buf) {
412 return stat(file,buf);
413 }
414
415 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
416 return fstat(fd,buf);
417 }
418
419 INLINE int __hscore_lstat( const char *fname, struct stat *buf )
420 {
421 #if HAVE_LSTAT
422 return lstat(fname, buf);
423 #else
424 return stat(fname, buf);
425 #endif
426 }
427 #endif
428
429 #if HAVE_TERMIOS_H
430 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
431
432 INLINE void
433 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
434
435 INLINE unsigned char*
436 __hscore_ptr_c_cc( struct termios* ts )
437 { return (unsigned char*) &ts->c_cc; }
438
439 INLINE HsInt
440 __hscore_sizeof_termios( void )
441 {
442 #ifndef __MINGW32__
443 return sizeof(struct termios);
444 #else
445 return 0;
446 #endif
447 }
448 #endif
449
450 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
451 INLINE HsInt
452 __hscore_sizeof_sigset_t( void )
453 {
454 return sizeof(sigset_t);
455 }
456 #endif
457
458 INLINE int
459 __hscore_echo( void )
460 {
461 #ifdef ECHO
462 return ECHO;
463 #else
464 return 0;
465 #endif
466
467 }
468
469 INLINE int
470 __hscore_tcsanow( void )
471 {
472 #ifdef TCSANOW
473 return TCSANOW;
474 #else
475 return 0;
476 #endif
477
478 }
479
480 INLINE int
481 __hscore_icanon( void )
482 {
483 #ifdef ICANON
484 return ICANON;
485 #else
486 return 0;
487 #endif
488 }
489
490 INLINE int __hscore_vmin( void )
491 {
492 #ifdef VMIN
493 return VMIN;
494 #else
495 return 0;
496 #endif
497 }
498
499 INLINE int __hscore_vtime( void )
500 {
501 #ifdef VTIME
502 return VTIME;
503 #else
504 return 0;
505 #endif
506 }
507
508 INLINE int __hscore_sigttou( void )
509 {
510 #ifdef SIGTTOU
511 return SIGTTOU;
512 #else
513 return 0;
514 #endif
515 }
516
517 INLINE int __hscore_sig_block( void )
518 {
519 #ifdef SIG_BLOCK
520 return SIG_BLOCK;
521 #else
522 return 0;
523 #endif
524 }
525
526 INLINE int __hscore_sig_setmask( void )
527 {
528 #ifdef SIG_SETMASK
529 return SIG_SETMASK;
530 #else
531 return 0;
532 #endif
533 }
534
535 #ifndef __MINGW32__
536 INLINE size_t __hscore_sizeof_siginfo_t (void)
537 {
538 return sizeof(siginfo_t);
539 }
540 #endif
541
542 INLINE int
543 __hscore_f_getfl( void )
544 {
545 #ifdef F_GETFL
546 return F_GETFL;
547 #else
548 return 0;
549 #endif
550 }
551
552 INLINE int
553 __hscore_f_setfl( void )
554 {
555 #ifdef F_SETFL
556 return F_SETFL;
557 #else
558 return 0;
559 #endif
560 }
561
562 INLINE int
563 __hscore_f_setfd( void )
564 {
565 #ifdef F_SETFD
566 return F_SETFD;
567 #else
568 return 0;
569 #endif
570 }
571
572 INLINE long
573 __hscore_fd_cloexec( void )
574 {
575 #ifdef FD_CLOEXEC
576 return FD_CLOEXEC;
577 #else
578 return 0;
579 #endif
580 }
581
582 // defined in rts/RtsStartup.c.
583 extern void* __hscore_get_saved_termios(int fd);
584 extern void __hscore_set_saved_termios(int fd, void* ts);
585
586 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
587
588 #ifdef __MINGW32__
589 INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
590 if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
591 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
592 // _O_NOINHERIT: see #2650
593 else
594 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
595 // _O_NOINHERIT: see #2650
596 }
597 #else
598 INLINE int __hscore_open(char *file, int how, mode_t mode) {
599 return open(file,how,mode);
600 }
601 #endif
602
603 // These are wrapped because on some OSs (eg. Linux) they are
604 // macros which redirect to the 64-bit-off_t versions when large file
605 // support is enabled.
606 //
607 #if defined(__MINGW32__)
608 INLINE off64_t __hscore_lseek(int fd, off64_t off, int whence) {
609 return (_lseeki64(fd,off,whence));
610 }
611 #else
612 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
613 return (lseek(fd,off,whence));
614 }
615 #endif
616
617 // select-related stuff
618
619 #if !defined(__MINGW32__)
620 INLINE int hsFD_SETSIZE(void) { return FD_SETSIZE; }
621 INLINE int hsFD_ISSET(int fd, fd_set *fds) { return FD_ISSET(fd, fds); }
622 INLINE void hsFD_SET(int fd, fd_set *fds) { FD_SET(fd, fds); }
623 INLINE HsInt sizeof_fd_set(void) { return sizeof(fd_set); }
624 extern void hsFD_ZERO(fd_set *fds);
625 #endif
626
627 INLINE int __hscore_select(int nfds, fd_set *readfds, fd_set *writefds,
628 fd_set *exceptfds, struct timeval *timeout) {
629 return (select(nfds,readfds,writefds,exceptfds,timeout));
630 }
631
632 // gettimeofday()-related
633
634 #if !defined(__MINGW32__)
635
636 INLINE HsInt sizeofTimeVal(void) { return sizeof(struct timeval); }
637
638 INLINE HsWord64 getUSecOfDay(void)
639 {
640 struct timeval tv;
641 gettimeofday(&tv, (struct timezone *) NULL);
642 // Don't forget to cast *before* doing the arithmetic, otherwise
643 // the arithmetic happens at the type of tv_sec, which is probably
644 // only 'int'.
645 return ((HsWord64)tv.tv_sec * 1000000 + (HsWord64)tv.tv_usec);
646 }
647
648 INLINE void setTimevalTicks(struct timeval *p, HsWord64 usecs)
649 {
650 p->tv_sec = usecs / 1000000;
651 p->tv_usec = usecs % 1000000;
652 }
653 #endif /* !defined(__MINGW32__) */
654
655 #if darwin_HOST_OS
656 // You should not access _environ directly on Darwin in a bundle/shared library.
657 // See #2458 and http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man7/environ.7.html
658 #include <crt_externs.h>
659 INLINE char **__hscore_environ(void) { return *(_NSGetEnviron()); }
660 #else
661 /* ToDo: write a feature test that doesn't assume 'environ' to
662 * be in scope at link-time. */
663 extern char** environ;
664 INLINE char **__hscore_environ(void) { return environ; }
665 #endif
666
667 /* lossless conversions between pointers and integral types */
668 INLINE void * __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
669 INLINE void * __hscore_from_intptr (intptr_t n) { return (void *)n; }
670 INLINE uintptr_t __hscore_to_uintptr (void *p) { return (uintptr_t)p; }
671 INLINE intptr_t __hscore_to_intptr (void *p) { return (intptr_t)p; }
672
673 void errorBelch2(const char*s, char *t);
674 void debugBelch2(const char*s, char *t);
675
676 #if !defined(mingw32_HOST_OS) && !defined(__MINGW32__)
677
678 INLINE int fcntl_read(int fd, int cmd) {
679 return fcntl(fd, cmd);
680 }
681 INLINE int fcntl_write(int fd, int cmd, long arg) {
682 return fcntl(fd, cmd, arg);
683 }
684 INLINE int fcntl_lock(int fd, int cmd, struct flock *lock) {
685 return fcntl(fd, cmd, lock);
686 }
687
688 #endif
689
690 #endif /* __HSBASE_H__ */
691