[project @ 1996-01-08 20:28:12 by partain]
[ghc.git] / ghc / lib / haskell-1.3 / LibPosix.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
3 %
4 \section[LibPosix]{Haskell 1.3 POSIX bindings}
5
6 \begin{code}
7 module LibPosix  (
8     LibPosixDB..,
9     LibPosixErr..,
10     LibPosixFiles..,
11     LibPosixIO..,
12     LibPosixProcEnv..,
13     LibPosixProcPrim..,
14     LibPosixTTY..,
15
16     runProcess,
17
18     ByteCount(..),
19     Channel(..),
20     ClockTick(..),
21     EpochTime(..),
22     FileOffset(..),
23     GroupID(..),
24     Limit(..),
25     LinkCount(..),
26     ProcessID(..),
27     ProcessGroupID(..),
28     UserID(..),
29     
30     ExitCode
31     )  where
32
33
34 import LibPosixDB
35 import LibPosixErr
36 import LibPosixFiles
37 import LibPosixIO
38 import LibPosixProcEnv
39 import LibPosixProcPrim
40 import LibPosixTTY
41 import LibPosixUtil
42
43 -- runProcess is our candidate for the high-level OS-independent primitive 
44 -- If accepted, it will be moved out of LibPosix into LibSystem.
45
46 import LibDirectory     ( setCurrentDirectory )
47
48 import PreludeGlaST
49 import PreludePrimIO    ( takeMVar, putMVar, _MVar )
50 import PreludeStdIO
51
52 runProcess :: FilePath                      -- Command
53            -> [String]                      -- Arguments
54            -> Maybe [(String, String)]      -- Environment
55            -> Maybe FilePath                -- Working directory    
56            -> Maybe Handle                  -- stdin
57            -> Maybe Handle                  -- stdout
58            -> Maybe Handle                  -- stderr
59            -> IO ()
60 runProcess path args env dir stdin stdout stderr = 
61     forkProcess >>= \ pid ->
62     case pid of
63       Nothing -> doTheBusiness
64       Just x  -> return ()
65   where
66     doTheBusiness :: IO ()
67     doTheBusiness =
68         maybeChangeWorkingDirectory     >>
69         maybeDup2 0 stdin               >>
70         maybeDup2 1 stdout              >>
71         maybeDup2 2 stderr              >>
72         executeFile path True args env  >>
73         syserr "runProcess"
74
75     maybeChangeWorkingDirectory :: IO ()
76     maybeChangeWorkingDirectory =
77         case dir of
78           Nothing -> return ()
79           Just x  -> setCurrentDirectory x
80
81     maybeDup2 :: Int -> Maybe Handle -> IO ()
82     maybeDup2 dest h =
83         case h of Nothing -> return ()
84                   Just x  -> handleFD x >>= \ src ->
85                              dupChannelTo src dest >>
86                              return ()
87
88     handleFD :: Handle -> IO Channel
89     handleFD handle =
90         takeMVar handle                             >>= \ htype ->
91         putMVar handle htype                        >>
92         case htype of 
93           _ErrorHandle ioError -> failWith ioError
94           _ClosedHandle -> failWith (IllegalOperation "handle is closed")
95           _SemiClosedHandle _ _ -> failWith (IllegalOperation "handle is closed")
96           other -> 
97             _casm_ ``%r = fileno((FILE *)%0);'' (_filePtr other)
98                                                     `thenPrimIO` \ fd ->
99             return fd
100
101 \end{code}