1 /* -----------------------------------------------------------------------------
3 * (c) The University of Glasgow 2001-2004
5 * Definitions for package `base' which are visible in Haskell land.
7 * ---------------------------------------------------------------------------*/
12 #include "HsBaseConfig.h"
15 #undef PACKAGE_BUGREPORT
18 #undef PACKAGE_TARNAME
19 #undef PACKAGE_VERSION
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. */
33 #include <sys/types.h>
49 /* Ultra-ugly: OpenBSD uses broken macros for sigemptyset and sigfillset (missing casts) */
67 #if HAVE_SYS_UTSNAME_H
68 #include <sys/utsname.h>
72 # include <sys/time.h>
75 # if HAVE_SYS_TIMERS_H
77 # include <sys/timers.h>
84 #include <sys/timeb.h>
90 #include <sys/times.h>
92 #if HAVE_WINSOCK_H && defined(__MINGW32__)
102 # include <inttypes.h>
107 #if !defined(__MINGW32__) && !defined(irix_HOST_OS)
108 # if HAVE_SYS_RESOURCE_H
109 # include <sys/resource.h>
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
123 #include <sys/wait.h>
128 #include "lockFile.h"
129 #include "dirUtils.h"
132 #include "runProcess.h"
134 #if defined(__MINGW32__)
135 /* in Win32Utils.c */
136 extern void maperrno (void);
137 extern HsWord64 getUSecOfDay(void);
140 #if defined(__MINGW32__)
143 #include "timeUtils.h"
148 #if HAVE_SYS_SELECT_H
149 #include <sys/select.h>
152 /* in inputReady.c */
153 int inputReady(int fd, int msecs, int isSock);
156 extern HsInt nocldstop;
158 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
160 extern int execvpe(char *name, char *const argv[], char **envp);
161 extern void pPrPr_disableITimers (void);
164 /* -----------------------------------------------------------------------------
165 64-bit operations, defined in longlong.c
166 -------------------------------------------------------------------------- */
168 #ifdef SUPPORT_LONG_LONGS
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);
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);
184 StgWord64 stg_remWord64 (StgWord64, StgWord64);
185 StgWord64 stg_quotWord64 (StgWord64, StgWord64);
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);
194 StgWord64 stg_and64 (StgWord64, StgWord64);
195 StgWord64 stg_or64 (StgWord64, StgWord64);
196 StgWord64 stg_xor64 (StgWord64, StgWord64);
197 StgWord64 stg_not64 (StgWord64);
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);
205 StgInt64 stg_intToInt64 (StgInt);
206 StgInt stg_int64ToInt (StgInt64);
207 StgWord64 stg_int64ToWord64 (StgInt64);
209 StgWord64 stg_wordToWord64 (StgWord);
210 StgWord stg_word64ToWord (StgWord64);
211 StgInt64 stg_word64ToInt64 (StgWord64);
213 StgInt64 stg_integerToInt64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da);
214 StgWord64 stg_integerToWord64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da);
216 #endif /* SUPPORT_LONG_LONGS */
218 /* -----------------------------------------------------------------------------
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 -------------------------------------------------------------------------- */
227 # if defined(_MSC_VER)
228 # define INLINE extern __inline
230 # define INLINE static inline
234 INLINE int __hscore_get_errno(void) { return errno; }
235 INLINE void __hscore_set_errno(int e) { errno = e; }
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); }
244 INLINE int __hscore_s_issock(m) { return S_ISSOCK(m); }
248 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
250 __hscore_sigemptyset( sigset_t *set )
251 { return sigemptyset(set); }
254 __hscore_sigfillset( sigset_t *set )
255 { return sigfillset(set); }
258 __hscore_sigaddset( sigset_t * set, int s )
259 { return sigaddset(set,s); }
262 __hscore_sigdelset( sigset_t * set, int s )
263 { return sigdelset(set,s); }
266 __hscore_sigismember( sigset_t * set, int s )
267 { return sigismember(set,s); }
271 __hscore_memcpy_dst_off( char *dst, int dst_off, char *src, size_t sz )
272 { return memcpy(dst+dst_off, src, sz); }
275 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
276 { return memcpy(dst, src+src_off, sz); }
279 __hscore_supportsTextMode()
281 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
282 return HS_BOOL_FALSE;
303 #if defined(_MSC_VER)
306 return CONST_O_BINARY;
321 __hscore_o_wronly( void )
331 __hscore_o_rdwr( void )
341 __hscore_o_append( void )
351 __hscore_o_creat( void )
361 __hscore_o_excl( void )
371 __hscore_o_trunc( void )
381 __hscore_o_noctty( void )
391 __hscore_o_nonblock( void )
401 __hscore_seek_set( void )
407 __hscore_seek_end( void )
413 __hscore_ftruncate( int fd, off_t where )
415 #if defined(HAVE_FTRUNCATE)
416 return ftruncate(fd,where);
417 #elif defined(HAVE__CHSIZE)
418 return _chsize(fd,where);
420 #error at least ftruncate or _chsize functions are required to build
425 __hscore_setmode( HsInt fd, HsBool toBin )
427 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
428 return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
434 #if __GLASGOW_HASKELL__
437 __hscore_PrelHandle_write( HsInt fd, HsAddr ptr, HsInt off, int sz )
439 return write(fd,(char *)ptr + off, sz);
443 __hscore_PrelHandle_read( HsInt fd, HsAddr ptr, HsInt off, int sz )
445 return read(fd,(char *)ptr + off, sz);
449 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
451 __hscore_PrelHandle_send( HsInt fd, HsAddr ptr, HsInt off, int sz )
453 return send(fd,(char *)ptr + off, sz, 0);
457 __hscore_PrelHandle_recv( HsInt fd, HsAddr ptr, HsInt off, int sz )
459 return recv(fd,(char *)ptr + off, sz, 0);
463 #endif /* __GLASGOW_HASKELL__ */
466 __hscore_mkdir( HsAddr pathName, HsInt mode )
468 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
469 return mkdir(pathName);
471 return mkdir(pathName,mode);
476 __hscore_lstat( HsAddr fname, HsAddr st )
479 return lstat((const char*)fname, (struct stat*)st);
481 return stat((const char*)fname, (struct stat*)st);
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,
490 INLINE HsInt __hscore_long_path_size() { return PATH_MAX; }
492 INLINE HsInt __hscore_long_path_size() { return 4096; }
496 INLINE mode_t __hscore_R_OK() { return R_OK; }
499 INLINE mode_t __hscore_W_OK() { return W_OK; }
502 INLINE mode_t __hscore_X_OK() { return X_OK; }
506 INLINE mode_t __hscore_S_IRUSR() { return S_IRUSR; }
509 INLINE mode_t __hscore_S_IWUSR() { return S_IWUSR; }
512 INLINE mode_t __hscore_S_IXUSR() { return S_IXUSR; }
516 __hscore_d_name( struct dirent* d )
518 return (HsAddr)(d->d_name);
522 __hscore_end_of_dir( void )
524 return READDIR_ERRNO_EOF;
528 __hscore_free_dirent(HsAddr dEnt)
536 __hscore_sizeof_stat( void )
538 return sizeof(struct stat);
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; }
548 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
551 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
553 INLINE unsigned char*
554 __hscore_ptr_c_cc( struct termios* ts )
555 { return (unsigned char*) &ts->c_cc; }
558 __hscore_sizeof_termios( void )
561 return sizeof(struct termios);
568 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
570 __hscore_sizeof_sigset_t( void )
572 return sizeof(sigset_t);
577 __hscore_echo( void )
588 __hscore_tcsanow( void )
599 __hscore_icanon( void )
608 INLINE int __hscore_vmin( void )
617 INLINE int __hscore_vtime( void )
626 INLINE int __hscore_sigttou( void )
635 INLINE int __hscore_sig_block( void )
644 INLINE int __hscore_sig_setmask( void )
654 __hscore_f_getfl( void )
664 __hscore_f_setfl( void )
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);
677 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
679 INLINE int __hscore_open(char *file, int how, mode_t mode) {
681 if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
682 return _sopen(file,how,_SH_DENYRW,mode);
684 return _sopen(file,how,_SH_DENYWR,mode);
686 return open(file,how,mode);
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.
694 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
695 return (lseek(fd,off,whence));
698 INLINE int __hscore_stat(char *file, struct stat *buf) {
699 return (stat(file,buf));
702 INLINE int __hscore_fstat(int fd, struct stat *buf) {
703 return (fstat(fd,buf));
706 // select-related stuff
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);
717 // gettimeofday()-related
719 #if !defined(__MINGW32__)
721 INLINE HsInt sizeofTimeVal(void) { return sizeof(struct timeval); }
723 INLINE HsWord64 getUSecOfDay(void)
726 gettimeofday(&tv, (struct timezone *) NULL);
727 // Don't forget to cast *before* doing the arithmetic, otherwise
728 // the arithmetic happens at the type of tv_sec, which is probably
730 return ((HsWord64)tv.tv_sec * 1000000 + (HsWord64)tv.tv_usec);
733 INLINE void setTimevalTicks(struct timeval *p, HsWord64 usecs)
735 p->tv_sec = usecs / 1000000;
736 p->tv_usec = usecs % 1000000;
738 #endif /* !defined(__MINGW32__) */
742 #if defined(__MINGW32__)
744 /* Make sure we've got the reqd CSIDL_ constants in scope;
745 * w32api header files are lagging a bit in defining the full set.
747 #if !defined(CSIDL_APPDATA)
748 #define CSIDL_APPDATA 0x001a
750 #if !defined(CSIDL_PERSONAL)
751 #define CSIDL_PERSONAL 0x0005
753 #if !defined(CSIDL_PROFILE)
754 #define CSIDL_PROFILE 0x0028
756 #if !defined(CSIDL_WINDOWS)
757 #define CSIDL_WINDOWS 0x0024
760 INLINE int __hscore_CSIDL_PROFILE() { return CSIDL_PROFILE; }
761 INLINE int __hscore_CSIDL_APPDATA() { return CSIDL_APPDATA; }
762 INLINE int __hscore_CSIDL_WINDOWS() { return CSIDL_WINDOWS; }
763 INLINE int __hscore_CSIDL_PERSONAL() { return CSIDL_PERSONAL; }
766 #if defined(__MINGW32__)
767 INLINE unsigned int __hscore_get_osver(void) { return _osver; }
770 /* ToDo: write a feature test that doesn't assume 'environ' to
771 * be in scope at link-time. */
772 extern char** environ;
773 INLINE char **__hscore_environ() { return environ; }
775 /* lossless conversions between pointers and integral types */
776 INLINE void * __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
777 INLINE void * __hscore_from_intptr (intptr_t n) { return (void *)n; }
778 INLINE uintptr_t __hscore_to_uintptr (void *p) { return (uintptr_t)p; }
779 INLINE intptr_t __hscore_to_intptr (void *p) { return (intptr_t)p; }
781 #endif /* __HSBASE_H__ */