7bb26fa3951b80be2be487f930356a94f9df2a5d
[ghc.git] / libraries / base / System / Posix / Internals.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE CPP, NoImplicitPrelude, CApiFFI #-}
3 {-# OPTIONS_HADDOCK hide #-}
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module : System.Posix.Internals
8 -- Copyright : (c) The University of Glasgow, 1992-2002
9 -- License : see libraries/base/LICENSE
10 --
11 -- Maintainer : cvs-ghc@haskell.org
12 -- Stability : internal
13 -- Portability : non-portable (requires POSIX)
14 --
15 -- POSIX support layer for the standard libraries.
16 -- This library is built on *every* platform, including Win32.
17 --
18 -- Non-posix compliant in order to support the following features:
19 -- * S_ISSOCK (no sockets in POSIX)
20 --
21 -----------------------------------------------------------------------------
22
23 module System.Posix.Internals where
24
25 #include "HsBaseConfig.h"
26
27 import System.Posix.Types
28
29 import Foreign
30 import Foreign.C
31
32 -- import Data.Bits
33 import Data.Maybe
34
35 #if !defined(HTYPE_TCFLAG_T)
36 import System.IO.Error
37 #endif
38
39 import GHC.Base
40 import GHC.Num
41 import GHC.Real
42 import GHC.IO
43 import GHC.IO.IOMode
44 import GHC.IO.Exception
45 import GHC.IO.Device
46 #ifndef mingw32_HOST_OS
47 import {-# SOURCE #-} GHC.IO.Encoding (getFileSystemEncoding)
48 import qualified GHC.Foreign as GHC
49 #endif
50
51 -- ---------------------------------------------------------------------------
52 -- Debugging the base package
53
54 puts :: String -> IO ()
55 puts s = withCAStringLen (s ++ "\n") $ \(p, len) -> do
56 -- In reality should be withCString, but assume ASCII to avoid loop
57 -- if this is called by GHC.Foreign
58 _ <- c_write 1 (castPtr p) (fromIntegral len)
59 return ()
60
61
62 -- ---------------------------------------------------------------------------
63 -- Types
64
65 data {-# CTYPE "struct flock" #-} CFLock
66 data {-# CTYPE "struct group" #-} CGroup
67 data {-# CTYPE "struct lconv" #-} CLconv
68 data {-# CTYPE "struct passwd" #-} CPasswd
69 data {-# CTYPE "struct sigaction" #-} CSigaction
70 data {-# CTYPE "sigset_t" #-} CSigset
71 data {-# CTYPE "struct stat" #-} CStat
72 data {-# CTYPE "struct termios" #-} CTermios
73 data {-# CTYPE "struct tm" #-} CTm
74 data {-# CTYPE "struct tms" #-} CTms
75 data {-# CTYPE "struct utimbuf" #-} CUtimbuf
76 data {-# CTYPE "struct utsname" #-} CUtsname
77
78 type FD = CInt
79
80 -- ---------------------------------------------------------------------------
81 -- stat()-related stuff
82
83 fdFileSize :: FD -> IO Integer
84 fdFileSize fd =
85 allocaBytes sizeof_stat $ \ p_stat -> do
86 throwErrnoIfMinus1Retry_ "fileSize" $
87 c_fstat fd p_stat
88 c_mode <- st_mode p_stat :: IO CMode
89 if not (s_isreg c_mode)
90 then return (-1)
91 else do
92 c_size <- st_size p_stat
93 return (fromIntegral c_size)
94
95 fileType :: FilePath -> IO IODeviceType
96 fileType file =
97 allocaBytes sizeof_stat $ \ p_stat -> do
98 withFilePath file $ \p_file -> do
99 throwErrnoIfMinus1Retry_ "fileType" $
100 c_stat p_file p_stat
101 statGetType p_stat
102
103 -- NOTE: On Win32 platforms, this will only work with file descriptors
104 -- referring to file handles. i.e., it'll fail for socket FDs.
105 fdStat :: FD -> IO (IODeviceType, CDev, CIno)
106 fdStat fd =
107 allocaBytes sizeof_stat $ \ p_stat -> do
108 throwErrnoIfMinus1Retry_ "fdType" $
109 c_fstat fd p_stat
110 ty <- statGetType p_stat
111 dev <- st_dev p_stat
112 ino <- st_ino p_stat
113 return (ty,dev,ino)
114
115 fdType :: FD -> IO IODeviceType
116 fdType fd = do (ty,_,_) <- fdStat fd; return ty
117
118 statGetType :: Ptr CStat -> IO IODeviceType
119 statGetType p_stat = do
120 c_mode <- st_mode p_stat :: IO CMode
121 case () of
122 _ | s_isdir c_mode -> return Directory
123 | s_isfifo c_mode || s_issock c_mode || s_ischr c_mode
124 -> return Stream
125 | s_isreg c_mode -> return RegularFile
126 -- Q: map char devices to RawDevice too?
127 | s_isblk c_mode -> return RawDevice
128 | otherwise -> ioError ioe_unknownfiletype
129
130 ioe_unknownfiletype :: IOException
131 ioe_unknownfiletype = IOError Nothing UnsupportedOperation "fdType"
132 "unknown file type"
133 Nothing
134 Nothing
135
136 fdGetMode :: FD -> IO IOMode
137 #if defined(mingw32_HOST_OS)
138 fdGetMode _ = do
139 -- We don't have a way of finding out which flags are set on FDs
140 -- on Windows, so make a handle that thinks that anything goes.
141 let flags = o_RDWR
142 #else
143 fdGetMode fd = do
144 flags <- throwErrnoIfMinus1Retry "fdGetMode"
145 (c_fcntl_read fd const_f_getfl)
146 #endif
147 let
148 wH = (flags .&. o_WRONLY) /= 0
149 aH = (flags .&. o_APPEND) /= 0
150 rwH = (flags .&. o_RDWR) /= 0
151
152 mode
153 | wH && aH = AppendMode
154 | wH = WriteMode
155 | rwH = ReadWriteMode
156 | otherwise = ReadMode
157
158 return mode
159
160 #ifdef mingw32_HOST_OS
161 withFilePath :: FilePath -> (CWString -> IO a) -> IO a
162 withFilePath = withCWString
163
164 newFilePath :: FilePath -> IO CWString
165 newFilePath = newCWString
166
167 peekFilePath :: CWString -> IO FilePath
168 peekFilePath = peekCWString
169 #else
170
171 withFilePath :: FilePath -> (CString -> IO a) -> IO a
172 newFilePath :: FilePath -> IO CString
173 peekFilePath :: CString -> IO FilePath
174 peekFilePathLen :: CStringLen -> IO FilePath
175
176 withFilePath fp f = getFileSystemEncoding >>= \enc -> GHC.withCString enc fp f
177 newFilePath fp = getFileSystemEncoding >>= \enc -> GHC.newCString enc fp
178 peekFilePath fp = getFileSystemEncoding >>= \enc -> GHC.peekCString enc fp
179 peekFilePathLen fp = getFileSystemEncoding >>= \enc -> GHC.peekCStringLen enc fp
180
181 #endif
182
183 -- ---------------------------------------------------------------------------
184 -- Terminal-related stuff
185
186 #if defined(HTYPE_TCFLAG_T)
187
188 setEcho :: FD -> Bool -> IO ()
189 setEcho fd on = do
190 tcSetAttr fd $ \ p_tios -> do
191 lflag <- c_lflag p_tios :: IO CTcflag
192 let new_lflag
193 | on = lflag .|. fromIntegral const_echo
194 | otherwise = lflag .&. complement (fromIntegral const_echo)
195 poke_c_lflag p_tios (new_lflag :: CTcflag)
196
197 getEcho :: FD -> IO Bool
198 getEcho fd = do
199 tcSetAttr fd $ \ p_tios -> do
200 lflag <- c_lflag p_tios :: IO CTcflag
201 return ((lflag .&. fromIntegral const_echo) /= 0)
202
203 setCooked :: FD -> Bool -> IO ()
204 setCooked fd cooked =
205 tcSetAttr fd $ \ p_tios -> do
206
207 -- turn on/off ICANON
208 lflag <- c_lflag p_tios :: IO CTcflag
209 let new_lflag | cooked = lflag .|. (fromIntegral const_icanon)
210 | otherwise = lflag .&. complement (fromIntegral const_icanon)
211 poke_c_lflag p_tios (new_lflag :: CTcflag)
212
213 -- set VMIN & VTIME to 1/0 respectively
214 when (not cooked) $ do
215 c_cc <- ptr_c_cc p_tios
216 let vmin = (c_cc `plusPtr` (fromIntegral const_vmin)) :: Ptr Word8
217 vtime = (c_cc `plusPtr` (fromIntegral const_vtime)) :: Ptr Word8
218 poke vmin 1
219 poke vtime 0
220
221 tcSetAttr :: FD -> (Ptr CTermios -> IO a) -> IO a
222 tcSetAttr fd fun = do
223 allocaBytes sizeof_termios $ \p_tios -> do
224 throwErrnoIfMinus1Retry_ "tcSetAttr"
225 (c_tcgetattr fd p_tios)
226
227 -- Save a copy of termios, if this is a standard file descriptor.
228 -- These terminal settings are restored in hs_exit().
229 when (fd <= 2) $ do
230 p <- get_saved_termios fd
231 when (p == nullPtr) $ do
232 saved_tios <- mallocBytes sizeof_termios
233 copyBytes saved_tios p_tios sizeof_termios
234 set_saved_termios fd saved_tios
235
236 -- tcsetattr() when invoked by a background process causes the process
237 -- to be sent SIGTTOU regardless of whether the process has TOSTOP set
238 -- in its terminal flags (try it...). This function provides a
239 -- wrapper which temporarily blocks SIGTTOU around the call, making it
240 -- transparent.
241 allocaBytes sizeof_sigset_t $ \ p_sigset -> do
242 allocaBytes sizeof_sigset_t $ \ p_old_sigset -> do
243 throwErrnoIfMinus1_ "sigemptyset" $
244 c_sigemptyset p_sigset
245 throwErrnoIfMinus1_ "sigaddset" $
246 c_sigaddset p_sigset const_sigttou
247 throwErrnoIfMinus1_ "sigprocmask" $
248 c_sigprocmask const_sig_block p_sigset p_old_sigset
249 r <- fun p_tios -- do the business
250 throwErrnoIfMinus1Retry_ "tcSetAttr" $
251 c_tcsetattr fd const_tcsanow p_tios
252 throwErrnoIfMinus1_ "sigprocmask" $
253 c_sigprocmask const_sig_setmask p_old_sigset nullPtr
254 return r
255
256 foreign import ccall unsafe "HsBase.h __hscore_get_saved_termios"
257 get_saved_termios :: CInt -> IO (Ptr CTermios)
258
259 foreign import ccall unsafe "HsBase.h __hscore_set_saved_termios"
260 set_saved_termios :: CInt -> (Ptr CTermios) -> IO ()
261
262 #else
263
264 -- 'raw' mode for Win32 means turn off 'line input' (=> buffering and
265 -- character translation for the console.) The Win32 API for doing
266 -- this is GetConsoleMode(), which also requires echoing to be disabled
267 -- when turning off 'line input' processing. Notice that turning off
268 -- 'line input' implies enter/return is reported as '\r' (and it won't
269 -- report that character until another character is input..odd.) This
270 -- latter feature doesn't sit too well with IO actions like IO.hGetLine..
271 -- consider yourself warned.
272 setCooked :: FD -> Bool -> IO ()
273 setCooked fd cooked = do
274 x <- set_console_buffering fd (if cooked then 1 else 0)
275 if (x /= 0)
276 then ioError (ioe_unk_error "setCooked" "failed to set buffering")
277 else return ()
278
279 ioe_unk_error :: String -> String -> IOException
280 ioe_unk_error loc msg
281 = ioeSetErrorString (mkIOError OtherError loc Nothing Nothing) msg
282
283 -- Note: echoing goes hand in hand with enabling 'line input' / raw-ness
284 -- for Win32 consoles, hence setEcho ends up being the inverse of setCooked.
285 setEcho :: FD -> Bool -> IO ()
286 setEcho fd on = do
287 x <- set_console_echo fd (if on then 1 else 0)
288 if (x /= 0)
289 then ioError (ioe_unk_error "setEcho" "failed to set echoing")
290 else return ()
291
292 getEcho :: FD -> IO Bool
293 getEcho fd = do
294 r <- get_console_echo fd
295 if (r == (-1))
296 then ioError (ioe_unk_error "getEcho" "failed to get echoing")
297 else return (r == 1)
298
299 foreign import ccall unsafe "consUtils.h set_console_buffering__"
300 set_console_buffering :: CInt -> CInt -> IO CInt
301
302 foreign import ccall unsafe "consUtils.h set_console_echo__"
303 set_console_echo :: CInt -> CInt -> IO CInt
304
305 foreign import ccall unsafe "consUtils.h get_console_echo__"
306 get_console_echo :: CInt -> IO CInt
307
308 foreign import ccall unsafe "consUtils.h is_console__"
309 is_console :: CInt -> IO CInt
310
311 #endif
312
313 -- ---------------------------------------------------------------------------
314 -- Turning on non-blocking for a file descriptor
315
316 setNonBlockingFD :: FD -> Bool -> IO ()
317 #if !defined(mingw32_HOST_OS)
318 setNonBlockingFD fd set = do
319 flags <- throwErrnoIfMinus1Retry "setNonBlockingFD"
320 (c_fcntl_read fd const_f_getfl)
321 let flags' | set = flags .|. o_NONBLOCK
322 | otherwise = flags .&. complement o_NONBLOCK
323 when (flags /= flags') $ do
324 -- An error when setting O_NONBLOCK isn't fatal: on some systems
325 -- there are certain file handles on which this will fail (eg. /dev/null
326 -- on FreeBSD) so we throw away the return code from fcntl_write.
327 _ <- c_fcntl_write fd const_f_setfl (fromIntegral flags')
328 return ()
329 #else
330
331 -- bogus defns for win32
332 setNonBlockingFD _ _ = return ()
333
334 #endif
335
336 -- -----------------------------------------------------------------------------
337 -- Set close-on-exec for a file descriptor
338
339 #if !defined(mingw32_HOST_OS)
340 setCloseOnExec :: FD -> IO ()
341 setCloseOnExec fd = do
342 throwErrnoIfMinus1_ "setCloseOnExec" $
343 c_fcntl_write fd const_f_setfd const_fd_cloexec
344 #endif
345
346 -- -----------------------------------------------------------------------------
347 -- foreign imports
348
349 #if !defined(mingw32_HOST_OS)
350 type CFilePath = CString
351 #else
352 type CFilePath = CWString
353 #endif
354
355 foreign import ccall unsafe "HsBase.h __hscore_open"
356 c_open :: CFilePath -> CInt -> CMode -> IO CInt
357
358 foreign import ccall safe "HsBase.h __hscore_open"
359 c_safe_open :: CFilePath -> CInt -> CMode -> IO CInt
360
361 foreign import ccall unsafe "HsBase.h __hscore_fstat"
362 c_fstat :: CInt -> Ptr CStat -> IO CInt
363
364 foreign import ccall unsafe "HsBase.h __hscore_lstat"
365 lstat :: CFilePath -> Ptr CStat -> IO CInt
366
367 {- Note: Win32 POSIX functions
368 Functions that are not part of the POSIX standards were
369 at some point deprecated by Microsoft. This deprecation
370 was performed by renaming the functions according to the
371 C++ ABI Section 17.6.4.3.2b. This was done to free up the
372 namespace of normal Windows programs since Windows isn't
373 POSIX compliant anyway.
374
375 These were working before since the RTS was re-exporting
376 these symbols under the undeprecated names. This is no longer
377 being done. See #11223
378
379 See https://msdn.microsoft.com/en-us/library/ms235384.aspx
380 for more.
381
382 However since we can't hope to get people to support Windows
383 packages we should support the deprecated names. See #12497
384 -}
385 foreign import capi unsafe "unistd.h lseek"
386 c_lseek :: CInt -> COff -> CInt -> IO COff
387
388 foreign import ccall unsafe "HsBase.h access"
389 c_access :: CString -> CInt -> IO CInt
390
391 foreign import ccall unsafe "HsBase.h chmod"
392 c_chmod :: CString -> CMode -> IO CInt
393
394 foreign import ccall unsafe "HsBase.h close"
395 c_close :: CInt -> IO CInt
396
397 foreign import ccall unsafe "HsBase.h creat"
398 c_creat :: CString -> CMode -> IO CInt
399
400 foreign import ccall unsafe "HsBase.h dup"
401 c_dup :: CInt -> IO CInt
402
403 foreign import ccall unsafe "HsBase.h dup2"
404 c_dup2 :: CInt -> CInt -> IO CInt
405
406 foreign import ccall unsafe "HsBase.h isatty"
407 c_isatty :: CInt -> IO CInt
408
409 #if defined(mingw32_HOST_OS)
410 -- See Note: Windows types
411 foreign import capi unsafe "HsBase.h _read"
412 c_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
413
414 -- See Note: Windows types
415 foreign import capi safe "HsBase.h _read"
416 c_safe_read :: CInt -> Ptr Word8 -> CUInt -> IO CInt
417
418 foreign import ccall unsafe "HsBase.h _umask"
419 c_umask :: CMode -> IO CMode
420
421 -- See Note: Windows types
422 foreign import capi unsafe "HsBase.h _write"
423 c_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
424
425 -- See Note: Windows types
426 foreign import capi safe "HsBase.h _write"
427 c_safe_write :: CInt -> Ptr Word8 -> CUInt -> IO CInt
428
429 foreign import ccall unsafe "HsBase.h _pipe"
430 c_pipe :: Ptr CInt -> IO CInt
431 #else
432 -- We use CAPI as on some OSs (eg. Linux) this is wrapped by a macro
433 -- which redirects to the 64-bit-off_t versions when large file
434 -- support is enabled.
435
436 -- See Note: Windows types
437 foreign import capi unsafe "HsBase.h read"
438 c_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
439
440 -- See Note: Windows types
441 foreign import capi safe "HsBase.h read"
442 c_safe_read :: CInt -> Ptr Word8 -> CSize -> IO CSsize
443
444 foreign import ccall unsafe "HsBase.h umask"
445 c_umask :: CMode -> IO CMode
446
447 -- See Note: Windows types
448 foreign import capi unsafe "HsBase.h write"
449 c_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
450
451 -- See Note: Windows types
452 foreign import capi safe "HsBase.h write"
453 c_safe_write :: CInt -> Ptr Word8 -> CSize -> IO CSsize
454
455 foreign import ccall unsafe "HsBase.h pipe"
456 c_pipe :: Ptr CInt -> IO CInt
457 #endif
458
459 foreign import ccall unsafe "HsBase.h unlink"
460 c_unlink :: CString -> IO CInt
461
462 foreign import capi unsafe "HsBase.h utime"
463 c_utime :: CString -> Ptr CUtimbuf -> IO CInt
464
465 foreign import ccall unsafe "HsBase.h getpid"
466 c_getpid :: IO CPid
467
468 foreign import ccall unsafe "HsBase.h __hscore_stat"
469 c_stat :: CFilePath -> Ptr CStat -> IO CInt
470
471 foreign import ccall unsafe "HsBase.h __hscore_ftruncate"
472 c_ftruncate :: CInt -> COff -> IO CInt
473
474 #if !defined(mingw32_HOST_OS)
475 foreign import capi unsafe "HsBase.h fcntl"
476 c_fcntl_read :: CInt -> CInt -> IO CInt
477
478 foreign import capi unsafe "HsBase.h fcntl"
479 c_fcntl_write :: CInt -> CInt -> CLong -> IO CInt
480
481 foreign import capi unsafe "HsBase.h fcntl"
482 c_fcntl_lock :: CInt -> CInt -> Ptr CFLock -> IO CInt
483
484 foreign import ccall unsafe "HsBase.h fork"
485 c_fork :: IO CPid
486
487 foreign import ccall unsafe "HsBase.h link"
488 c_link :: CString -> CString -> IO CInt
489
490 -- capi is required at least on Android
491 foreign import capi unsafe "HsBase.h mkfifo"
492 c_mkfifo :: CString -> CMode -> IO CInt
493
494 foreign import capi unsafe "signal.h sigemptyset"
495 c_sigemptyset :: Ptr CSigset -> IO CInt
496
497 foreign import capi unsafe "signal.h sigaddset"
498 c_sigaddset :: Ptr CSigset -> CInt -> IO CInt
499
500 foreign import capi unsafe "signal.h sigprocmask"
501 c_sigprocmask :: CInt -> Ptr CSigset -> Ptr CSigset -> IO CInt
502
503 -- capi is required at least on Android
504 foreign import capi unsafe "HsBase.h tcgetattr"
505 c_tcgetattr :: CInt -> Ptr CTermios -> IO CInt
506
507 -- capi is required at least on Android
508 foreign import capi unsafe "HsBase.h tcsetattr"
509 c_tcsetattr :: CInt -> CInt -> Ptr CTermios -> IO CInt
510
511 foreign import ccall unsafe "HsBase.h waitpid"
512 c_waitpid :: CPid -> Ptr CInt -> CInt -> IO CPid
513 #endif
514
515 -- POSIX flags only:
516 foreign import ccall unsafe "HsBase.h __hscore_o_rdonly" o_RDONLY :: CInt
517 foreign import ccall unsafe "HsBase.h __hscore_o_wronly" o_WRONLY :: CInt
518 foreign import ccall unsafe "HsBase.h __hscore_o_rdwr" o_RDWR :: CInt
519 foreign import ccall unsafe "HsBase.h __hscore_o_append" o_APPEND :: CInt
520 foreign import ccall unsafe "HsBase.h __hscore_o_creat" o_CREAT :: CInt
521 foreign import ccall unsafe "HsBase.h __hscore_o_excl" o_EXCL :: CInt
522 foreign import ccall unsafe "HsBase.h __hscore_o_trunc" o_TRUNC :: CInt
523
524 -- non-POSIX flags.
525 foreign import ccall unsafe "HsBase.h __hscore_o_noctty" o_NOCTTY :: CInt
526 foreign import ccall unsafe "HsBase.h __hscore_o_nonblock" o_NONBLOCK :: CInt
527 foreign import ccall unsafe "HsBase.h __hscore_o_binary" o_BINARY :: CInt
528
529 foreign import capi unsafe "sys/stat.h S_ISREG" c_s_isreg :: CMode -> CInt
530 foreign import capi unsafe "sys/stat.h S_ISCHR" c_s_ischr :: CMode -> CInt
531 foreign import capi unsafe "sys/stat.h S_ISBLK" c_s_isblk :: CMode -> CInt
532 foreign import capi unsafe "sys/stat.h S_ISDIR" c_s_isdir :: CMode -> CInt
533 foreign import capi unsafe "sys/stat.h S_ISFIFO" c_s_isfifo :: CMode -> CInt
534
535 s_isreg :: CMode -> Bool
536 s_isreg cm = c_s_isreg cm /= 0
537 s_ischr :: CMode -> Bool
538 s_ischr cm = c_s_ischr cm /= 0
539 s_isblk :: CMode -> Bool
540 s_isblk cm = c_s_isblk cm /= 0
541 s_isdir :: CMode -> Bool
542 s_isdir cm = c_s_isdir cm /= 0
543 s_isfifo :: CMode -> Bool
544 s_isfifo cm = c_s_isfifo cm /= 0
545
546 foreign import ccall unsafe "HsBase.h __hscore_sizeof_stat" sizeof_stat :: Int
547 foreign import ccall unsafe "HsBase.h __hscore_st_mtime" st_mtime :: Ptr CStat -> IO CTime
548 #ifdef mingw32_HOST_OS
549 foreign import ccall unsafe "HsBase.h __hscore_st_size" st_size :: Ptr CStat -> IO Int64
550 #else
551 foreign import ccall unsafe "HsBase.h __hscore_st_size" st_size :: Ptr CStat -> IO COff
552 #endif
553 foreign import ccall unsafe "HsBase.h __hscore_st_mode" st_mode :: Ptr CStat -> IO CMode
554 foreign import ccall unsafe "HsBase.h __hscore_st_dev" st_dev :: Ptr CStat -> IO CDev
555 foreign import ccall unsafe "HsBase.h __hscore_st_ino" st_ino :: Ptr CStat -> IO CIno
556
557 foreign import ccall unsafe "HsBase.h __hscore_echo" const_echo :: CInt
558 foreign import ccall unsafe "HsBase.h __hscore_tcsanow" const_tcsanow :: CInt
559 foreign import ccall unsafe "HsBase.h __hscore_icanon" const_icanon :: CInt
560 foreign import ccall unsafe "HsBase.h __hscore_vmin" const_vmin :: CInt
561 foreign import ccall unsafe "HsBase.h __hscore_vtime" const_vtime :: CInt
562 foreign import ccall unsafe "HsBase.h __hscore_sigttou" const_sigttou :: CInt
563 foreign import ccall unsafe "HsBase.h __hscore_sig_block" const_sig_block :: CInt
564 foreign import ccall unsafe "HsBase.h __hscore_sig_setmask" const_sig_setmask :: CInt
565 foreign import ccall unsafe "HsBase.h __hscore_f_getfl" const_f_getfl :: CInt
566 foreign import ccall unsafe "HsBase.h __hscore_f_setfl" const_f_setfl :: CInt
567 foreign import ccall unsafe "HsBase.h __hscore_f_setfd" const_f_setfd :: CInt
568 foreign import ccall unsafe "HsBase.h __hscore_fd_cloexec" const_fd_cloexec :: CLong
569
570 #if defined(HTYPE_TCFLAG_T)
571 foreign import ccall unsafe "HsBase.h __hscore_sizeof_termios" sizeof_termios :: Int
572 foreign import ccall unsafe "HsBase.h __hscore_sizeof_sigset_t" sizeof_sigset_t :: Int
573
574 foreign import ccall unsafe "HsBase.h __hscore_lflag" c_lflag :: Ptr CTermios -> IO CTcflag
575 foreign import ccall unsafe "HsBase.h __hscore_poke_lflag" poke_c_lflag :: Ptr CTermios -> CTcflag -> IO ()
576 foreign import ccall unsafe "HsBase.h __hscore_ptr_c_cc" ptr_c_cc :: Ptr CTermios -> IO (Ptr Word8)
577 #endif
578
579 s_issock :: CMode -> Bool
580 #if !defined(mingw32_HOST_OS)
581 s_issock cmode = c_s_issock cmode /= 0
582 foreign import capi unsafe "sys/stat.h S_ISSOCK" c_s_issock :: CMode -> CInt
583 #else
584 s_issock _ = False
585 #endif
586
587 foreign import ccall unsafe "__hscore_bufsiz" dEFAULT_BUFFER_SIZE :: Int
588 foreign import capi unsafe "stdio.h value SEEK_CUR" sEEK_CUR :: CInt
589 foreign import capi unsafe "stdio.h value SEEK_SET" sEEK_SET :: CInt
590 foreign import capi unsafe "stdio.h value SEEK_END" sEEK_END :: CInt
591
592 {-
593 Note: Windows types
594
595 Windows' _read and _write have types that differ from POSIX. They take an
596 unsigned int for lengh and return a signed int where POSIX uses size_t and
597 ssize_t. Those are different on x86_64 and equivalent on x86. We import them
598 with the types in Microsoft's documentation which means that c_read,
599 c_safe_read, c_write and c_safe_write have different Haskell types depending on
600 the OS.
601 -}
602