cbbccbf458ebcba4e85f4f02d0e22521999fa967
[ghc.git] / libraries / base / 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_UTIME_H
62 #include <utime.h>
63 #endif
64 #if HAVE_SYS_UTSNAME_H
65 #include <sys/utsname.h>
66 #endif
67 #if HAVE_GETTIMEOFDAY
68 # if HAVE_SYS_TIME_H
69 # include <sys/time.h>
70 # endif
71 #elif HAVE_GETCLOCK
72 # if HAVE_SYS_TIMERS_H
73 # define POSIX_4D9 1
74 # include <sys/timers.h>
75 # endif
76 #endif
77 #if HAVE_TIME_H
78 #include <time.h>
79 #endif
80 #if HAVE_SYS_TIMEB_H && !defined(__FreeBSD__)
81 #include <sys/timeb.h>
82 #endif
83 #if HAVE_WINDOWS_H
84 #include <windows.h>
85 #endif
86 #if HAVE_SYS_TIMES_H
87 #include <sys/times.h>
88 #endif
89 #if HAVE_WINSOCK_H && defined(_WIN32)
90 #include <winsock.h>
91 #endif
92 #if HAVE_LIMITS_H
93 #include <limits.h>
94 #endif
95 #if HAVE_WCTYPE_H
96 #include <wctype.h>
97 #endif
98 #if HAVE_INTTYPES_H
99 # include <inttypes.h>
100 #elif HAVE_STDINT_H
101 # include <stdint.h>
102 #endif
103 #ifdef HAVE_CLOCK_GETTIME
104 # ifdef _POSIX_MONOTONIC_CLOCK
105 # define CLOCK_ID CLOCK_MONOTONIC
106 # else
107 # define CLOCK_ID CLOCK_REALTIME
108 # endif
109 #elif defined(darwin_HOST_OS)
110 # include <mach/mach.h>
111 # include <mach/mach_time.h>
112 #endif
113
114 #if !defined(_WIN32)
115 # if HAVE_SYS_RESOURCE_H
116 # include <sys/resource.h>
117 # endif
118 #endif
119
120 #if !HAVE_GETRUSAGE && HAVE_SYS_SYSCALL_H
121 # include <sys/syscall.h>
122 # if defined(SYS_GETRUSAGE) /* hpux_HOST_OS */
123 # define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
124 # define HAVE_GETRUSAGE 1
125 # endif
126 #endif
127
128 /* For System */
129 #if HAVE_SYS_WAIT_H
130 #include <sys/wait.h>
131 #endif
132 #if HAVE_VFORK_H
133 #include <vfork.h>
134 #endif
135 #include "WCsubst.h"
136
137 #if defined(_WIN32)
138 /* in Win32Utils.c */
139 extern void maperrno (void);
140 extern int maperrno_func(DWORD dwErrorCode);
141 extern HsWord64 getMonotonicUSec(void);
142 #endif
143
144 #if defined(_WIN32)
145 #include <io.h>
146 #include <fcntl.h>
147 #include <shlobj.h>
148 #include <share.h>
149 #endif
150
151 #if HAVE_SYS_SELECT_H
152 #include <sys/select.h>
153 #endif
154
155 /* in inputReady.c */
156 extern int fdReady(int fd, int write, int msecs, int isSock);
157
158 /* -----------------------------------------------------------------------------
159 INLINE functions.
160
161 These functions are given as inlines here for when compiling via C,
162 but we also generate static versions into the cbits library for
163 when compiling to native code.
164 -------------------------------------------------------------------------- */
165
166 #ifndef INLINE
167 # if defined(_MSC_VER)
168 # define INLINE extern __inline
169 # else
170 # define INLINE static inline
171 # endif
172 #endif
173
174 INLINE int __hscore_get_errno(void) { return errno; }
175 INLINE void __hscore_set_errno(int e) { errno = e; }
176
177 INLINE HsInt
178 __hscore_bufsiz(void)
179 {
180 return BUFSIZ;
181 }
182
183 INLINE int
184 __hscore_o_binary(void)
185 {
186 #if defined(_MSC_VER)
187 return O_BINARY;
188 #else
189 return CONST_O_BINARY;
190 #endif
191 }
192
193 INLINE int
194 __hscore_o_rdonly(void)
195 {
196 #ifdef O_RDONLY
197 return O_RDONLY;
198 #else
199 return 0;
200 #endif
201 }
202
203 INLINE int
204 __hscore_o_wronly( void )
205 {
206 #ifdef O_WRONLY
207 return O_WRONLY;
208 #else
209 return 0;
210 #endif
211 }
212
213 INLINE int
214 __hscore_o_rdwr( void )
215 {
216 #ifdef O_RDWR
217 return O_RDWR;
218 #else
219 return 0;
220 #endif
221 }
222
223 INLINE int
224 __hscore_o_append( void )
225 {
226 #ifdef O_APPEND
227 return O_APPEND;
228 #else
229 return 0;
230 #endif
231 }
232
233 INLINE int
234 __hscore_o_creat( void )
235 {
236 #ifdef O_CREAT
237 return O_CREAT;
238 #else
239 return 0;
240 #endif
241 }
242
243 INLINE int
244 __hscore_o_excl( void )
245 {
246 #ifdef O_EXCL
247 return O_EXCL;
248 #else
249 return 0;
250 #endif
251 }
252
253 INLINE int
254 __hscore_o_trunc( void )
255 {
256 #ifdef O_TRUNC
257 return O_TRUNC;
258 #else
259 return 0;
260 #endif
261 }
262
263 INLINE int
264 __hscore_o_noctty( void )
265 {
266 #ifdef O_NOCTTY
267 return O_NOCTTY;
268 #else
269 return 0;
270 #endif
271 }
272
273 INLINE int
274 __hscore_o_nonblock( void )
275 {
276 #ifdef O_NONBLOCK
277 return O_NONBLOCK;
278 #else
279 return 0;
280 #endif
281 }
282
283 INLINE int
284 __hscore_ftruncate( int fd, off_t where )
285 {
286 #if defined(HAVE_FTRUNCATE)
287 return ftruncate(fd,where);
288 #elif defined(HAVE__CHSIZE)
289 return _chsize(fd,where);
290 #else
291 // ToDo: we should use _chsize_s() on Windows which allows a 64-bit
292 // offset, but it doesn't seem to be available from mingw at this time
293 // --SDM (01/2008)
294 #error at least ftruncate or _chsize functions are required to build
295 #endif
296 }
297
298 INLINE int
299 __hscore_setmode( int fd, HsBool toBin )
300 {
301 #if defined(_WIN32)
302 return _setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
303 #else
304 return 0;
305 #endif
306 }
307
308 #if defined(_WIN32)
309 // We want the versions of stat/fstat/lseek that use 64-bit offsets,
310 // and you have to ask for those explicitly. Unfortunately there
311 // doesn't seem to be a 64-bit version of truncate/ftruncate, so while
312 // hFileSize and hSeek will work with large files, hSetFileSize will not.
313 typedef struct _stati64 struct_stat;
314 typedef off64_t stsize_t;
315 #else
316 typedef struct stat struct_stat;
317 typedef off_t stsize_t;
318 #endif
319
320 INLINE HsInt
321 __hscore_sizeof_stat( void )
322 {
323 return sizeof(struct_stat);
324 }
325
326 INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; }
327 INLINE stsize_t __hscore_st_size ( struct_stat* st ) { return st->st_size; }
328 #if !defined(_MSC_VER)
329 INLINE mode_t __hscore_st_mode ( struct_stat* st ) { return st->st_mode; }
330 INLINE dev_t __hscore_st_dev ( struct_stat* st ) { return st->st_dev; }
331 INLINE ino_t __hscore_st_ino ( struct_stat* st ) { return st->st_ino; }
332 #endif
333
334 #if defined(_WIN32)
335 INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
336 return _wstati64(file,buf);
337 }
338
339 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
340 return _fstati64(fd,buf);
341 }
342 INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
343 {
344 return _wstati64(fname,buf);
345 }
346 #else
347 INLINE int __hscore_stat(char *file, struct_stat *buf) {
348 return stat(file,buf);
349 }
350
351 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
352 return fstat(fd,buf);
353 }
354
355 INLINE int __hscore_lstat( const char *fname, struct stat *buf )
356 {
357 #if HAVE_LSTAT
358 return lstat(fname, buf);
359 #else
360 return stat(fname, buf);
361 #endif
362 }
363 #endif
364
365 #if HAVE_TERMIOS_H
366 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
367
368 INLINE void
369 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
370
371 INLINE unsigned char*
372 __hscore_ptr_c_cc( struct termios* ts )
373 { return (unsigned char*) &ts->c_cc; }
374
375 INLINE HsInt
376 __hscore_sizeof_termios( void )
377 {
378 #ifndef _WIN32
379 return sizeof(struct termios);
380 #else
381 return 0;
382 #endif
383 }
384 #endif
385
386 #if !defined(_WIN32)
387 INLINE HsInt
388 __hscore_sizeof_sigset_t( void )
389 {
390 return sizeof(sigset_t);
391 }
392 #endif
393
394 INLINE int
395 __hscore_echo( void )
396 {
397 #ifdef ECHO
398 return ECHO;
399 #else
400 return 0;
401 #endif
402
403 }
404
405 INLINE int
406 __hscore_tcsanow( void )
407 {
408 #ifdef TCSANOW
409 return TCSANOW;
410 #else
411 return 0;
412 #endif
413
414 }
415
416 INLINE int
417 __hscore_icanon( void )
418 {
419 #ifdef ICANON
420 return ICANON;
421 #else
422 return 0;
423 #endif
424 }
425
426 INLINE int __hscore_vmin( void )
427 {
428 #ifdef VMIN
429 return VMIN;
430 #else
431 return 0;
432 #endif
433 }
434
435 INLINE int __hscore_vtime( void )
436 {
437 #ifdef VTIME
438 return VTIME;
439 #else
440 return 0;
441 #endif
442 }
443
444 INLINE int __hscore_sigttou( void )
445 {
446 #ifdef SIGTTOU
447 return SIGTTOU;
448 #else
449 return 0;
450 #endif
451 }
452
453 INLINE int __hscore_sig_block( void )
454 {
455 #ifdef SIG_BLOCK
456 return SIG_BLOCK;
457 #else
458 return 0;
459 #endif
460 }
461
462 INLINE int __hscore_sig_setmask( void )
463 {
464 #ifdef SIG_SETMASK
465 return SIG_SETMASK;
466 #else
467 return 0;
468 #endif
469 }
470
471 #ifndef _WIN32
472 INLINE size_t __hscore_sizeof_siginfo_t (void)
473 {
474 return sizeof(siginfo_t);
475 }
476 #endif
477
478 INLINE int
479 __hscore_f_getfl( void )
480 {
481 #ifdef F_GETFL
482 return F_GETFL;
483 #else
484 return 0;
485 #endif
486 }
487
488 INLINE int
489 __hscore_f_setfl( void )
490 {
491 #ifdef F_SETFL
492 return F_SETFL;
493 #else
494 return 0;
495 #endif
496 }
497
498 INLINE int
499 __hscore_f_setfd( void )
500 {
501 #ifdef F_SETFD
502 return F_SETFD;
503 #else
504 return 0;
505 #endif
506 }
507
508 INLINE long
509 __hscore_fd_cloexec( void )
510 {
511 #ifdef FD_CLOEXEC
512 return FD_CLOEXEC;
513 #else
514 return 0;
515 #endif
516 }
517
518 // defined in rts/RtsStartup.c.
519 extern void* __hscore_get_saved_termios(int fd);
520 extern void __hscore_set_saved_termios(int fd, void* ts);
521
522 #ifdef _WIN32
523 INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
524 if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
525 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYNO,mode);
526 // _O_NOINHERIT: see #2650
527 else
528 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYNO,mode);
529 // _O_NOINHERIT: see #2650
530 }
531 #else
532 INLINE int __hscore_open(char *file, int how, mode_t mode) {
533 return open(file,how,mode);
534 }
535 #endif
536
537 #if darwin_HOST_OS
538 // You should not access _environ directly on Darwin in a bundle/shared library.
539 // See #2458 and http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man7/environ.7.html
540 #include <crt_externs.h>
541 INLINE char **__hscore_environ(void) { return *(_NSGetEnviron()); }
542 #else
543 /* ToDo: write a feature test that doesn't assume 'environ' to
544 * be in scope at link-time. */
545 extern char** environ;
546 INLINE char **__hscore_environ(void) { return environ; }
547 #endif
548
549 /* lossless conversions between pointers and integral types */
550 INLINE void * __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
551 INLINE void * __hscore_from_intptr (intptr_t n) { return (void *)n; }
552 INLINE uintptr_t __hscore_to_uintptr (void *p) { return (uintptr_t)p; }
553 INLINE intptr_t __hscore_to_intptr (void *p) { return (intptr_t)p; }
554
555 void errorBelch2(const char*s, char *t);
556 void debugBelch2(const char*s, char *t);
557
558 #endif /* __HSBASE_H__ */
559