[project @ 1999-11-26 16:29:09 by simonmar]
[ghc-hetmet.git] / ghc / lib / posix / PosixProcPrim.lhs
diff --git a/ghc/lib/posix/PosixProcPrim.lhs b/ghc/lib/posix/PosixProcPrim.lhs
deleted file mode 100644 (file)
index ffe7214..0000000
+++ /dev/null
@@ -1,511 +0,0 @@
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1995-1997
-%
-\section[PosixProcPrim]{Haskell 1.3 POSIX Process Primitives}
-
-\begin{code}
-
-#include "config.h"
-
-module PosixProcPrim (
-    Handler(..),
-    SignalSet,
-    Signal,
-    ProcessStatus(..),
-
-    addSignal,
-#ifndef cygwin32_TARGET_OS
-    awaitSignal,
-#endif
-    backgroundRead,
-    backgroundWrite,
-    blockSignals,
-#ifndef cygwin32_TARGET_OS
-    continueProcess,
-#endif
-    deleteSignal,
-    emptySignalSet,
-    executeFile,
-    exitImmediately,
-    floatingPointException,
-    forkProcess,
-    fullSignalSet,
-    getAnyProcessStatus,
-    getEnvVar,
-    getEnvironment,
-    getGroupProcessStatus,
-    getPendingSignals,
-    getProcessStatus,
-    getSignalMask,
-    illegalInstruction,
-    inSignalSet,
-    installHandler,
-    internalAbort,
-    keyboardSignal,
-    keyboardStop,
-    keyboardTermination,
-    killProcess,
-    lostConnection,
-    nullSignal,
-    openEndedPipe,
-    processStatusChanged,
-    queryStoppedChildFlag,
-    raiseSignal,
-    realTimeAlarm,
-    removeEnvVar,
-    scheduleAlarm,
-    segmentationViolation,
-    setEnvVar,
-    setEnvironment,
-    setSignalMask,
-    setStoppedChildFlag,
-    sigABRT,
-    sigALRM,
-    sigCHLD,
-#ifndef cygwin32_TARGET_OS
-    sigCONT,
-#endif
-    sigFPE,
-    sigHUP,
-    sigILL,
-    sigINT,
-    sigKILL,
-    sigPIPE,
-    sigProcMask,
-    sigQUIT,
-    sigSEGV,
-    sigSTOP,
-    sigSetSize,
-    sigTERM,
-    sigTSTP,
-    sigTTIN,
-    sigTTOU,
-    sigUSR1,
-    sigUSR2,
-    signalProcess,
-    signalProcessGroup,
-    sleep,
-    softwareStop,
-    softwareTermination,
-    unBlockSignals,
-    userDefinedSignal1,
-    userDefinedSignal2,
-
-    ExitCode
-
-    ) where
-
-import GlaExts
-import IO
-import PrelIOBase
-import Foreign     ( makeStablePtr, StablePtr, deRefStablePtr )
-import Addr        ( nullAddr )
-
-import PosixErr
-import PosixUtil
-import CString ( unvectorize, packStringIO,
-                allocChars, freeze, vectorize,
-                allocWords, strcpy
-              )
-
-import System(ExitCode(..))
-import PosixProcEnv (getProcessID)
-
-forkProcess :: IO (Maybe ProcessID)
-forkProcess = do
-    pid <-_ccall_ fork
-    case (pid::Int) of
-      -1 -> syserr "forkProcess"
-      0  -> return Nothing
-      _  -> return (Just pid)
-
-executeFile :: FilePath                            -- Command
-            -> Bool                        -- Search PATH?
-            -> [String]                            -- Arguments
-            -> Maybe [(String, String)]            -- Environment
-            -> IO ()
-executeFile path search args Nothing = do
-    prog <- packStringIO path
-    argv <- vectorize (basename path:args)
-    (if search then
-        _casm_ ``execvp(%0,(char **)%1);'' prog argv
-     else
-        _casm_ ``execv(%0,(char **)%1);'' prog argv
-     )
-    syserr "executeFile"
-
-executeFile path search args (Just env) = do
-    prog <- packStringIO path
-    argv <- vectorize (basename path:args)
-    envp <- vectorize (map (\ (name, val) -> name ++ ('=' : val)) env)
-    (if search then
-        _casm_ `` execvpe(%0,(char **)%1,(char **)%2);'' prog argv envp
-     else
-        _casm_ `` execve(%0,(char **)%1,(char **)%2);'' prog argv envp
-     )
-    syserr "executeFile"
-
-data ProcessStatus = Exited ExitCode
-                   | Terminated Signal
-                   | Stopped Signal
-                  deriving (Eq, Ord, Show)
-
-getProcessStatus :: Bool -> Bool -> ProcessID -> IO (Maybe ProcessStatus)
-getProcessStatus block stopped pid = do
-    wstat <- allocWords 1
-    pid   <-_casm_ ``%r = waitpid(%0, (int *)%1, %2);'' pid wstat
-               (waitOptions block stopped)
-    case (pid::Int) of
-      -1 -> syserr "getProcessStatus"
-      0  -> return Nothing
-      _  -> do ps <- decipherWaitStatus wstat
-              return (Just ps)
-
-getGroupProcessStatus :: Bool
-                      -> Bool
-                      -> ProcessGroupID
-                      -> IO (Maybe (ProcessID, ProcessStatus))
-getGroupProcessStatus block stopped pgid = do
-    wstat <- allocWords 1
-    pid   <-_casm_ ``%r = waitpid(%0, (int *)%1, %2);'' (-pgid) wstat
-                  (waitOptions block stopped)
-    case (pid::Int) of
-      -1 -> syserr "getGroupProcessStatus"
-      0  -> return Nothing
-      _  -> do ps <- decipherWaitStatus wstat
-              return (Just (pid, ps))
-
-getAnyProcessStatus :: Bool -> Bool -> IO (Maybe (ProcessID, ProcessStatus))
-getAnyProcessStatus block stopped =
-    getGroupProcessStatus block stopped 1          `catch`
-    \ _err -> syserr "getAnyProcessStatus"
-
-exitImmediately :: ExitCode -> IO ()
-exitImmediately exitcode = do
-    _casm_ ``_exit(%0);'' (exitcode2Int exitcode)
-    syserr "exitImmediately"
-  where
-    exitcode2Int ExitSuccess = 0
-    exitcode2Int (ExitFailure n) = n
-
-getEnvironment :: IO [(String, String)]
-getEnvironment = do
-    --WAS: env  <- unvectorize ``environ'' 0
-    -- does not work too well, since the lit-lit
-    -- is turned into an Addr that is only evaluated
-    -- once (environ is changed to point the most
-    -- current env. block after the addition of new entries).
-    envp <- _casm_ `` %r=environ; ''
-    env  <- unvectorize (envp::Addr) 0
-    return (map (split "") env)
-  where
-    split :: String -> String -> (String, String)
-    split x [] = error ("PosixProcPrim.getEnvironment:no `='? in: "++reverse x)
-    split x ('=' : xs) = (reverse x, xs)
-    split x (c:cs) = split (c:x) cs
-
-setEnvironment :: [(String, String)] -> IO ()
-setEnvironment pairs = do
-    env <- vectorize (map (\ (var,val) -> var ++ ('=' : val)) pairs)
-    nonzero_error (_casm_ ``%r = setenviron((char **)%0);'' env)
-       "setEnvironment"
-
-getEnvVar :: String -> IO String
-getEnvVar name = do
-    str <- packStringIO name
-    str <- _ccall_ getenv str
-    if str == nullAddr
-       then ioError (IOError Nothing NoSuchThing "getEnvVar" "no such environment variable")
-       else strcpy str
-
-setEnvVar :: String -> String -> IO ()
-setEnvVar name value = do
-    str <- packStringIO (name ++ ('=' : value))
-    nonzero_error (_casm_ ``%r = _setenv(%0);'' str) "setEnvVar"
-
-removeEnvVar :: String -> IO ()
-removeEnvVar name = do
-    str <- packStringIO name
-    nonzero_error (_ccall_ delenv str) "removeEnvVar"
-
-type Signal = Int
-
-nullSignal :: Signal
-nullSignal = 0
-
-backgroundRead, sigTTIN :: Signal
-backgroundRead = ``SIGTTIN''
-sigTTIN = ``SIGTTIN''
-
-backgroundWrite, sigTTOU :: Signal
-backgroundWrite = ``SIGTTOU''
-sigTTOU = ``SIGTTOU''
-
-#ifndef cygwin32_TARGET_OS
-continueProcess, sigCONT :: Signal
-continueProcess = ``SIGCONT''
-sigCONT = ``SIGCONT''
-#endif
-
-floatingPointException, sigFPE :: Signal
-floatingPointException = ``SIGFPE''
-sigFPE = ``SIGFPE''
-
-illegalInstruction, sigILL :: Signal
-illegalInstruction = ``SIGILL''
-sigILL = ``SIGILL''
-
-internalAbort, sigABRT ::Signal
-internalAbort = ``SIGABRT''
-sigABRT = ``SIGABRT''
-
-keyboardSignal, sigINT :: Signal
-keyboardSignal = ``SIGINT''
-sigINT = ``SIGINT''
-
-keyboardStop, sigTSTP :: Signal
-keyboardStop = ``SIGTSTP''
-sigTSTP = ``SIGTSTP''
-
-keyboardTermination, sigQUIT :: Signal
-keyboardTermination = ``SIGQUIT''
-sigQUIT = ``SIGQUIT''
-
-killProcess, sigKILL :: Signal
-killProcess = ``SIGKILL''
-sigKILL = ``SIGKILL''
-
-lostConnection, sigHUP :: Signal
-lostConnection = ``SIGHUP''
-sigHUP = ``SIGHUP''
-
-openEndedPipe, sigPIPE :: Signal
-openEndedPipe = ``SIGPIPE''
-sigPIPE = ``SIGPIPE''
-
-processStatusChanged, sigCHLD :: Signal
-processStatusChanged = ``SIGCHLD''
-sigCHLD = ``SIGCHLD''
-
-realTimeAlarm, sigALRM :: Signal
-realTimeAlarm = ``SIGALRM''
-sigALRM = ``SIGALRM''
-
-segmentationViolation, sigSEGV :: Signal
-segmentationViolation = ``SIGSEGV''
-sigSEGV = ``SIGSEGV''
-
-softwareStop, sigSTOP :: Signal
-softwareStop = ``SIGSTOP''
-sigSTOP = ``SIGSTOP''
-
-softwareTermination, sigTERM :: Signal
-softwareTermination = ``SIGTERM''
-sigTERM = ``SIGTERM''
-
-userDefinedSignal1, sigUSR1 :: Signal
-userDefinedSignal1 = ``SIGUSR1''
-sigUSR1 = ``SIGUSR1''
-
-userDefinedSignal2, sigUSR2 :: Signal
-userDefinedSignal2 = ``SIGUSR2''
-sigUSR2 = ``SIGUSR2''
-
-signalProcess :: Signal -> ProcessID -> IO ()
-signalProcess int pid =
-    nonzero_error (_ccall_ kill pid int) "signalProcess"
-
-raiseSignal :: Signal -> IO ()
-raiseSignal int = getProcessID >>= signalProcess int
-
-signalProcessGroup :: Signal -> ProcessGroupID -> IO ()
-signalProcessGroup int pgid = signalProcess int (-pgid)
-
-setStoppedChildFlag :: Bool -> IO Bool
-setStoppedChildFlag b = do
-    rc <- _casm_ ``%r = nocldstop; nocldstop = %0;'' (x::Int)
-    return (rc == (0::Int))
-  where
-    x = case b of {True -> 0; False -> 1}
-
-queryStoppedChildFlag :: IO Bool
-queryStoppedChildFlag = do
-    rc <- _casm_ ``%r = nocldstop;''
-    return (rc == (0::Int))
-
-data Handler = Default
-             | Ignore
-             | Catch (IO ())
-
-type SignalSet = ByteArray Int
-
-sigSetSize :: Int
-sigSetSize = ``sizeof(sigset_t)''
-
-emptySignalSet :: SignalSet
-emptySignalSet = unsafePerformPrimIO $ do
-    bytes <- allocChars sigSetSize
-    _casm_ ``(void) sigemptyset((sigset_t *)%0);'' bytes
-    freeze bytes
-
-fullSignalSet :: SignalSet
-fullSignalSet = unsafePerformPrimIO $ do
-    bytes <- allocChars sigSetSize
-    _casm_ ``(void) sigfillset((sigset_t *)%0);'' bytes
-    freeze bytes
-
-addSignal :: Signal -> SignalSet -> SignalSet
-addSignal int oldset = unsafePerformPrimIO $ do
-    bytes <- allocChars sigSetSize
-    _ccall_ stg_sigaddset bytes oldset int
-    freeze bytes
-
-inSignalSet :: Signal -> SignalSet -> Bool
-inSignalSet int sigset = unsafePerformPrimIO $ do
-    rc <- _casm_ ``%r = sigismember((sigset_t *)%0, %1);'' sigset int
-    return (rc == (1::Int))
-
-deleteSignal :: Signal -> SignalSet -> SignalSet
-deleteSignal int oldset = unsafePerformPrimIO $ do
-    bytes <- allocChars sigSetSize
-    _ccall_ stg_sigdelset bytes oldset int
-    freeze bytes
-
-installHandler :: Signal
-               -> Handler
-               -> Maybe SignalSet      -- other signals to block
-               -> IO Handler           -- old handler
-
-#ifdef __PARALLEL_HASKELL__
-installHandler = ioError (userError "installHandler: not available for Parallel Haskell")
-#else
-installHandler int handler maybe_mask = (
-    case handler of
-      Default -> _ccall_ stg_sig_default int mask
-      Ignore  -> _ccall_ stg_sig_ignore  int mask
-      Catch m -> do
-        sptr <- makeStablePtr (ioToPrimIO m)
-       _ccall_ stg_sig_catch int sptr mask
-    ) >>= \rc ->
-
-    if rc >= (0::Int) then do
-        osptr <- _casm_ ``%r = (StgStablePtr) (%0);'' rc
-        m     <- deRefStablePtr osptr
-       return (Catch m)
-    else if rc == ``STG_SIG_DFL'' then
-       return Default
-    else if rc == ``STG_SIG_IGN'' then
-       return Ignore
-    else
-       syserr "installHandler"
-  where
-    mask = case maybe_mask of
-            Nothing -> emptySignalSet
-             Just x -> x
-
-#endif {-!__PARALLEL_HASKELL__-}
-
-getSignalMask :: IO SignalSet
-getSignalMask = do
-    bytes <- allocChars sigSetSize
-    rc    <- _casm_ ``%r = sigprocmask(0, NULL, (sigset_t *)%0);'' bytes
-    if rc == (0::Int)
-       then freeze bytes
-       else syserr "getSignalMask"
-
-sigProcMask :: String -> Int -> SignalSet -> IO SignalSet
-sigProcMask name how sigset = do
-    bytes <- allocChars sigSetSize
-    rc <- _casm_ ``%r = sigprocmask(%0, (sigset_t *)%1, (sigset_t *)%2);''
-                how sigset bytes
-    if rc == (0::Int)
-       then freeze bytes
-       else syserr name
-
-setSignalMask :: SignalSet -> IO SignalSet
-setSignalMask = sigProcMask "setSignalMask" ``SIG_SETMASK''
-
-blockSignals :: SignalSet -> IO SignalSet
-blockSignals = sigProcMask "blockSignals" ``SIG_BLOCK''
-
-unBlockSignals :: SignalSet -> IO SignalSet
-unBlockSignals = sigProcMask "unBlockSignals" ``SIG_UNBLOCK''
-
-getPendingSignals :: IO SignalSet
-getPendingSignals = do
-    bytes <- allocChars sigSetSize
-    rc <- _casm_ ``%r = sigpending((sigset_t *)%0);'' bytes
-    if rc == (0::Int)
-       then freeze bytes
-       else syserr "getPendingSignals"
-
-#ifndef cygwin32_TARGET_OS
-awaitSignal :: Maybe SignalSet -> IO ()
-awaitSignal maybe_sigset = do
-    pause maybe_sigset
-    err <- getErrorCode
-    if err == interruptedOperation
-       then return ()
-       else syserr "awaitSignal"
-
-pause :: Maybe SignalSet -> IO ()
-pause maybe_sigset =
-  case maybe_sigset of
-   Nothing -> _casm_ ``(void) pause();''
-   Just sigset -> _casm_ ``(void) sigsuspend((sigset_t *)%0);'' sigset
-#endif
-
-scheduleAlarm :: Int -> IO Int
-scheduleAlarm (I# secs#) =
-    _ccall_ alarm (W# (int2Word# secs#))           >>= \ (W# w#) ->
-    return (I# (word2Int# w#))
-
-sleep :: Int -> IO ()
-sleep 0 = return ()
-sleep (I# secs#) = do
-    _ccall_ sleep (W# (int2Word# secs#))
-    return ()
-\end{code}
-
-Local utility functions
-
-\begin{code}
-
--- Get the trailing component of a path
-
-basename :: String -> String
-basename "" = ""
-basename (c:cs)
-  | c == '/' = basename cs
-  | otherwise = c : basename cs
-
--- Convert wait options to appropriate set of flags
-
-waitOptions :: Bool -> Bool -> Int
---             block   stopped
-waitOptions False False = ``WNOHANG''
-waitOptions False True  = ``(WNOHANG|WUNTRACED)''
-waitOptions True  False = 0
-waitOptions True  True  = ``WUNTRACED''
-
--- Turn a (ptr to a) wait status into a ProcessStatus
-
-decipherWaitStatus :: MutableByteArray s x -> IO ProcessStatus
-decipherWaitStatus wstat = do
-    exited <- _casm_ ``%r = WIFEXITED(*(int *)%0);'' wstat
-    if exited /= (0::Int)
-      then do
-        exitstatus <- _casm_ ``%r = WEXITSTATUS(*(int *)%0);'' wstat
-        if exitstatus == (0::Int)
-          then return (Exited ExitSuccess)
-          else return (Exited (ExitFailure exitstatus))
-      else do
-        signalled <- _casm_ ``%r = WIFSIGNALED(*(int *)%0);'' wstat
-        if signalled /= (0::Int)
-          then do
-               termsig <- _casm_ ``%r = WTERMSIG(*(int *)%0);'' wstat
-               return (Terminated termsig)
-          else do
-               stopsig <-_casm_ ``%r = WSTOPSIG(*(int *)%0);'' wstat
-               return (Stopped stopsig)
-\end{code}