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_HOST_OS)
102 # include <inttypes.h>
107 #if !defined(mingw32_HOST_OS) && !defined(irix_HOST_OS)
108 # if HAVE_SYS_RESOURCE_H
109 # include <sys/resource.h>
114 #include <sys/syscall.h>
115 #define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
116 #define HAVE_GETRUSAGE
121 #include <sys/wait.h>
126 #include "lockFile.h"
127 #include "dirUtils.h"
130 #include "runProcess.h"
132 #if defined(mingw32_HOST_OS)
135 #include "timeUtils.h"
140 #if HAVE_SYS_SELECT_H
141 #include <sys/select.h>
144 /* in inputReady.c */
145 int inputReady(int fd, int msecs, int isSock);
148 extern HsInt nocldstop;
150 #if !defined(mingw32_HOST_OS)
152 extern int execvpe(char *name, char *const argv[], char **envp);
153 extern void pPrPr_disableITimers (void);
156 /* -----------------------------------------------------------------------------
157 64-bit operations, defined in longlong.c
158 -------------------------------------------------------------------------- */
160 #ifdef SUPPORT_LONG_LONGS
162 StgInt stg_gtWord64 (StgWord64, StgWord64);
163 StgInt stg_geWord64 (StgWord64, StgWord64);
164 StgInt stg_eqWord64 (StgWord64, StgWord64);
165 StgInt stg_neWord64 (StgWord64, StgWord64);
166 StgInt stg_ltWord64 (StgWord64, StgWord64);
167 StgInt stg_leWord64 (StgWord64, StgWord64);
169 StgInt stg_gtInt64 (StgInt64, StgInt64);
170 StgInt stg_geInt64 (StgInt64, StgInt64);
171 StgInt stg_eqInt64 (StgInt64, StgInt64);
172 StgInt stg_neInt64 (StgInt64, StgInt64);
173 StgInt stg_ltInt64 (StgInt64, StgInt64);
174 StgInt stg_leInt64 (StgInt64, StgInt64);
176 StgWord64 stg_remWord64 (StgWord64, StgWord64);
177 StgWord64 stg_quotWord64 (StgWord64, StgWord64);
179 StgInt64 stg_remInt64 (StgInt64, StgInt64);
180 StgInt64 stg_quotInt64 (StgInt64, StgInt64);
181 StgInt64 stg_negateInt64 (StgInt64);
182 StgInt64 stg_plusInt64 (StgInt64, StgInt64);
183 StgInt64 stg_minusInt64 (StgInt64, StgInt64);
184 StgInt64 stg_timesInt64 (StgInt64, StgInt64);
186 StgWord64 stg_and64 (StgWord64, StgWord64);
187 StgWord64 stg_or64 (StgWord64, StgWord64);
188 StgWord64 stg_xor64 (StgWord64, StgWord64);
189 StgWord64 stg_not64 (StgWord64);
191 StgWord64 stg_uncheckedShiftL64 (StgWord64, StgInt);
192 StgWord64 stg_uncheckedShiftRL64 (StgWord64, StgInt);
193 StgInt64 stg_uncheckedIShiftL64 (StgInt64, StgInt);
194 StgInt64 stg_uncheckedIShiftRL64 (StgInt64, StgInt);
195 StgInt64 stg_uncheckedIShiftRA64 (StgInt64, StgInt);
197 StgInt64 stg_intToInt64 (StgInt);
198 StgInt stg_int64ToInt (StgInt64);
199 StgWord64 stg_int64ToWord64 (StgInt64);
201 StgWord64 stg_wordToWord64 (StgWord);
202 StgWord stg_word64ToWord (StgWord64);
203 StgInt64 stg_word64ToInt64 (StgWord64);
205 StgInt64 stg_integerToInt64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da);
206 StgWord64 stg_integerToWord64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da);
208 #endif /* SUPPORT_LONG_LONGS */
210 /* -----------------------------------------------------------------------------
213 These functions are given as inlines here for when compiling via C,
214 but we also generate static versions into the cbits library for
215 when compiling to native code.
216 -------------------------------------------------------------------------- */
219 # if defined(_MSC_VER)
220 # define INLINE extern __inline
221 # elif defined(__GNUC__)
222 # define INLINE extern inline
224 # define INLINE inline
228 INLINE int __hscore_get_errno(void) { return errno; }
229 INLINE void __hscore_set_errno(int e) { errno = e; }
231 #if !defined(_MSC_VER)
232 INLINE int __hscore_s_isreg(m) { return S_ISREG(m); }
233 INLINE int __hscore_s_isdir(m) { return S_ISDIR(m); }
234 INLINE int __hscore_s_isfifo(m) { return S_ISFIFO(m); }
235 INLINE int __hscore_s_isblk(m) { return S_ISBLK(m); }
236 INLINE int __hscore_s_ischr(m) { return S_ISCHR(m); }
238 INLINE int __hscore_s_issock(m) { return S_ISSOCK(m); }
242 #if !defined(mingw32_HOST_OS) && !defined(_MSC_VER)
244 __hscore_sigemptyset( sigset_t *set )
245 { return sigemptyset(set); }
248 __hscore_sigfillset( sigset_t *set )
249 { return sigfillset(set); }
252 __hscore_sigaddset( sigset_t * set, int s )
253 { return sigaddset(set,s); }
256 __hscore_sigdelset( sigset_t * set, int s )
257 { return sigdelset(set,s); }
260 __hscore_sigismember( sigset_t * set, int s )
261 { return sigismember(set,s); }
265 __hscore_memcpy_dst_off( char *dst, int dst_off, char *src, size_t sz )
266 { return memcpy(dst+dst_off, src, sz); }
269 __hscore_memcpy_src_off( char *dst, char *src, int src_off, size_t sz )
270 { return memcpy(dst, src+src_off, sz); }
273 __hscore_supportsTextMode()
275 #if defined(mingw32_HOST_OS)
276 return HS_BOOL_FALSE;
297 #if defined(_MSC_VER)
300 return CONST_O_BINARY;
315 __hscore_o_wronly( void )
325 __hscore_o_rdwr( void )
335 __hscore_o_append( void )
345 __hscore_o_creat( void )
355 __hscore_o_excl( void )
365 __hscore_o_trunc( void )
375 __hscore_o_noctty( void )
385 __hscore_o_nonblock( void )
395 __hscore_seek_set( void )
401 __hscore_seek_end( void )
407 __hscore_ftruncate( int fd, off_t where )
409 #if defined(HAVE_FTRUNCATE)
410 return ftruncate(fd,where);
411 #elif defined(HAVE__CHSIZE)
412 return _chsize(fd,where);
414 #error at least ftruncate or _chsize functions are required to build
419 __hscore_setmode( HsInt fd, HsBool toBin )
421 #if defined(mingw32_HOST_OS) || defined(_MSC_VER)
422 return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
428 #if __GLASGOW_HASKELL__
431 __hscore_PrelHandle_write( HsInt fd, HsAddr ptr, HsInt off, int sz )
433 return write(fd,(char *)ptr + off, sz);
437 __hscore_PrelHandle_read( HsInt fd, HsAddr ptr, HsInt off, int sz )
439 return read(fd,(char *)ptr + off, sz);
443 #if defined(mingw32_HOST_OS) || defined(_MSC_VER)
445 __hscore_PrelHandle_send( HsInt fd, HsAddr ptr, HsInt off, int sz )
447 return send(fd,(char *)ptr + off, sz, 0);
451 __hscore_PrelHandle_recv( HsInt fd, HsAddr ptr, HsInt off, int sz )
453 return recv(fd,(char *)ptr + off, sz, 0);
457 #endif /* __GLASGOW_HASKELL__ */
460 __hscore_mkdir( HsAddr pathName, HsInt mode )
462 #if defined(mingw32_HOST_OS) || defined(_MSC_VER)
463 return mkdir(pathName);
465 return mkdir(pathName,mode);
470 __hscore_lstat( HsAddr fname, HsAddr st )
473 return lstat((const char*)fname, (struct stat*)st);
475 return stat((const char*)fname, (struct stat*)st);
480 /* A size that will contain many path names, but not necessarily all
481 * (PATH_MAX is not defined on systems with unlimited path length,
484 INLINE HsInt __hscore_long_path_size() { return PATH_MAX; }
486 INLINE HsInt __hscore_long_path_size() { return 4096; }
490 INLINE mode_t __hscore_R_OK() { return R_OK; }
493 INLINE mode_t __hscore_W_OK() { return W_OK; }
496 INLINE mode_t __hscore_X_OK() { return X_OK; }
500 INLINE mode_t __hscore_S_IRUSR() { return S_IRUSR; }
503 INLINE mode_t __hscore_S_IWUSR() { return S_IWUSR; }
506 INLINE mode_t __hscore_S_IXUSR() { return S_IXUSR; }
510 __hscore_d_name( struct dirent* d )
512 return (HsAddr)(d->d_name);
516 __hscore_end_of_dir( void )
518 return READDIR_ERRNO_EOF;
522 __hscore_free_dirent(HsAddr dEnt)
530 __hscore_sizeof_stat( void )
532 return sizeof(struct stat);
535 INLINE time_t __hscore_st_mtime ( struct stat* st ) { return st->st_mtime; }
536 INLINE off_t __hscore_st_size ( struct stat* st ) { return st->st_size; }
537 #if !defined(_MSC_VER)
538 INLINE mode_t __hscore_st_mode ( struct stat* st ) { return st->st_mode; }
542 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
545 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
547 INLINE unsigned char*
548 __hscore_ptr_c_cc( struct termios* ts )
549 { return (unsigned char*) &ts->c_cc; }
552 __hscore_sizeof_termios( void )
554 #ifndef mingw32_HOST_OS
555 return sizeof(struct termios);
562 #if !defined(mingw32_HOST_OS) && !defined(_MSC_VER)
564 __hscore_sizeof_sigset_t( void )
566 return sizeof(sigset_t);
571 __hscore_echo( void )
582 __hscore_tcsanow( void )
593 __hscore_icanon( void )
602 INLINE int __hscore_vmin( void )
611 INLINE int __hscore_vtime( void )
620 INLINE int __hscore_sigttou( void )
629 INLINE int __hscore_sig_block( void )
638 INLINE int __hscore_sig_setmask( void )
648 __hscore_f_getfl( void )
658 __hscore_f_setfl( void )
667 // defined in rts/RtsStartup.c.
668 extern void* __hscore_get_saved_termios(int fd);
669 extern void __hscore_set_saved_termios(int fd, void* ts);
671 INLINE int __hscore_hs_fileno (FILE *f) { return fileno (f); }
673 INLINE int __hscore_open(char *file, int how, mode_t mode) {
674 #ifdef mingw32_HOST_OS
675 if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
676 return _sopen(file,how,_SH_DENYRW,mode);
678 return _sopen(file,how,_SH_DENYWR,mode);
680 return open(file,how,mode);
684 // These are wrapped because on some OSs (eg. Linux) they are
685 // macros which redirect to the 64-bit-off_t versions when large file
686 // support is enabled.
688 INLINE off_t __hscore_lseek(int fd, off_t off, int whence) {
689 return (lseek(fd,off,whence));
692 INLINE int __hscore_stat(char *file, struct stat *buf) {
693 return (stat(file,buf));
696 INLINE int __hscore_fstat(int fd, struct stat *buf) {
697 return (fstat(fd,buf));
700 // select-related stuff
702 #if !defined(mingw32_HOST_OS)
703 INLINE int hsFD_SETSIZE(void) { return FD_SETSIZE; }
704 INLINE void hsFD_CLR(int fd, fd_set *fds) { FD_CLR(fd, fds); }
705 INLINE int hsFD_ISSET(int fd, fd_set *fds) { return FD_ISSET(fd, fds); }
706 INLINE void hsFD_SET(int fd, fd_set *fds) { FD_SET(fd, fds); }
707 INLINE int sizeof_fd_set(void) { return sizeof(fd_set); }
708 extern void hsFD_ZERO(fd_set *fds);
711 // gettimeofday()-related
713 #if !defined(mingw32_HOST_OS)
716 INLINE HsInt sizeofTimeVal(void) { return sizeof(struct timeval); }
718 INLINE HsInt getTicksOfDay(void)
721 gettimeofday(&tv, (struct timezone *) NULL);
722 return (tv.tv_sec * TICK_FREQ +
723 tv.tv_usec * TICK_FREQ / 1000000);
726 INLINE void setTimevalTicks(struct timeval *p, HsInt ticks)
728 p->tv_sec = ticks / TICK_FREQ;
729 p->tv_usec = (ticks % TICK_FREQ) * (1000000 / TICK_FREQ);
731 #endif /* !defined(mingw32_HOST_OS) */
735 #if defined(mingw32_HOST_OS)
737 /* Make sure we've got the reqd CSIDL_ constants in scope;
738 * w32api header files are lagging a bit in defining the full set.
740 #if !defined(CSIDL_APPDATA)
741 #define CSIDL_APPDATA 0x001a
743 #if !defined(CSIDL_PERSONAL)
744 #define CSIDL_PERSONAL 0x0005
746 #if !defined(CSIDL_PROFILE)
747 #define CSIDL_PROFILE 0x0028
749 #if !defined(CSIDL_WINDOWS)
750 #define CSIDL_WINDOWS 0x0024
753 INLINE int __hscore_CSIDL_PROFILE() { return CSIDL_PROFILE; }
754 INLINE int __hscore_CSIDL_APPDATA() { return CSIDL_APPDATA; }
755 INLINE int __hscore_CSIDL_WINDOWS() { return CSIDL_WINDOWS; }
756 INLINE int __hscore_CSIDL_PERSONAL() { return CSIDL_PERSONAL; }
759 #if defined(mingw32_HOST_OS)
760 INLINE unsigned int __hscore_get_osver(void) { return _osver; }
763 /* ToDo: write a feature test that doesn't assume 'environ' to
764 * be in scope at link-time. */
765 extern char** environ;
766 INLINE char **__hscore_environ() { return environ; }
768 /* lossless conversions between pointers and integral types */
769 INLINE void * __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
770 INLINE void * __hscore_from_intptr (intptr_t n) { return (void *)n; }
771 INLINE uintptr_t __hscore_to_uintptr (void *p) { return (uintptr_t)p; }
772 INLINE intptr_t __hscore_to_intptr (void *p) { return (intptr_t)p; }
774 #endif /* __HSBASE_H__ */