packages feed

unix 2.7.3 → 2.8.0.0

raw patch · 64 files changed

+8200/−4272 lines, 64 filesdep +filepathdep ~basedep ~bytestringdep ~timenew-uploader

Dependencies added: filepath

Dependency ranges changed: base, bytestring, time

Files

System/Posix/ByteString/FilePath.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |@@ -29,7 +25,8 @@      throwErrnoPathIf_,      throwErrnoPathIfNull,      throwErrnoPathIfMinus1,-     throwErrnoPathIfMinus1_+     throwErrnoPathIfMinus1_,+     throwErrnoTwoPathsIfMinus1_   ) where  import Foreign hiding ( void )@@ -45,6 +42,9 @@ import Data.ByteString import Data.ByteString.Char8 as BC import Prelude hiding (FilePath)+#if !MIN_VERSION_base(4, 11, 0)+import Data.Monoid ((<>))+#endif  -- | A literal POSIX file path type RawFilePath = ByteString@@ -125,3 +125,9 @@ -- throwErrnoPathIfMinus1_ :: (Eq a, Num a) => String -> RawFilePath -> IO a -> IO () throwErrnoPathIfMinus1_  = throwErrnoPathIf_ (== -1)++-- | as 'throwErrnoTwoPathsIfMinus1_', but exceptions include two paths when appropriate.+--+throwErrnoTwoPathsIfMinus1_ :: (Eq a, Num a) => String -> RawFilePath -> RawFilePath -> IO a -> IO ()+throwErrnoTwoPathsIfMinus1_  loc path1 path2 =+    throwErrnoIfMinus1_ (loc <> " '" <> BC.unpack path1 <> "' to '" <> BC.unpack path2 <> "'")
System/Posix/Directory.hsc view
@@ -1,10 +1,6 @@ {-# LANGUAGE CApiFFI #-} {-# LANGUAGE NondecreasingIndentation #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |@@ -35,6 +31,7 @@    DirStream,    openDirStream,    readDirStream,+   readDirStreamMaybe,    rewindDirStream,    closeDirStream,    DirStreamOffset,@@ -51,6 +48,7 @@    changeWorkingDirectoryFd,   ) where +import Data.Maybe import System.IO.Error import System.Posix.Error import System.Posix.Types@@ -88,8 +86,20 @@ --   next directory entry (@struct dirent@) for the open directory --   stream @dp@, and returns the @d_name@ member of that --  structure.+--+--  Note that this function returns an empty filepath if the end of the+--  directory stream is reached. For a safer alternative use+--  'readDirStreamMaybe'. readDirStream :: DirStream -> IO FilePath-readDirStream (DirStream dirp) =+readDirStream = fmap (fromMaybe "") . readDirStreamMaybe++-- | @readDirStreamMaybe dp@ calls @readdir@ to obtain the+--   next directory entry (@struct dirent@) for the open directory+--   stream @dp@. It returns the @d_name@ member of that+--  structure wrapped in a @Just d_name@ if an entry was read and @Nothing@ if+--  the end of the directory stream was reached.+readDirStreamMaybe :: DirStream -> IO (Maybe FilePath)+readDirStreamMaybe (DirStream dirp) =   alloca $ \ptr_dEnt  -> loop ptr_dEnt  where   loop ptr_dEnt = do@@ -98,16 +108,16 @@     if (r == 0)          then do dEnt <- peek ptr_dEnt                  if (dEnt == nullPtr)-                    then return []+                    then return Nothing                     else do                      entry <- (d_name dEnt >>= peekFilePath)                      c_freeDirEnt dEnt-                     return entry+                     return $ Just entry          else do errno <- getErrno                  if (errno == eINTR) then loop ptr_dEnt else do                  let (Errno eo) = errno                  if (eo == 0)-                    then return []+                    then return Nothing                     else throwErrno "readDirStream"  -- traversing directories
System/Posix/Directory/ByteString.hsc view
@@ -1,10 +1,6 @@ {-# LANGUAGE CApiFFI #-} {-# LANGUAGE NondecreasingIndentation #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |@@ -35,6 +31,7 @@    DirStream,    openDirStream,    readDirStream,+   readDirStreamMaybe,    rewindDirStream,    closeDirStream,    DirStreamOffset,@@ -45,12 +42,13 @@    seekDirStream, #endif -   -- * The working dirctory+   -- * The working directory    getWorkingDirectory,    changeWorkingDirectory,    changeWorkingDirectoryFd,   ) where +import Data.Maybe import System.IO.Error import System.Posix.Types import Foreign@@ -89,8 +87,20 @@ --   next directory entry (@struct dirent@) for the open directory --   stream @dp@, and returns the @d_name@ member of that --  structure.+--+--  Note that this function returns an empty filepath if the end of the+--  directory stream is reached. For a safer alternative use+--  'readDirStreamMaybe'. readDirStream :: DirStream -> IO RawFilePath-readDirStream (DirStream dirp) =+readDirStream = fmap (fromMaybe BC.empty) . readDirStreamMaybe++-- | @readDirStreamMaybe dp@ calls @readdir@ to obtain the+--   next directory entry (@struct dirent@) for the open directory+--   stream @dp@. It returns the @d_name@ member of that+--  structure wrapped in a @Just d_name@ if an entry was read and @Nothing@ if+--  the end of the directory stream was reached.+readDirStreamMaybe :: DirStream -> IO (Maybe RawFilePath)+readDirStreamMaybe (DirStream dirp) =   alloca $ \ptr_dEnt  -> loop ptr_dEnt  where   loop ptr_dEnt = do@@ -99,16 +109,16 @@     if (r == 0)          then do dEnt <- peek ptr_dEnt                  if (dEnt == nullPtr)-                    then return BC.empty+                    then return Nothing                     else do                      entry <- (d_name dEnt >>= peekFilePath)                      c_freeDirEnt dEnt-                     return entry+                     return $ Just entry          else do errno <- getErrno                  if (errno == eINTR) then loop ptr_dEnt else do                  let (Errno eo) = errno                  if (eo == 0)-                    then return BC.empty+                    then return Nothing                     else throwErrno "readDirStream"  -- traversing directories
System/Posix/Directory/Common.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709-{-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif+{-# LANGUAGE Safe, CApiFFI #-}  ----------------------------------------------------------------------------- -- |@@ -22,6 +18,7 @@  module System.Posix.Directory.Common (        DirStream(..), CDir, CDirent, DirStreamOffset(..),+       unsafeOpenDirStreamFd,        rewindDirStream,        closeDirStream, #ifdef HAVE_SEEKDIR@@ -33,14 +30,48 @@        changeWorkingDirectoryFd,   ) where +import Control.Exception (mask_)+import Control.Monad (void, when) import System.Posix.Types-import Foreign+import Foreign hiding (void) import Foreign.C  newtype DirStream = DirStream (Ptr CDir)  data {-# CTYPE "DIR" #-} CDir data {-# CTYPE "struct dirent" #-} CDirent++-- | Call @fdopendir@ to obtain a directory stream for @fd@. @fd@ must not be+-- otherwise used after this.+--+-- On success, it is owned by the returned 'DirStream', which should be closed+-- via 'closeDirStream' when no longer needed.  On error, the file descriptor+-- is automatically closed and then an exception is thrown.  There is no code+-- path in which the file descriptor remains open and yet not owned by a+-- returned 'DirStream'.+--+-- The input file descriptor must not have been used with @threadWaitRead@ or+-- @threadWaitWrite@.+unsafeOpenDirStreamFd :: Fd -> IO DirStream+unsafeOpenDirStreamFd (Fd fd) = mask_ $ do+    ptr <- c_fdopendir fd+    when (ptr == nullPtr) $ do+        errno <- getErrno+        void $ c_close fd+        ioError (errnoToIOError "openDirStreamFd" errno Nothing Nothing)+    return $ DirStream ptr++-- We need c_close here, because 'closeFd' throws exceptions on error,+-- but we want to silently close the (presumably directory) descriptor.+foreign import ccall unsafe "HsUnix.h close"+   c_close :: CInt -> IO CInt++-- NOTE: It is /critical/ to use "capi" and "dirent.h" here, because system+-- headers on e.g. macOS alias this function, and linking directly to the+-- "fdopendir" symbol in libc leads to a crash!+--+foreign import capi unsafe "dirent.h fdopendir"+    c_fdopendir :: CInt -> IO (Ptr CDir)  -- | @rewindDirStream dp@ calls @rewinddir@ to reposition --   the directory stream @dp@ at the beginning of the directory.
+ System/Posix/Directory/Fd.hsc view
@@ -0,0 +1,7 @@+#include "HsUnix.h"++module System.Posix.Directory.Fd (+    unsafeOpenDirStreamFd+) where++import System.Posix.Directory.Common
+ System/Posix/Directory/Internals.hsc view
@@ -0,0 +1,17 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Directory.Internals+-- Copyright   :  (c) The University of Glasgow 2022+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX directory support (internal module, no PVP guarantees)+--+-----------------------------------------------------------------------------++module System.Posix.Directory.Internals ( DirStream(..), CDir, CDirent, DirStreamOffset(..) ) where++import System.Posix.Directory.Common
+ System/Posix/Directory/PosixPath.hsc view
@@ -0,0 +1,166 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE NondecreasingIndentation #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Directory.PosixPath+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- PosixPath based POSIX directory support+--+-----------------------------------------------------------------------------++#include "HsUnix.h"++-- hack copied from System.Posix.Files+#if !defined(PATH_MAX)+# define PATH_MAX 4096+#endif++module System.Posix.Directory.PosixPath (+   -- * Creating and removing directories+   createDirectory, removeDirectory,++   -- * Reading directories+   DirStream,+   openDirStream,+   readDirStream,+   rewindDirStream,+   closeDirStream,+   DirStreamOffset,+#ifdef HAVE_TELLDIR+   tellDirStream,+#endif+#ifdef HAVE_SEEKDIR+   seekDirStream,+#endif++   -- * The working directory+   getWorkingDirectory,+   changeWorkingDirectory,+   changeWorkingDirectoryFd,+  ) where++import System.IO.Error+import System.Posix.Types+import Foreign+import Foreign.C++import System.OsPath.Types+import GHC.IO.Encoding.UTF8 ( mkUTF8 )+import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )+import System.OsPath.Posix+import System.Posix.Directory hiding (createDirectory, openDirStream, readDirStream, getWorkingDirectory, changeWorkingDirectory, removeDirectory)+import qualified System.Posix.Directory.Common as Common+import System.Posix.PosixPath.FilePath++-- | @createDirectory dir mode@ calls @mkdir@ to+--   create a new directory, @dir@, with permissions based on+--  @mode@.+createDirectory :: PosixPath -> FileMode -> IO ()+createDirectory name mode =+  withFilePath name $ \s ->+    throwErrnoPathIfMinus1Retry_ "createDirectory" name (c_mkdir s mode)+    -- POSIX doesn't allow mkdir() to return EINTR, but it does on+    -- OS X (#5184), so we need the Retry variant here.++foreign import ccall unsafe "mkdir"+  c_mkdir :: CString -> CMode -> IO CInt++-- | @openDirStream dir@ calls @opendir@ to obtain a+--   directory stream for @dir@.+openDirStream :: PosixPath -> IO DirStream+openDirStream name =+  withFilePath name $ \s -> do+    dirp <- throwErrnoPathIfNullRetry "openDirStream" name $ c_opendir s+    return (Common.DirStream dirp)++foreign import capi unsafe "HsUnix.h opendir"+   c_opendir :: CString  -> IO (Ptr Common.CDir)++-- | @readDirStream dp@ calls @readdir@ to obtain the+--   next directory entry (@struct dirent@) for the open directory+--   stream @dp@, and returns the @d_name@ member of that+--  structure.+readDirStream :: DirStream -> IO PosixPath+readDirStream (Common.DirStream dirp) = alloca $ \ptr_dEnt  -> loop ptr_dEnt+ where+  loop ptr_dEnt = do+    resetErrno+    r <- c_readdir dirp ptr_dEnt+    if (r == 0)+         then do dEnt <- peek ptr_dEnt+                 if (dEnt == nullPtr)+                    then return mempty+                    else do+                     entry <- (d_name dEnt >>= peekFilePath)+                     c_freeDirEnt dEnt+                     return entry+         else do errno <- getErrno+                 if (errno == eINTR) then loop ptr_dEnt else do+                 let (Errno eo) = errno+                 if (eo == 0)+                    then return mempty+                    else throwErrno "readDirStream"++-- traversing directories+foreign import ccall unsafe "__hscore_readdir"+  c_readdir  :: Ptr Common.CDir -> Ptr (Ptr Common.CDirent) -> IO CInt++foreign import ccall unsafe "__hscore_free_dirent"+  c_freeDirEnt  :: Ptr Common.CDirent -> IO ()++foreign import ccall unsafe "__hscore_d_name"+  d_name :: Ptr Common.CDirent -> IO CString+++-- | @getWorkingDirectory@ calls @getcwd@ to obtain the name+--   of the current working directory.+getWorkingDirectory :: IO PosixPath+getWorkingDirectory = go (#const PATH_MAX)+  where+    go bytes = do+        r <- allocaBytes bytes $ \buf -> do+            buf' <- c_getcwd buf (fromIntegral bytes)+            if buf' /= nullPtr+                then do s <- peekFilePath buf+                        return (Just s)+                else do errno <- getErrno+                        if errno == eRANGE+                            -- we use Nothing to indicate that we should+                            -- try again with a bigger buffer+                            then return Nothing+                            else throwErrno "getWorkingDirectory"+        maybe (go (2 * bytes)) return r++foreign import ccall unsafe "getcwd"+   c_getcwd   :: Ptr CChar -> CSize -> IO (Ptr CChar)++-- | @changeWorkingDirectory dir@ calls @chdir@ to change+--   the current working directory to @dir@.+changeWorkingDirectory :: PosixPath -> IO ()+changeWorkingDirectory path =+  modifyIOError (`ioeSetFileName` (_toStr path)) $+    withFilePath path $ \s ->+       throwErrnoIfMinus1Retry_ "changeWorkingDirectory" (c_chdir s)++foreign import ccall unsafe "chdir"+   c_chdir :: CString -> IO CInt++removeDirectory :: PosixPath -> IO ()+removeDirectory path =+  modifyIOError (`ioeSetFileName` _toStr path) $+    withFilePath path $ \s ->+       throwErrnoIfMinus1Retry_ "removeDirectory" (c_rmdir s)++foreign import ccall unsafe "rmdir"+   c_rmdir :: CString -> IO CInt++_toStr :: PosixPath -> String+_toStr fp = either (error . show) id $ decodeWith (mkUTF8 TransliterateCodingFailure) fp+
System/Posix/DynamicLinker.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.DynamicLinker@@ -56,17 +52,15 @@ #include "HsUnix.h"  import Control.Exception        ( bracket )-import Control.Monad    ( liftM ) import Foreign import System.Posix.Internals ( withFilePath )  dlopen :: FilePath -> [RTLDFlags] -> IO DL-dlopen path flags = do-  withFilePath path $ \ p -> do-    liftM DLHandle $ throwDLErrorIf "dlopen" (== nullPtr) $ c_dlopen p (packRTLDFlags flags)+dlopen path flags = withFilePath path $ \p -> DLHandle <$>+  throwDLErrorIf "dlopen" (== nullPtr) (c_dlopen p (packRTLDFlags flags)) -withDL :: String -> [RTLDFlags] -> (DL -> IO a) -> IO a+withDL :: FilePath -> [RTLDFlags] -> (DL -> IO a) -> IO a withDL file flags f = bracket (dlopen file flags) (dlclose) f -withDL_ :: String -> [RTLDFlags] -> (DL -> IO a) -> IO ()+withDL_ :: FilePath -> [RTLDFlags] -> (DL -> IO a) -> IO () withDL_ file flags f = withDL file flags f >> return ()
System/Posix/DynamicLinker/ByteString.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |@@ -57,14 +53,12 @@ #include "HsUnix.h"  import Control.Exception        ( bracket )-import Control.Monad    ( liftM ) import Foreign import System.Posix.ByteString.FilePath  dlopen :: RawFilePath -> [RTLDFlags] -> IO DL-dlopen path flags = do-  withFilePath path $ \ p -> do-    liftM DLHandle $ throwDLErrorIf "dlopen" (== nullPtr) $ c_dlopen p (packRTLDFlags flags)+dlopen path flags = withFilePath path $ \p -> DLHandle <$>+  throwDLErrorIf "dlopen" (== nullPtr) (c_dlopen p (packRTLDFlags flags))  withDL :: RawFilePath -> [RTLDFlags] -> (DL -> IO a) -> IO a withDL file flags f = bracket (dlopen file flags) (dlclose) f
System/Posix/DynamicLinker/Common.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.DynamicLinker.Common
System/Posix/DynamicLinker/Module.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.DynamicLinker.Module
System/Posix/DynamicLinker/Module/ByteString.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |
System/Posix/DynamicLinker/Prim.hsc view
@@ -1,7 +1,5 @@ {-# LANGUAGE Trustworthy #-}-#if __GLASGOW_HASKELL__ >= 709-{-# OPTIONS_GHC -fno-warn-trustworthy-safe #-}-#endif+{-# OPTIONS_GHC -Wno-trustworthy-safe #-}  ----------------------------------------------------------------------------- -- |@@ -43,11 +41,16 @@ import Foreign.C.Types import Foreign.C.String ( CString ) +#if !defined(HAVE_DLFCN_H)+import Control.Exception ( throw )+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif  -- |On some hosts (e.g. SuSe and Ubuntu Linux) @RTLD_NEXT@ (and -- @RTLD_DEFAULT@) are not visible without setting the macro -- @_GNU_SOURCE@. Since we don\'t want to define this macro, you can use--- the function 'haveRtldNext' to check wether the flag `Next` is+-- the function 'haveRtldNext' to check whether the flag `Next` is -- available. Ideally, this will be optimized by the compiler so that it -- should be as efficient as an @#ifdef@. --@@ -90,11 +93,20 @@ packRTLDFlags flags = foldl (\ s f -> (packRTLDFlag f) .|. s) 0 flags  packRTLDFlag :: RTLDFlags -> CInt+#if defined(HAVE_DLFCN_H)+ packRTLDFlag RTLD_LAZY = #const RTLD_LAZY packRTLDFlag RTLD_NOW = #const RTLD_NOW packRTLDFlag RTLD_GLOBAL = #const RTLD_GLOBAL packRTLDFlag RTLD_LOCAL = #const RTLD_LOCAL +#else++{-# WARNING packRTLDFlag+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_DLFCN_H@)" #-}+packRTLDFlag _ = throw (ioeSetLocation unsupportedOperation "packRTLDFlag")++#endif // HAVE_DLFCN_H  -- |Flags for 'System.Posix.DynamicLinker.dlsym'. Notice that 'Next' -- might not be available on your particular platform! Use
System/Posix/Env.hsc view
@@ -1,9 +1,5 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Env@@ -42,12 +38,6 @@ import Data.Maybe (fromMaybe) import System.Posix.Internals -#if !MIN_VERSION_base(4,7,0)--- needed for backported local 'newFilePath' binding in 'putEnv'-import GHC.IO.Encoding (getFileSystemEncoding)-import qualified GHC.Foreign as GHC (newCString)-#endif- -- |'getEnv' looks up a variable in the environment.  getEnv ::@@ -56,7 +46,7 @@ getEnv name = do   litstring <- withFilePath name c_getenv   if litstring /= nullPtr-     then liftM Just $ peekFilePath litstring+     then Just <$> peekFilePath litstring      else return Nothing  -- |'getEnvDefault' is a wrapper around 'getEnv' where the@@ -67,7 +57,7 @@   String    {- ^ variable name                    -} ->   String    {- ^ fallback value                   -} ->   IO String {- ^ variable value or fallback value -}-getEnvDefault name fallback = liftM (fromMaybe fallback) (getEnv name)+getEnvDefault name fallback = fromMaybe fallback <$> getEnv name  foreign import ccall unsafe "getenv"    c_getenv :: CString -> IO CString@@ -150,11 +140,6 @@                      -- According to SUSv2, the string passed to putenv                      -- becomes part of the environment. #7342                      throwErrnoIfMinus1_ "putenv" (c_putenv s)-#if !MIN_VERSION_base(4,7,0)-    where-      newFilePath :: FilePath -> IO CString-      newFilePath fp = getFileSystemEncoding >>= \enc -> GHC.newCString enc fp-#endif  foreign import ccall unsafe "putenv"    c_putenv :: CString -> IO CInt
System/Posix/Env/ByteString.hsc view
@@ -52,7 +52,7 @@ getEnv name = do   litstring <- B.useAsCString name c_getenv   if litstring /= nullPtr-     then liftM Just $ B.packCString litstring+     then Just <$> B.packCString litstring      else return Nothing  -- |'getEnvDefault' is a wrapper around 'getEnv' where the@@ -63,7 +63,7 @@   ByteString    {- ^ variable name                    -} ->   ByteString    {- ^ fallback value                   -} ->   IO ByteString {- ^ variable value or fallback value -}-getEnvDefault name fallback = liftM (fromMaybe fallback) (getEnv name)+getEnvDefault name fallback = fromMaybe fallback <$> getEnv name  foreign import ccall unsafe "getenv"    c_getenv :: CString -> IO CString@@ -104,7 +104,7 @@ -- |'setEnvironment' resets the entire environment to the given list of -- @(key,value)@ pairs. ----- @since 2.7.3+-- @since 2.8.0.0 setEnvironment ::   [(ByteString,ByteString)] {- ^ @[(key,value)]@ -} ->   IO ()@@ -199,7 +199,7 @@   alloca $ \ p_argc ->   alloca $ \ p_argv -> do    getProgArgv p_argc p_argv-   p    <- fromIntegral `liftM` peek p_argc+   p    <- fromIntegral <$> peek p_argc    argv <- peek p_argv    peekArray (p - 1) (advancePtr argv 1) >>= mapM B.packCString 
+ System/Posix/Env/PosixString.hsc view
@@ -0,0 +1,206 @@+{-# LANGUAGE CApiFFI #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Env.PosixString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX environment support+--+-----------------------------------------------------------------------------++module System.Posix.Env.PosixString (+       -- * Environment Variables+        getEnv+        , getEnvDefault+        , getEnvironmentPrim+        , getEnvironment+        , setEnvironment+        , putEnv+        , setEnv+        , unsetEnv+        , clearEnv++       -- * Program arguments+       , getArgs+) where++#include "HsUnix.h"++import Control.Monad+import Foreign+import Foreign.C+import Data.Maybe       ( fromMaybe )++import GHC.IO.Encoding.UTF8 ( mkUTF8 )+import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )+import System.Posix.Env ( clearEnv )+import System.OsPath.Posix+import System.OsString.Internal.Types+import qualified System.OsPath.Data.ByteString.Short as B+import Data.ByteString.Short.Internal ( copyToPtr )++-- |'getEnv' looks up a variable in the environment.++getEnv ::+  PosixString            {- ^ variable name  -} ->+  IO (Maybe PosixString) {- ^ variable value -}+getEnv (PS name) = do+  litstring <- B.useAsCString name c_getenv+  if litstring /= nullPtr+     then (Just . PS) <$> B.packCString litstring+     else return Nothing++-- |'getEnvDefault' is a wrapper around 'getEnv' where the+-- programmer can specify a fallback as the second argument, which will be+-- used if the variable is not found in the environment.++getEnvDefault ::+  PosixString    {- ^ variable name                    -} ->+  PosixString    {- ^ fallback value                   -} ->+  IO PosixString {- ^ variable value or fallback value -}+getEnvDefault name fallback = fromMaybe fallback <$> getEnv name++foreign import ccall unsafe "getenv"+   c_getenv :: CString -> IO CString++getEnvironmentPrim :: IO [PosixString]+getEnvironmentPrim = do+  c_environ <- getCEnviron+  arr <- peekArray0 nullPtr c_environ+  mapM (fmap PS . B.packCString) arr++getCEnviron :: IO (Ptr CString)+#if HAVE__NSGETENVIRON+-- You should not access @char **environ@ directly on Darwin in a bundle/shared library.+-- See #2458 and http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man7/environ.7.html+getCEnviron = nsGetEnviron >>= peek++foreign import ccall unsafe "_NSGetEnviron"+   nsGetEnviron :: IO (Ptr (Ptr CString))+#else+getCEnviron = peek c_environ_p++foreign import ccall unsafe "&environ"+   c_environ_p :: Ptr (Ptr CString)+#endif++-- |'getEnvironment' retrieves the entire environment as a+-- list of @(key,value)@ pairs.++getEnvironment :: IO [(PosixString,PosixString)] {- ^ @[(key,value)]@ -}+getEnvironment = do+  env <- getEnvironmentPrim+  return $ map (dropEq . (B.break ((==) _equal)) . getPosixString) env+ where+   dropEq (x,y)+      | B.head y == _equal = (PS x, PS (B.tail y))+      | otherwise          = error $ "getEnvironment: insane variable " ++ _toStr x++-- |'setEnvironment' resets the entire environment to the given list of+-- @(key,value)@ pairs.+setEnvironment ::+  [(PosixString,PosixString)] {- ^ @[(key,value)]@ -} ->+  IO ()+setEnvironment env = do+  clearEnv+  forM_ env $ \(key,value) ->+    setEnv key value True {-overwrite-}++-- |The 'unsetEnv' function deletes all instances of the variable name+-- from the environment.++unsetEnv :: PosixString {- ^ variable name -} -> IO ()+#if HAVE_UNSETENV+# if !UNSETENV_RETURNS_VOID+unsetEnv (PS name) = B.useAsCString name $ \ s ->+  throwErrnoIfMinus1_ "unsetenv" (c_unsetenv s)++-- POSIX.1-2001 compliant unsetenv(3)+foreign import capi unsafe "HsUnix.h unsetenv"+   c_unsetenv :: CString -> IO CInt+# else+unsetEnv name = B.useAsCString name c_unsetenv++-- pre-POSIX unsetenv(3) returning @void@+foreign import capi unsafe "HsUnix.h unsetenv"+   c_unsetenv :: CString -> IO ()+# endif+#else+unsetEnv name = putEnv (name <> PosixString (B.pack "="))+#endif++-- |'putEnv' function takes an argument of the form @name=value@+-- and is equivalent to @setEnv(key,value,True{-overwrite-})@.+putEnv :: PosixString {- ^ "key=value" -} -> IO ()+putEnv (PS sbs) = do+  buf <- mallocBytes (l+1)+  copyToPtr sbs 0 buf (fromIntegral l)+  pokeByteOff buf l (0::Word8)+  throwErrnoIfMinus1_ "putenv" (c_putenv buf)+ where l = B.length sbs+++foreign import ccall unsafe "putenv"+   c_putenv :: CString -> IO CInt++{- |The 'setEnv' function inserts or resets the environment variable name in+     the current environment list.  If the variable @name@ does not exist in the+     list, it is inserted with the given value.  If the variable does exist,+     the argument @overwrite@ is tested; if @overwrite@ is @False@, the variable is+     not reset, otherwise it is reset to the given value.+-}++setEnv ::+  PosixString {- ^ variable name  -} ->+  PosixString {- ^ variable value -} ->+  Bool       {- ^ overwrite      -} ->+  IO ()+#ifdef HAVE_SETENV+setEnv (PS key) (PS value) ovrwrt = do+  B.useAsCString key $ \ keyP ->+    B.useAsCString value $ \ valueP ->+      throwErrnoIfMinus1_ "setenv" $+        c_setenv keyP valueP (fromIntegral (fromEnum ovrwrt))++foreign import ccall unsafe "setenv"+   c_setenv :: CString -> CString -> CInt -> IO CInt+#else+setEnv key value True = putEnv (key++"="++value)+setEnv key value False = do+  res <- getEnv key+  case res of+    Just _  -> return ()+    Nothing -> putEnv (key++"="++value)+#endif++-- | Computation 'getArgs' returns a list of the program's command+-- line arguments (not including the program name), as 'PosixString's.+--+-- Unlike 'System.Environment.getArgs', this function does no Unicode+-- decoding of the arguments; you get the exact bytes that were passed+-- to the program by the OS.  To interpret the arguments as text, some+-- Unicode decoding should be applied.+--+getArgs :: IO [PosixString]+getArgs =+  alloca $ \ p_argc ->+  alloca $ \ p_argv -> do+   getProgArgv p_argc p_argv+   p    <- fromIntegral <$> peek p_argc+   argv <- peek p_argv+   peekArray (p - 1) (advancePtr argv 1) >>= mapM (fmap PS . B.packCString)++foreign import ccall unsafe "getProgArgv"+  getProgArgv :: Ptr CInt -> Ptr (Ptr CString) -> IO ()++_equal :: Word8+_equal = 0x3d++_toStr :: B.ShortByteString -> String+_toStr = either (error . show) id . decodeWith (mkUTF8 TransliterateCodingFailure) . PosixString
System/Posix/Error.hs view
@@ -1,9 +1,4 @@-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Error
System/Posix/Fcntl.hsc view
@@ -1,9 +1,5 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Fcntl
System/Posix/Files.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif {-# LANGUAGE CApiFFI #-}  -----------------------------------------------------------------------------@@ -52,7 +48,7 @@     fileAccess, fileExist,      -- * File status-    FileStatus,+    FileStatus(..),     -- ** Obtaining file status     getFileStatus, getFdStatus, getSymbolicLinkStatus,     -- ** Querying file status@@ -63,6 +59,9 @@     isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,     isDirectory, isSymbolicLink, isSocket, +    fileBlockSize,+    fileBlocks,+     -- * Creation     createNamedPipe,     createDevice,@@ -103,8 +102,24 @@ import System.Posix.Error import System.Posix.Internals +#if !MIN_VERSION_base(4, 11, 0)+import Data.Monoid ((<>))+#endif+ import Data.Time.Clock.POSIX (POSIXTime) +#if !defined(HAVE_MKNOD)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++-- throwErrnoTwoPathsIfMinus1_+--+-- | For operations that require two paths (e.g., renaming a file)+throwErrnoTwoPathsIfMinus1_ :: (Eq a, Num a) => String -> FilePath -> FilePath -> IO a -> IO ()+throwErrnoTwoPathsIfMinus1_ loc path1 path2 =+  throwErrnoIfMinus1_ (loc <> " '" <> path1 <> "' to '" <> path2 <> "'")+ -- ----------------------------------------------------------------------------- -- chmod() @@ -202,6 +217,13 @@   withFilePath name $ \s ->     throwErrnoPathIfMinus1_ "createNamedPipe" name (c_mkfifo s mode) +#if !defined(HAVE_MKNOD)++{-# WARNING createDevice "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_MKNOD@)" #-}+createDevice :: FilePath -> FileMode -> DeviceID -> IO ()+createDevice _ _ _ = ioError (ioeSetLocation unsupportedOperation "createDevice")++#else -- | @createDevice path mode dev@ creates either a regular or a special file -- depending on the value of @mode@ (and @dev@).  @mode@ will normally be either -- 'blockSpecialMode' or 'characterSpecialMode'.  May fail with@@ -218,6 +240,8 @@ foreign import capi unsafe "HsUnix.h mknod"   c_mknod :: CString -> CMode -> CDev -> IO CInt +#endif // HAVE_MKNOD+ -- ----------------------------------------------------------------------------- -- Hard links @@ -229,7 +253,7 @@ createLink name1 name2 =   withFilePath name1 $ \s1 ->   withFilePath name2 $ \s2 ->-  throwErrnoPathIfMinus1_ "createLink" name1 (c_link s1 s2)+  throwErrnoTwoPathsIfMinus1_ "createLink" name1 name2 (c_link s1 s2)  -- | @removeLink path@ removes the link named @path@. --@@ -242,18 +266,18 @@ -- ----------------------------------------------------------------------------- -- Symbolic Links --- | @createSymbolicLink file1 file2@ creates a symbolic link named @file2@--- which points to the file @file1@.+-- | @createSymbolicLink name1 name2@ creates a symbolic link named @name2@+-- which points to the file @name1@. -- -- Symbolic links are interpreted at run-time as if the contents of the link -- had been substituted into the path being followed to find a file or directory. -- -- Note: calls @symlink@. createSymbolicLink :: FilePath -> FilePath -> IO ()-createSymbolicLink file1 file2 =-  withFilePath file1 $ \s1 ->-  withFilePath file2 $ \s2 ->-  throwErrnoPathIfMinus1_ "createSymbolicLink" file2 (c_symlink s1 s2)+createSymbolicLink name1 name2 =+  withFilePath name1 $ \s1 ->+  withFilePath name2 $ \s2 ->+  throwErrnoTwoPathsIfMinus1_ "createSymbolicLink" name1 name2 (c_symlink s1 s2)  foreign import ccall unsafe "symlink"   c_symlink :: CString -> CString -> IO CInt@@ -291,7 +315,7 @@ rename name1 name2 =   withFilePath name1 $ \s1 ->   withFilePath name2 $ \s2 ->-  throwErrnoPathIfMinus1_ "rename" name1 (c_rename s1 s2)+  throwErrnoTwoPathsIfMinus1_  "rename" name1 name2 (c_rename s1 s2)  foreign import ccall unsafe "rename"    c_rename :: CString -> CString -> IO CInt@@ -345,8 +369,11 @@  -- | Like 'setFileTimes' but timestamps can have sub-second resolution. ----- Note: calls @utimensat@ or @utimes@.+-- Note: calls @utimensat@ or @utimes@.  Support for high resolution timestamps+--   is filesystem dependent with the following limitations: --+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+-- -- @since 2.7.0.0 setFileTimesHiRes :: FilePath -> POSIXTime -> POSIXTime -> IO () #ifdef HAVE_UTIMENSAT@@ -366,8 +393,11 @@ -- This operation is not supported on all platforms. On these platforms, -- this function will raise an exception. ----- Note: calls @utimensat@ or @lutimes@.+-- Note: calls @utimensat@ or @lutimes@. Support for high resolution timestamps+--   is filesystem dependent with the following limitations: --+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+-- -- @since 2.7.0.0 setSymbolicLinkTimesHiRes :: FilePath -> POSIXTime -> POSIXTime -> IO () #if HAVE_UTIMENSAT@@ -383,6 +413,9 @@       throwErrnoPathIfMinus1_ "setSymbolicLinkTimesHiRes" name $         c_lutimes s times #else+{-# WARNING setSymbolicLinkTimesHiRes+ "System.Posix.Files.setSymbolicLinkTImesHiRes: not available on this platform"+  #-} setSymbolicLinkTimesHiRes =   error "setSymbolicLinkTimesHiRes: not available on this platform" #endif@@ -409,6 +442,9 @@   withFilePath name $ \s ->     throwErrnoPathIfMinus1_ "touchSymbolicLink" name (c_lutimes s nullPtr) #else+{-#+  WARNING touchSymbolicLink "System.Posix.Files.touchSymbolicLink: not available on this platform"+  #-} touchSymbolicLink =   error "touchSymbolicLink: not available on this platform" #endif
System/Posix/Files/ByteString.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif {-# LANGUAGE CApiFFI #-}  -----------------------------------------------------------------------------@@ -63,6 +59,9 @@     isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,     isDirectory, isSymbolicLink, isSocket, +    fileBlockSize,+    fileBlocks,+     -- * Creation     createNamedPipe,     createDevice,@@ -110,6 +109,11 @@  import Data.Time.Clock.POSIX (POSIXTime) +#if !defined(HAVE_MKNOD)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ -- ----------------------------------------------------------------------------- -- chmod() @@ -208,6 +212,14 @@   withFilePath name $ \s ->     throwErrnoPathIfMinus1_ "createNamedPipe" name (c_mkfifo s mode) +#if !defined(HAVE_MKNOD)++{-# WARNING createDevice "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_MKNOD@)" #-}+createDevice :: RawFilePath -> FileMode -> DeviceID -> IO ()+createDevice _ _ _ = ioError (ioeSetLocation unsupportedOperation "createDevice")++#else+ -- | @createDevice path mode dev@ creates either a regular or a special file -- depending on the value of @mode@ (and @dev@).  @mode@ will normally be either -- 'blockSpecialMode' or 'characterSpecialMode'.  May fail with@@ -224,6 +236,8 @@ foreign import capi unsafe "HsUnix.h mknod"   c_mknod :: CString -> CMode -> CDev -> IO CInt +#endif // HAVE_MKNOD+ -- ----------------------------------------------------------------------------- -- Hard links @@ -235,7 +249,7 @@ createLink name1 name2 =   withFilePath name1 $ \s1 ->   withFilePath name2 $ \s2 ->-  throwErrnoPathIfMinus1_ "createLink" name1 (c_link s1 s2)+  throwErrnoTwoPathsIfMinus1_ "createLink" name1 name2 (c_link s1 s2)  -- | @removeLink path@ removes the link named @path@. --@@ -256,10 +270,10 @@ -- -- Note: calls @symlink@. createSymbolicLink :: RawFilePath -> RawFilePath -> IO ()-createSymbolicLink file1 file2 =-  withFilePath file1 $ \s1 ->-  withFilePath file2 $ \s2 ->-  throwErrnoPathIfMinus1_ "createSymbolicLink" file2 (c_symlink s1 s2)+createSymbolicLink name1 name2 =+  withFilePath name1 $ \s1 ->+  withFilePath name2 $ \s2 ->+  throwErrnoTwoPathsIfMinus1_ "createSymbolicLink" name1 name2 (c_symlink s1 s2)  foreign import ccall unsafe "symlink"   c_symlink :: CString -> CString -> IO CInt@@ -297,7 +311,7 @@ rename name1 name2 =   withFilePath name1 $ \s1 ->   withFilePath name2 $ \s2 ->-  throwErrnoPathIfMinus1_ "rename" name1 (c_rename s1 s2)+  throwErrnoTwoPathsIfMinus1_ "rename" name1 name2 (c_rename s1 s2)  foreign import ccall unsafe "rename"    c_rename :: CString -> CString -> IO CInt@@ -351,7 +365,11 @@  -- | Like 'setFileTimes' but timestamps can have sub-second resolution. ----- Note: calls @utimensat@ or @utimes@.+-- Note: calls @utimensat@ or @utimes@. Support for high resolution timestamps+--   is filesystem dependent with the following limitations:+--+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+-- setFileTimesHiRes :: RawFilePath -> POSIXTime -> POSIXTime -> IO () #ifdef HAVE_UTIMENSAT setFileTimesHiRes name atime mtime =@@ -370,7 +388,11 @@ -- This operation is not supported on all platforms. On these platforms, -- this function will raise an exception. ----- Note: calls @utimensat@ or @lutimes@.+-- Note: calls @utimensat@ or @lutimes@. Support for high resolution timestamps+--   is filesystem dependent with the following limitations:+--+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+-- setSymbolicLinkTimesHiRes :: RawFilePath -> POSIXTime -> POSIXTime -> IO () #if HAVE_UTIMENSAT setSymbolicLinkTimesHiRes name atime mtime =@@ -385,6 +407,7 @@       throwErrnoPathIfMinus1_ "setSymbolicLinkTimesHiRes" name $         c_lutimes s times #else+{-# WARNING setSymbolicLinkTimesHiRes "setSymbolicLinkTimesHiRes: not available on this platform" #-} setSymbolicLinkTimesHiRes =   error "setSymbolicLinkTimesHiRes: not available on this platform" #endif@@ -409,6 +432,7 @@   withFilePath name $ \s ->     throwErrnoPathIfMinus1_ "touchSymbolicLink" name (c_lutimes s nullPtr) #else+{-# WARNING touchSymbolicLink "touchSymbolicLink: not available on this platform" #-} touchSymbolicLink =   error "touchSymbolicLink: not available on this platform" #endif
System/Posix/Files/Common.hsc view
@@ -56,6 +56,9 @@     isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,     isDirectory, isSymbolicLink, isSocket, +    fileBlockSize,+    fileBlocks,+     -- * Setting file sizes     setFdSize, @@ -231,7 +234,12 @@ -- 'FileStatus' type. -- -- Note: see @chmod@.-newtype FileStatus = FileStatus (ForeignPtr CStat)+--+-- Limitations: Support for high resolution timestamps is filesystem dependent:+--+-- - HFS+ volumes on OS X only support whole-second times.+--+newtype FileStatus = FileStatus (ForeignPtr CStat) -- ^ The constructor is considered internal and may change.  -- | ID of the device on which this file resides. deviceID         :: FileStatus -> DeviceID@@ -250,17 +258,28 @@ -- | Size of the file in bytes. If this file is a symbolic link the size is -- the length of the pathname it contains. fileSize         :: FileStatus -> FileOffset+-- | Number of blocks allocated for this file, in units of+-- 512-bytes. Returns @Nothing@ if @st_blocks@ is not supported on this+-- platform.+fileBlocks       :: FileStatus -> Maybe CBlkCnt+-- | Gives the preferred block size for efficient filesystem I/O in+-- bytes. Returns @Nothing@ if @st_blocksize@ is not supported on this+-- platform.+fileBlockSize    :: FileStatus -> Maybe CBlkSize -- | Time of last access. accessTime       :: FileStatus -> EpochTime--- | Time of last access in sub-second resolution.+-- | Time of last access in sub-second resolution. Depends on the timestamp resolution of the+-- underlying filesystem. accessTimeHiRes  :: FileStatus -> POSIXTime -- | Time of last modification. modificationTime :: FileStatus -> EpochTime--- | Time of last modification in sub-second resolution.+-- | Time of last modification in sub-second resolution. Depends on the timestamp resolution of the+-- underlying filesystem. modificationTimeHiRes :: FileStatus -> POSIXTime -- | Time of last status change (i.e. owner, group, link count, mode, etc.). statusChangeTime :: FileStatus -> EpochTime -- | Time of last status change (i.e. owner, group, link count, mode, etc.) in sub-second resolution.+-- Depends on the timestamp resolution of the underlying filesystem. statusChangeTimeHiRes :: FileStatus -> POSIXTime  deviceID (FileStatus stat) =@@ -286,6 +305,19 @@ statusChangeTime (FileStatus stat) =   unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_ctime) +#ifdef HAVE_STRUCT_STAT_ST_BLOCKS+fileBlocks (FileStatus stat) =+  Just $ unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_blocks)+#else+fileBlocks _ = Nothing+#endif+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE+fileBlockSize (FileStatus stat) =+  Just $ unsafePerformIO $ withForeignPtr stat $ (#peek struct stat, st_blksize)+#else+fileBlockSize _ = Nothing+#endif+ accessTimeHiRes (FileStatus stat) =   unsafePerformIO $ withForeignPtr stat $ \stat_ptr -> do     sec  <- (#peek struct stat, st_atime) stat_ptr :: IO EpochTime@@ -465,8 +497,12 @@ -- This operation is not supported on all platforms. On these platforms, -- this function will raise an exception. ----- Note: calls @futimens@ or @futimes@.+-- Note: calls @futimens@ or @futimes@. Support for high resolution timestamps+--   is filesystem dependent with the following limitations: --+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+--+-- -- @since 2.7.0.0 setFdTimesHiRes :: Fd -> POSIXTime -> POSIXTime -> IO () #if HAVE_FUTIMENS@@ -478,6 +514,7 @@   withArray [toCTimeVal atime, toCTimeVal mtime] $ \times ->     throwErrnoIfMinus1_ "setFdTimesHiRes" (c_futimes fd times) #else+{-# WARNING setFdTimesHiRes "setFdTimesHiRes: not available on this platform" #-} setFdTimesHiRes =   error "setSymbolicLinkTimesHiRes: not available on this platform" #endif@@ -494,6 +531,7 @@ touchFd (Fd fd) =   throwErrnoIfMinus1_ "touchFd" (c_futimes fd nullPtr) #else+{-# WARNING touchFd "touchFd: not available on this platform" #-} touchFd =   error "touchFd: not available on this platform" #endif
+ System/Posix/Files/PosixString.hsc view
@@ -0,0 +1,453 @@+{-# LANGUAGE CApiFFI #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Files.PosixString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- Functions defined by the POSIX standards for manipulating and querying the+-- file system. Names of underlying POSIX functions are indicated whenever+-- possible. A more complete documentation of the POSIX functions together+-- with a more detailed description of different error conditions are usually+-- available in the system's manual pages or from+-- <http://www.unix.org/version3/online.html> (free registration required).+--+-- When a function that calls an underlying POSIX function fails, the errno+-- code is converted to an 'IOError' using 'Foreign.C.Error.errnoToIOError'.+-- For a list of which errno codes may be generated, consult the POSIX+-- documentation for the underlying function.+--+-----------------------------------------------------------------------------++#include "HsUnix.h"++module System.Posix.Files.PosixString (+    -- * File modes+    -- FileMode exported by System.Posix.Types+    unionFileModes, intersectFileModes,+    nullFileMode,+    ownerReadMode, ownerWriteMode, ownerExecuteMode, ownerModes,+    groupReadMode, groupWriteMode, groupExecuteMode, groupModes,+    otherReadMode, otherWriteMode, otherExecuteMode, otherModes,+    setUserIDMode, setGroupIDMode,+    stdFileMode,   accessModes,+    fileTypeModes,+    blockSpecialMode, characterSpecialMode, namedPipeMode, regularFileMode,+    directoryMode, symbolicLinkMode, socketMode,++    -- ** Setting file modes+    setFileMode, setFdMode, setFileCreationMask,++    -- ** Checking file existence and permissions+    fileAccess, fileExist,++    -- * File status+    FileStatus,+    -- ** Obtaining file status+    getFileStatus, getFdStatus, getSymbolicLinkStatus,+    -- ** Querying file status+    deviceID, fileID, fileMode, linkCount, fileOwner, fileGroup,+    specialDeviceID, fileSize, accessTime, modificationTime,+    statusChangeTime,+    accessTimeHiRes, modificationTimeHiRes, statusChangeTimeHiRes,+    isBlockDevice, isCharacterDevice, isNamedPipe, isRegularFile,+    isDirectory, isSymbolicLink, isSocket,++    -- * Creation+    createNamedPipe,+    createDevice,++    -- * Hard links+    createLink, removeLink,++    -- * Symbolic links+    createSymbolicLink, readSymbolicLink,++    -- * Renaming files+    rename,++    -- * Changing file ownership+    setOwnerAndGroup,  setFdOwnerAndGroup,+#if HAVE_LCHOWN+    setSymbolicLinkOwnerAndGroup,+#endif++    -- * Changing file timestamps+    setFileTimes, setFileTimesHiRes,+    setSymbolicLinkTimesHiRes,+    touchFile, touchFd, touchSymbolicLink,++    -- * Setting file sizes+    setFileSize, setFdSize,++    -- * Find system-specific limits for a file+    PathVar(..), getPathVar, getFdPathVar,+  ) where++import System.Posix.Types+import System.Posix.Internals hiding (withFilePath, peekFilePathLen)+import qualified System.Posix.Files.Common as Common+import Foreign+import Foreign.C hiding (+     throwErrnoPath,+     throwErrnoPathIf,+     throwErrnoPathIf_,+     throwErrnoPathIfNull,+     throwErrnoPathIfMinus1,+     throwErrnoPathIfMinus1_ )++import System.OsPath.Types+import System.Posix.Files hiding (getFileStatus, getSymbolicLinkStatus, createNamedPipe, createDevice, createLink, removeLink, createSymbolicLink, readSymbolicLink, rename, setOwnerAndGroup, setSymbolicLinkOwnerAndGroup, setFileTimes, setSymbolicLinkTimesHiRes, touchFile, touchSymbolicLink, setFileSize, getPathVar, setFileMode, fileAccess, fileExist, setFdTimesHiRes, setFileTimesHiRes)+import System.Posix.PosixPath.FilePath++import Data.Time.Clock.POSIX (POSIXTime)++-- -----------------------------------------------------------------------------+-- chmod()++-- | @setFileMode path mode@ changes permission of the file given by @path@+-- to @mode@. This operation may fail with 'throwErrnoPathIfMinus1_' if @path@+-- doesn't exist or if the effective user ID of the current process is not that+-- of the file's owner.+--+-- Note: calls @chmod@.+setFileMode :: PosixPath -> FileMode -> IO ()+setFileMode name m =+  withFilePath name $ \s -> do+    throwErrnoPathIfMinus1_ "setFileMode" name (c_chmod s m)+++-- -----------------------------------------------------------------------------+-- access()++-- | @fileAccess name read write exec@ checks if the file (or other file system+-- object) @name@ can be accessed for reading, writing and\/or executing. To+-- check a permission set the corresponding argument to 'True'.+--+-- Note: calls @access@.+fileAccess :: PosixPath -> Bool -> Bool -> Bool -> IO Bool+fileAccess name readOK writeOK execOK = access name flags+  where+   flags   = read_f .|. write_f .|. exec_f+   read_f  = if readOK  then (#const R_OK) else 0+   write_f = if writeOK then (#const W_OK) else 0+   exec_f  = if execOK  then (#const X_OK) else 0++-- | Checks for the existence of the file.+--+-- Note: calls @access@.+fileExist :: PosixPath -> IO Bool+fileExist name =+  withFilePath name $ \s -> do+    r <- c_access s (#const F_OK)+    if (r == 0)+        then return True+        else do err <- getErrno+                if (err == eNOENT)+                   then return False+                   else throwErrnoPath "fileExist" name++access :: PosixPath -> CMode -> IO Bool+access name flags =+  withFilePath name $ \s -> do+    r <- c_access s (fromIntegral flags)+    if (r == 0)+        then return True+        else do err <- getErrno+                if (err == eACCES || err == eROFS || err == eTXTBSY ||+                    err == ePERM)+                   then return False+                   else throwErrnoPath "fileAccess" name+++-- | @getFileStatus path@ calls gets the @FileStatus@ information (user ID,+-- size, access times, etc.) for the file @path@.+--+-- Note: calls @stat@.+getFileStatus :: PosixPath -> IO FileStatus+getFileStatus path = do+  fp <- mallocForeignPtrBytes (#const sizeof(struct stat))+  withForeignPtr fp $ \p ->+    withFilePath path $ \s ->+      throwErrnoPathIfMinus1Retry_ "getFileStatus" path (c_stat s p)+  return (Common.FileStatus fp)++-- | Acts as 'getFileStatus' except when the 'PosixPath' refers to a symbolic+-- link. In that case the @FileStatus@ information of the symbolic link itself+-- is returned instead of that of the file it points to.+--+-- Note: calls @lstat@.+getSymbolicLinkStatus :: PosixPath -> IO FileStatus+getSymbolicLinkStatus path = do+  fp <- mallocForeignPtrBytes (#const sizeof(struct stat))+  withForeignPtr fp $ \p ->+    withFilePath path $ \s ->+      throwErrnoPathIfMinus1_ "getSymbolicLinkStatus" path (c_lstat s p)+  return (Common.FileStatus fp)++foreign import capi unsafe "HsUnix.h lstat"+  c_lstat :: CString -> Ptr CStat -> IO CInt++-- | @createNamedPipe fifo mode@+-- creates a new named pipe, @fifo@, with permissions based on+-- @mode@. May fail with 'throwErrnoPathIfMinus1_' if a file named @name@+-- already exists or if the effective user ID of the current process doesn't+-- have permission to create the pipe.+--+-- Note: calls @mkfifo@.+createNamedPipe :: PosixPath -> FileMode -> IO ()+createNamedPipe name mode = do+  withFilePath name $ \s ->+    throwErrnoPathIfMinus1_ "createNamedPipe" name (c_mkfifo s mode)++-- | @createDevice path mode dev@ creates either a regular or a special file+-- depending on the value of @mode@ (and @dev@).  @mode@ will normally be either+-- 'blockSpecialMode' or 'characterSpecialMode'.  May fail with+-- 'throwErrnoPathIfMinus1_' if a file named @name@ already exists or if the+-- effective user ID of the current process doesn't have permission to create+-- the file.+--+-- Note: calls @mknod@.+createDevice :: PosixPath -> FileMode -> DeviceID -> IO ()+createDevice path mode dev =+  withFilePath path $ \s ->+    throwErrnoPathIfMinus1_ "createDevice" path (c_mknod s mode dev)++foreign import capi unsafe "HsUnix.h mknod"+  c_mknod :: CString -> CMode -> CDev -> IO CInt++-- -----------------------------------------------------------------------------+-- Hard links++-- | @createLink old new@ creates a new path, @new@, linked to an existing file,+-- @old@.+--+-- Note: calls @link@.+createLink :: PosixPath -> PosixPath -> IO ()+createLink name1 name2 =+  withFilePath name1 $ \s1 ->+  withFilePath name2 $ \s2 ->+  throwErrnoTwoPathsIfMinus1_ "createLink" name1 name2 (c_link s1 s2)++-- | @removeLink path@ removes the link named @path@.+--+-- Note: calls @unlink@.+removeLink :: PosixPath -> IO ()+removeLink name =+  withFilePath name $ \s ->+  throwErrnoPathIfMinus1_ "removeLink" name (c_unlink s)++-- -----------------------------------------------------------------------------+-- Symbolic Links++-- | @createSymbolicLink file1 file2@ creates a symbolic link named @file2@+-- which points to the file @file1@.+--+-- Symbolic links are interpreted at run-time as if the contents of the link+-- had been substituted into the path being followed to find a file or directory.+--+-- Note: calls @symlink@.+createSymbolicLink :: PosixPath -> PosixPath -> IO ()+createSymbolicLink name1 name2 =+  withFilePath name1 $ \s1 ->+  withFilePath name2 $ \s2 ->+  throwErrnoTwoPathsIfMinus1_ "createSymbolicLink" name1 name2 (c_symlink s1 s2)++foreign import ccall unsafe "symlink"+  c_symlink :: CString -> CString -> IO CInt++-- ToDo: should really use SYMLINK_MAX, but not everyone supports it yet,+-- and it seems that the intention is that SYMLINK_MAX is no larger than+-- PATH_MAX.+#if !defined(PATH_MAX)+-- PATH_MAX is not defined on systems with unlimited path length.+-- Ugly.  Fix this.+#define PATH_MAX 4096+#endif++-- | Reads the @PosixPath@ pointed to by the symbolic link and returns it.+--+-- Note: calls @readlink@.+readSymbolicLink :: PosixPath -> IO PosixPath+readSymbolicLink file =+  allocaArray0 (#const PATH_MAX) $ \buf -> do+    withFilePath file $ \s -> do+      len <- throwErrnoPathIfMinus1 "readSymbolicLink" file $+        c_readlink s buf (#const PATH_MAX)+      peekFilePathLen (buf,fromIntegral len)++foreign import ccall unsafe "readlink"+  c_readlink :: CString -> CString -> CSize -> IO CInt++-- -----------------------------------------------------------------------------+-- Renaming files++-- | @rename old new@ renames a file or directory from @old@ to @new@.+--+-- Note: calls @rename@.+rename :: PosixPath -> PosixPath -> IO ()+rename name1 name2 =+  withFilePath name1 $ \s1 ->+  withFilePath name2 $ \s2 ->+  throwErrnoTwoPathsIfMinus1_ "rename" name1 name2 (c_rename s1 s2)++foreign import ccall unsafe "rename"+   c_rename :: CString -> CString -> IO CInt++-- -----------------------------------------------------------------------------+-- chown()++-- | @setOwnerAndGroup path uid gid@ changes the owner and group of @path@ to+-- @uid@ and @gid@, respectively.+--+-- If @uid@ or @gid@ is specified as -1, then that ID is not changed.+--+-- Note: calls @chown@.+setOwnerAndGroup :: PosixPath -> UserID -> GroupID -> IO ()+setOwnerAndGroup name uid gid = do+  withFilePath name $ \s ->+    throwErrnoPathIfMinus1_ "setOwnerAndGroup" name (c_chown s uid gid)++foreign import ccall unsafe "chown"+  c_chown :: CString -> CUid -> CGid -> IO CInt++#if HAVE_LCHOWN+-- | Acts as 'setOwnerAndGroup' but does not follow symlinks (and thus+-- changes permissions on the link itself).+--+-- Note: calls @lchown@.+setSymbolicLinkOwnerAndGroup :: PosixPath -> UserID -> GroupID -> IO ()+setSymbolicLinkOwnerAndGroup name uid gid = do+  withFilePath name $ \s ->+    throwErrnoPathIfMinus1_ "setSymbolicLinkOwnerAndGroup" name+        (c_lchown s uid gid)++foreign import ccall unsafe "lchown"+  c_lchown :: CString -> CUid -> CGid -> IO CInt+#endif++-- -----------------------------------------------------------------------------+-- Setting file times++-- | @setFileTimes path atime mtime@ sets the access and modification times+-- associated with file @path@ to @atime@ and @mtime@, respectively.+--+-- Note: calls @utime@.+setFileTimes :: PosixPath -> EpochTime -> EpochTime -> IO ()+setFileTimes name atime mtime = do+  withFilePath name $ \s ->+   allocaBytes (#const sizeof(struct utimbuf)) $ \p -> do+     (#poke struct utimbuf, actime)  p atime+     (#poke struct utimbuf, modtime) p mtime+     throwErrnoPathIfMinus1_ "setFileTimes" name (c_utime s p)++-- | Like 'setFileTimes' but timestamps can have sub-second resolution.+--+-- Note: calls @utimensat@ or @utimes@. Support for high resolution timestamps+--   is filesystem dependent with the following limitations:+--+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+--+setFileTimesHiRes :: PosixPath -> POSIXTime -> POSIXTime -> IO ()+#ifdef HAVE_UTIMENSAT+setFileTimesHiRes name atime mtime =+  withFilePath name $ \s ->+    withArray [Common.toCTimeSpec atime, Common.toCTimeSpec mtime] $ \times ->+      throwErrnoPathIfMinus1_ "setFileTimesHiRes" name $+        Common.c_utimensat (#const AT_FDCWD) s times 0+#else+setFileTimesHiRes name atime mtime =+  withFilePath name $ \s ->+    withArray [Common.toCTimeVal atime, Common.toCTimeVal mtime] $ \times ->+      throwErrnoPathIfMinus1_ "setFileTimesHiRes" name (Common.c_utimes s times)+#endif++-- | Like 'setFileTimesHiRes' but does not follow symbolic links.+-- This operation is not supported on all platforms. On these platforms,+-- this function will raise an exception.+--+-- Note: calls @utimensat@ or @lutimes@. Support for high resolution timestamps+--   is filesystem dependent with the following limitations:+--+-- - HFS+ volumes on OS X truncate the sub-second part of the timestamp.+--+setSymbolicLinkTimesHiRes :: PosixPath -> POSIXTime -> POSIXTime -> IO ()+#if HAVE_UTIMENSAT+setSymbolicLinkTimesHiRes name atime mtime =+  withFilePath name $ \s ->+    withArray [Common.toCTimeSpec atime, Common.toCTimeSpec mtime] $ \times ->+      throwErrnoPathIfMinus1_ "setSymbolicLinkTimesHiRes" name $+        Common.c_utimensat (#const AT_FDCWD) s times (#const AT_SYMLINK_NOFOLLOW)+#elif HAVE_LUTIMES+setSymbolicLinkTimesHiRes name atime mtime =+  withFilePath name $ \s ->+    withArray [Common.toCTimeVal atime, Common.toCTimeVal mtime] $ \times ->+      throwErrnoPathIfMinus1_ "setSymbolicLinkTimesHiRes" name $+        Common.c_lutimes s times+#else+setSymbolicLinkTimesHiRes =+  error "setSymbolicLinkTimesHiRes: not available on this platform"+#endif++-- | @touchFile path@ sets the access and modification times associated with+-- file @path@ to the current time.+--+-- Note: calls @utime@.+touchFile :: PosixPath -> IO ()+touchFile name = do+  withFilePath name $ \s ->+   throwErrnoPathIfMinus1_ "touchFile" name (c_utime s nullPtr)++-- | Like 'touchFile' but does not follow symbolic links.+-- This operation is not supported on all platforms. On these platforms,+-- this function will raise an exception.+--+-- Note: calls @lutimes@.+touchSymbolicLink :: PosixPath -> IO ()+#if HAVE_LUTIMES+touchSymbolicLink name =+  withFilePath name $ \s ->+    throwErrnoPathIfMinus1_ "touchSymbolicLink" name (Common.c_lutimes s nullPtr)+#else+touchSymbolicLink =+  error "touchSymbolicLink: not available on this platform"+#endif++-- -----------------------------------------------------------------------------+-- Setting file sizes++-- | Truncates the file down to the specified length. If the file was larger+-- than the given length before this operation was performed the extra is lost.+--+-- Note: calls @truncate@.+setFileSize :: PosixPath -> FileOffset -> IO ()+setFileSize file off =+  withFilePath file $ \s ->+    throwErrnoPathIfMinus1_ "setFileSize" file (c_truncate s off)++foreign import capi unsafe "HsUnix.h truncate"+  c_truncate :: CString -> COff -> IO CInt++-- -----------------------------------------------------------------------------+-- pathconf()/fpathconf() support++-- | @getPathVar var path@ obtains the dynamic value of the requested+-- configurable file limit or option associated with file or directory @path@.+-- For defined file limits, @getPathVar@ returns the associated+-- value.  For defined file options, the result of @getPathVar@+-- is undefined, but not failure.+--+-- Note: calls @pathconf@.+getPathVar :: PosixPath -> PathVar -> IO Limit+getPathVar name v = do+  withFilePath name $ \ nameP ->+    throwErrnoPathIfMinus1 "getPathVar" name $+      c_pathconf nameP (Common.pathVarConst v)++foreign import ccall unsafe "pathconf"+  c_pathconf :: CString -> CInt -> IO CLong
System/Posix/IO.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.IO@@ -31,7 +27,7 @@     -- ** Opening and closing files     OpenMode(..),     OpenFileFlags(..), defaultFileFlags,-    openFd, createFile,+    openFd, openFdAt, createFile, createFileAt,     closeFd,      -- ** Reading\/writing data@@ -67,6 +63,13 @@    ) where +import Foreign ( allocaBytes, castPtr )+import Foreign.C ( peekCStringLen, withCStringLen )++import GHC.IO.Exception ( IOErrorType(EOF) )++import System.IO.Error ( ioeSetErrorString, mkIOError )+ import System.Posix.Types import System.Posix.Error import System.Posix.IO.Common@@ -76,18 +79,65 @@ -- for information on how to use the 'FileMode' type. openFd :: FilePath        -> OpenMode-       -> Maybe FileMode -- ^Just x => creates the file with the given modes, Nothing => the file must exist.        -> OpenFileFlags        -> IO Fd-openFd name how maybe_mode flags = do-   withFilePath name $ \str -> do-     throwErrnoPathIfMinus1Retry "openFd" name $-       open_ str how maybe_mode flags+openFd = openFdAt Nothing +-- | Open a file relative to an optional directory file descriptor.+--+-- Directory file descriptors can be used to avoid some race conditions when+-- navigating changing directory trees, or to retain access to a portion of the+-- directory tree that would otherwise become inaccessible after dropping+-- privileges.+openFdAt :: Maybe Fd -- ^ Optional directory file descriptor+         -> FilePath -- ^ Pathname to open+         -> OpenMode -- ^ Read-only, read-write or write-only+         -> OpenFileFlags -- ^ Append, exclusive, truncate, etc.+         -> IO Fd+openFdAt fdMay name how flags =+  withFilePath name $ \str ->+    throwErrnoPathIfMinus1Retry "openFdAt" name $+      openat_ fdMay str how flags+ -- |Create and open this file in WriteOnly mode.  A special case of -- 'openFd'.  See 'System.Posix.Files' for information on how to use -- the 'FileMode' type.- createFile :: FilePath -> FileMode -> IO Fd-createFile name mode-  = openFd name WriteOnly (Just mode) defaultFileFlags{ trunc=True }+createFile = createFileAt Nothing++-- | Create and open a file for write-only, with default flags,+-- relative an optional directory file-descriptor.+--+-- Directory file descriptors can be used to avoid some race conditions when+-- navigating changing directory trees, or to retain access to a portion of the+-- directory tree that would otherwise become inaccessible after dropping+-- privileges.+createFileAt :: Maybe Fd -- ^ Optional directory file descriptor+             -> FilePath -- ^ Pathname to create+             -> FileMode -- ^ File permission bits (before umask)+             -> IO Fd+createFileAt fdMay name mode+  = openFdAt fdMay name WriteOnly defaultFileFlags{ trunc=True, creat=(Just mode) }++{-# DEPRECATED fdRead "This function is scheduled to be dropped in favor of 'System.Posix.IO.ByteString.fdRead', because decoding e.g. UTF-8 streams partially is unsafe." #-} -- deprecated in 2.8.0.0+-- | Read data from an 'Fd' and convert it to a 'String' using the locale encoding.+-- Throws an exception if this is an invalid descriptor, or EOF has been+-- reached.+fdRead :: Fd+       -> ByteCount -- ^How many bytes to read+       -> IO (String, ByteCount) -- ^The bytes read, how many bytes were read.+fdRead _fd 0 = return ("", 0)+fdRead fd nbytes =+  allocaBytes (fromIntegral nbytes) $ \ buf -> do+  rc <- fdReadBuf fd buf nbytes+  case rc of+    0 -> ioError (ioeSetErrorString (mkIOError EOF "fdRead" Nothing Nothing) "EOF")+    n -> do+      s <- peekCStringLen (castPtr buf, fromIntegral n)+      return (s, n)++-- | Write a 'String' to an 'Fd' using the locale encoding.+fdWrite :: Fd -> String -> IO ByteCount+fdWrite fd str =+  withCStringLen str $ \ (buf,len) ->+    fdWriteBuf fd (castPtr buf) (fromIntegral len)
System/Posix/IO/ByteString.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709-{-# LANGUAGE Safe #-}-#else {-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.IO.ByteString@@ -31,7 +27,7 @@     -- ** Opening and closing files     OpenMode(..),     OpenFileFlags(..), defaultFileFlags,-    openFd, createFile,+    openFd, openFdAt, createFile, createFileAt,     closeFd,      -- ** Reading\/writing data@@ -67,6 +63,16 @@    ) where +import Data.ByteString ( ByteString, empty )+import qualified Data.ByteString.Internal as BI+import qualified Data.ByteString.Unsafe as BU++import Foreign ( castPtr )++import GHC.IO.Exception ( IOErrorType(EOF) )++import System.IO.Error ( ioeSetErrorString, mkIOError )+ import System.Posix.Types import System.Posix.IO.Common @@ -76,18 +82,62 @@ -- for information on how to use the 'FileMode' type. openFd :: RawFilePath        -> OpenMode-       -> Maybe FileMode -- ^Just x => creates the file with the given modes, Nothing => the file must exist.        -> OpenFileFlags        -> IO Fd-openFd name how maybe_mode flags = do-   withFilePath name $ \str -> do-     throwErrnoPathIfMinus1Retry "openFd" name $-       open_ str how maybe_mode flags+openFd = openFdAt Nothing +-- | Open a file relative to an optional directory file descriptor.+--+-- Directory file descriptors can be used to avoid some race conditions when+-- navigating changing directory trees, or to retain access to a portion of the+-- directory tree that would otherwise become inaccessible after dropping+-- privileges.+openFdAt :: Maybe Fd -- ^ Optional directory file descriptor+         -> RawFilePath -- ^ Pathname to open+         -> OpenMode -- ^ Read-only, read-write or write-only+         -> OpenFileFlags -- ^ Append, exclusive, truncate, etc.+         -> IO Fd+openFdAt fdMay name how flags =+  withFilePath name $ \str ->+    throwErrnoPathIfMinus1Retry "openFdAt" name $+      openat_ fdMay str how flags+ -- |Create and open this file in WriteOnly mode.  A special case of -- 'openFd'.  See 'System.Posix.Files' for information on how to use -- the 'FileMode' type.- createFile :: RawFilePath -> FileMode -> IO Fd-createFile name mode-  = openFd name WriteOnly (Just mode) defaultFileFlags{ trunc=True }+createFile = createFileAt Nothing++-- | Create and open a file for write-only, with default flags,+-- relative an optional directory file-descriptor.+--+-- Directory file descriptors can be used to avoid some race conditions when+-- navigating changing directory trees, or to retain access to a portion of the+-- directory tree that would otherwise become inaccessible after dropping+-- privileges.+createFileAt :: Maybe Fd -- ^ Optional directory file descriptor+             -> RawFilePath -- ^ Pathname to create+             -> FileMode -- ^ File permission bits (before umask)+             -> IO Fd+createFileAt fdMay name mode+  = openFdAt fdMay name WriteOnly defaultFileFlags{ trunc=True, creat=(Just mode) }++-- | Read data from an 'Fd' and return it as a 'ByteString'.+-- Throws an exception if this is an invalid descriptor, or EOF has been+-- reached.+fdRead :: Fd+       -> ByteCount -- ^How many bytes to read+       -> IO ByteString -- ^The bytes read+fdRead _fd 0 = return empty+fdRead fd nbytes =+  BI.createUptoN (fromIntegral nbytes) $ \ buf -> do+  rc <- fdReadBuf fd buf nbytes+  case rc of+    0 -> ioError (ioeSetErrorString (mkIOError EOF "fdRead" Nothing Nothing) "EOF")+    n -> return (fromIntegral n)++-- | Write a 'ByteString' to an 'Fd'.+fdWrite :: Fd -> ByteString -> IO ByteCount+fdWrite fd bs =+  BU.unsafeUseAsCStringLen bs $ \ (buf,len) ->+    fdWriteBuf fd (castPtr buf) (fromIntegral len)
System/Posix/IO/Common.hsc view
@@ -1,11 +1,7 @@ {-# LANGUAGE CApiFFI #-} {-# LANGUAGE NondecreasingIndentation #-} {-# LANGUAGE RecordWildCards #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |@@ -28,14 +24,13 @@     -- ** Opening and closing files     OpenMode(..),     OpenFileFlags(..), defaultFileFlags,-    open_,+    openat_,     closeFd,      -- ** Reading\/writing data     -- |Programmers using the 'fdRead' and 'fdWrite' API should be aware that     -- EAGAIN exceptions may occur for non-blocking IO! -    fdRead, fdWrite,     fdReadBuf, fdWriteBuf,      -- ** Seeking@@ -79,8 +74,22 @@ import GHC.IO.Exception import Data.Typeable (cast) +#if !defined(HAVE_PIPE)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ #include "HsUnix.h" +#if !defined(HAVE_PIPE)++createPipe :: IO (Fd, Fd)+{-# WARNING createPipe+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PIPE@)" #-}+createPipe = ioError (ioeSetLocation unsupportedOperation "createPipe")++#else+ -- ----------------------------------------------------------------------------- -- Pipes -- |The 'createPipe' function creates a pair of connected file@@ -101,6 +110,22 @@ foreign import ccall unsafe "pipe"    c_pipe :: Ptr CInt -> IO CInt +#endif // HAVE_PIPE++#if !defined(HAVE_DUP)++dup :: Fd -> IO Fd+{-# WARNING dup+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_DUP@)" #-}+dup _ = ioError (ioeSetLocation unsupportedOperation "dup")++dupTo :: Fd -> Fd -> IO Fd+{-# WARNING dupTo+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_DUP@)" #-}+dupTo _ _ = ioError (ioeSetLocation unsupportedOperation "dupTo")++#else+ -- ----------------------------------------------------------------------------- -- Duplicating file descriptors @@ -120,6 +145,8 @@ foreign import ccall unsafe "dup2"    c_dup2 :: CInt -> CInt -> IO CInt +#endif // HAVE_DUP+ -- ----------------------------------------------------------------------------- -- Opening and closing files @@ -129,20 +156,41 @@ stdError   = Fd (#const STDERR_FILENO)  data OpenMode = ReadOnly | WriteOnly | ReadWrite+              deriving (Read, Show, Eq, Ord)  -- |Correspond to some of the int flags from C's fcntl.h. data OpenFileFlags =  OpenFileFlags {-    append    :: Bool, -- ^ O_APPEND-    exclusive :: Bool, -- ^ O_EXCL-    noctty    :: Bool, -- ^ O_NOCTTY-    nonBlock  :: Bool, -- ^ O_NONBLOCK-    trunc     :: Bool  -- ^ O_TRUNC+    append    :: Bool,           -- ^ O_APPEND+    exclusive :: Bool,           -- ^ O_EXCL, result is undefined if O_CREAT is False+                                 --+                                 -- __NOTE__: Result is undefined if 'creat' is 'Nothing'.+    noctty    :: Bool,           -- ^ O_NOCTTY+    nonBlock  :: Bool,           -- ^ O_NONBLOCK+    trunc     :: Bool,           -- ^ O_TRUNC+    nofollow  :: Bool,           -- ^ O_NOFOLLOW+                                 --+                                 -- @since 2.8.0.0+    creat     :: Maybe FileMode, -- ^ O_CREAT+                                 --+                                 -- @since 2.8.0.0+    cloexec   :: Bool,           -- ^ O_CLOEXEC+                                 --+                                 -- @since 2.8.0.0+    directory :: Bool,           -- ^ O_DIRECTORY+                                 --+                                 -- @since 2.8.0.0+    sync      :: Bool            -- ^ O_SYNC+                                 --+                                 -- @since 2.8.0.0  }+ deriving (Read, Show, Eq, Ord)  --- |Default values for the 'OpenFileFlags' type. False for each of--- append, exclusive, noctty, nonBlock, and trunc.+-- | Default values for the 'OpenFileFlags' type.+--+-- Each field of 'OpenFileFlags' is either 'False' or 'Nothing'+-- respectively. defaultFileFlags :: OpenFileFlags defaultFileFlags =  OpenFileFlags {@@ -150,32 +198,43 @@     exclusive = False,     noctty    = False,     nonBlock  = False,-    trunc     = False+    trunc     = False,+    nofollow  = False,+    creat     = Nothing,+    cloexec   = False,+    directory = False,+    sync      = False   }  --- |Open and optionally create this file.  See 'System.Posix.Files'--- for information on how to use the 'FileMode' type.-open_  :: CString-       -> OpenMode-       -> Maybe FileMode -- ^Just x => creates the file with the given modes, Nothing => the file must exist.-       -> OpenFileFlags-       -> IO Fd-open_ str how maybe_mode (OpenFileFlags appendFlag exclusiveFlag nocttyFlag-                                nonBlockFlag truncateFlag) = do-    fd <- c_open str all_flags mode_w-    return (Fd fd)+-- |Open and optionally create a file relative to an optional+-- directory file descriptor.+openat_  :: Maybe Fd -- ^ Optional directory file descriptor+         -> CString -- ^ Pathname to open+         -> OpenMode -- ^ Read-only, read-write or write-only+         -> OpenFileFlags -- ^ Append, exclusive, etc.+         -> IO Fd+openat_ fdMay str how (OpenFileFlags appendFlag exclusiveFlag nocttyFlag+                                nonBlockFlag truncateFlag nofollowFlag+                                creatFlag cloexecFlag directoryFlag+                                syncFlag) =+    Fd <$> c_openat c_fd str all_flags mode_w   where+    c_fd = maybe (#const AT_FDCWD) (\ (Fd fd) -> fd) fdMay     all_flags  = creat .|. flags .|. open_mode      flags =-       (if appendFlag    then (#const O_APPEND)   else 0) .|.-       (if exclusiveFlag then (#const O_EXCL)     else 0) .|.-       (if nocttyFlag    then (#const O_NOCTTY)   else 0) .|.-       (if nonBlockFlag  then (#const O_NONBLOCK) else 0) .|.-       (if truncateFlag  then (#const O_TRUNC)    else 0)+       (if appendFlag       then (#const O_APPEND)    else 0) .|.+       (if exclusiveFlag    then (#const O_EXCL)      else 0) .|.+       (if nocttyFlag       then (#const O_NOCTTY)    else 0) .|.+       (if nonBlockFlag     then (#const O_NONBLOCK)  else 0) .|.+       (if truncateFlag     then (#const O_TRUNC)     else 0) .|.+       (if nofollowFlag     then (#const O_NOFOLLOW)  else 0) .|.+       (if cloexecFlag      then (#const O_CLOEXEC)   else 0) .|.+       (if directoryFlag    then (#const O_DIRECTORY) else 0) .|.+       (if syncFlag         then (#const O_SYNC)      else 0) -    (creat, mode_w) = case maybe_mode of+    (creat, mode_w) = case creatFlag of                         Nothing -> (0,0)                         Just x  -> ((#const O_CREAT), x) @@ -184,14 +243,20 @@                    WriteOnly -> (#const O_WRONLY)                    ReadWrite -> (#const O_RDWR) -foreign import capi unsafe "HsUnix.h open"-   c_open :: CString -> CInt -> CMode -> IO CInt+foreign import capi unsafe "HsUnix.h openat"+   c_openat :: CInt -> CString -> CInt -> CMode -> IO CInt  -- |Close this file descriptor.  May throw an exception if this is an -- invalid descriptor.  closeFd :: Fd -> IO () closeFd (Fd fd) = throwErrnoIfMinus1_ "closeFd" (c_close fd)+-- Here we don't to retry on EINTR because according to+--  http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html+-- "with errno set to [EINTR] [...] the state of fildes is unspecified"+-- and on Linux, already the first close() removes the FD from the process's+-- FD table so closing a second time is invalid+-- (see http://man7.org/linux/man-pages/man2/close.2.html#NOTES).  foreign import ccall unsafe "HsUnix.h close"    c_close :: CInt -> IO CInt@@ -200,7 +265,15 @@ -- Converting file descriptors to/from Handles  -- | Extracts the 'Fd' from a 'Handle'.  This function has the side effect--- of closing the 'Handle' and flushing its write buffer, if necessary.+-- of closing the 'Handle' (and flushing its write buffer, if necessary),+-- without closing the underlying 'Fd'.+--+-- __Warning:__ This means you take over ownership of the underlying 'Fd'.+-- 'hClose` on the 'Handle' will no longer have any effect.+-- This will break common patterns to avoid file descriptor leaks,+-- such as using 'hClose' in the cleanup action of @Control.Exception.bracket@,+-- making it a silent no-op.+-- Be sure to close the returned 'Fd' yourself to not leak it. handleToFd :: Handle -> IO Fd  -- | Converts an 'Fd' into a 'Handle' that can be used with the@@ -292,6 +365,25 @@  type FileLock = (LockRequest, SeekMode, FileOffset, FileOffset) +#if !defined(HAVE_F_GETLK)++getLock :: Fd -> FileLock -> IO (Maybe (ProcessID, FileLock))+{-# WARNING getLock+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_F_GETLK@)" #-}+getLock _ _ = ioError (ioeSetLocation unsupportedOperation "getLock")++setLock :: Fd -> FileLock -> IO ()+{-# WARNING setLock+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_F_GETLK@)" #-}+setLock _ _ = ioError (ioeSetLocation unsupportedOperation "setLock")++waitToSetLock :: Fd -> FileLock -> IO ()+{-# WARNING waitToSetLock+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_F_GETLK@)" #-}+waitToSetLock _ _ = ioError (ioeSetLocation unsupportedOperation "waitToSetLock")++#else+ -- | May throw an exception if this is an invalid descriptor. getLock :: Fd -> FileLock -> IO (Maybe (ProcessID, FileLock)) getLock (Fd fd) lock =@@ -351,24 +443,10 @@     throwErrnoIfMinus1_ "waitToSetLock"         (Base.c_fcntl_lock fd (#const F_SETLKW) p_flock) --- -------------------------------------------------------------------------------- fd{Read,Write}+#endif // HAVE_F_GETLK --- | Read data from an 'Fd' and convert it to a 'String' using the locale encoding.--- Throws an exception if this is an invalid descriptor, or EOF has been--- reached.-fdRead :: Fd-       -> ByteCount -- ^How many bytes to read-       -> IO (String, ByteCount) -- ^The bytes read, how many bytes were read.-fdRead _fd 0 = return ("", 0)-fdRead fd nbytes = do-    allocaBytes (fromIntegral nbytes) $ \ buf -> do-    rc <- fdReadBuf fd buf nbytes-    case rc of-      0 -> ioError (ioeSetErrorString (mkIOError EOF "fdRead" Nothing Nothing) "EOF")-      n -> do-       s <- peekCStringLen (castPtr buf, fromIntegral n)-       return (s, n)+-- -----------------------------------------------------------------------------+-- fd{Read,Write}Buf  -- | Read data from an 'Fd' into memory.  This is exactly equivalent -- to the POSIX @read@ function.@@ -384,12 +462,6 @@  foreign import ccall safe "read"    c_safe_read :: CInt -> Ptr CChar -> CSize -> IO CSsize---- | Write a 'String' to an 'Fd' using the locale encoding.-fdWrite :: Fd -> String -> IO ByteCount-fdWrite fd str =-  withCStringLen str $ \ (buf,len) ->-    fdWriteBuf fd (castPtr buf) (fromIntegral len)  -- | Write data from memory to an 'Fd'.  This is exactly equivalent -- to the POSIX @write@ function.
+ System/Posix/IO/PosixString.hsc view
@@ -0,0 +1,116 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.IO.PosixString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX IO support.  These types and functions correspond to the unix+-- functions open(2), close(2), etc.  For more portable functions+-- which are more like fopen(3) and friends from stdio.h, see+-- "System.IO".+--+-----------------------------------------------------------------------------++#include "HsUnix.h"++module System.Posix.IO.PosixString (+    -- * Input \/ Output++    -- ** Standard file descriptors+    stdInput, stdOutput, stdError,++    -- ** Opening and closing files+    OpenMode(..),+    OpenFileFlags(..), defaultFileFlags,+    openFd, openFdAt, createFile, createFileAt,+    closeFd,++    -- ** Reading\/writing data+    -- |Programmers using the 'fdRead' and 'fdWrite' API should be aware that+    -- EAGAIN exceptions may occur for non-blocking IO!++    fdRead, fdWrite,+    fdReadBuf, fdWriteBuf,++    -- ** Seeking+    fdSeek,++    -- ** File options+    FdOption(..),+    queryFdOption,+    setFdOption,++    -- ** Locking+    FileLock,+    LockRequest(..),+    getLock,  setLock,+    waitToSetLock,++    -- ** Pipes+    createPipe,++    -- ** Duplicating file descriptors+    dup, dupTo,++    -- ** Converting file descriptors to\/from Handles+    handleToFd,+    fdToHandle,++  ) where++import System.Posix.Types+import System.Posix.IO.Common+import System.Posix.IO.ByteString ( fdRead, fdWrite )+import System.OsPath.Types++import System.Posix.PosixPath.FilePath++++-- |Open and optionally create this file.  See 'System.Posix.Files'+-- for information on how to use the 'FileMode' type.+openFd :: PosixPath+       -> OpenMode+       -> OpenFileFlags+       -> IO Fd+openFd = openFdAt Nothing++-- | Open a file relative to an optional directory file descriptor.+--+-- Directory file descriptors can be used to avoid some race conditions when+-- navigating changing directory trees, or to retain access to a portion of the+-- directory tree that would otherwise become inaccessible after dropping+-- privileges.+openFdAt :: Maybe Fd -- ^ Optional directory file descriptor+         -> PosixPath -- ^ Pathname to open+         -> OpenMode -- ^ Read-only, read-write or write-only+         -> OpenFileFlags -- ^ Append, exclusive, truncate, etc.+         -> IO Fd+openFdAt fdMay name how flags =+   withFilePath name $ \str ->+     throwErrnoPathIfMinus1Retry "openFdAt" name $+       openat_ fdMay str how flags++-- |Create and open this file in WriteOnly mode.  A special case of+-- 'openFd'.  See 'System.Posix.Files' for information on how to use+-- the 'FileMode' type.+createFile :: PosixPath -> FileMode -> IO Fd+createFile = createFileAt Nothing++-- | Create and open a file for write-only, with default flags,+-- relative an optional directory file-descriptor.+--+-- Directory file descriptors can be used to avoid some race conditions when+-- navigating changing directory trees, or to retain access to a portion of the+-- directory tree that would otherwise become inaccessible after dropping+-- privileges.+createFileAt :: Maybe Fd -- ^ Optional directory file descriptor+             -> PosixPath -- ^ Pathname to create+             -> FileMode -- ^ File permission bits (before umask)+             -> IO Fd+createFileAt fdMay name mode+  = openFdAt fdMay name WriteOnly defaultFileFlags{ trunc=True, creat=(Just mode) }
+ System/Posix/PosixPath/FilePath.hsc view
@@ -0,0 +1,140 @@+{-# LANGUAGE CPP #-}++-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.PosixPath.FilePath+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- Internal stuff: support for ByteString FilePaths+--+-----------------------------------------------------------------------------++module System.Posix.PosixPath.FilePath (+     withFilePath, peekFilePath, peekFilePathLen,+     throwErrnoPathIfMinus1Retry,+     throwErrnoPathIfMinus1Retry_,+     throwErrnoPathIfNullRetry,+     throwErrnoPathIfRetry,+     throwErrnoPath,+     throwErrnoPathIf,+     throwErrnoPathIf_,+     throwErrnoPathIfNull,+     throwErrnoPathIfMinus1,+     throwErrnoPathIfMinus1_,+     throwErrnoTwoPathsIfMinus1_+  ) where++import Foreign hiding ( void )+import Foreign.C hiding (+     throwErrnoPath,+     throwErrnoPathIf,+     throwErrnoPathIf_,+     throwErrnoPathIfNull,+     throwErrnoPathIfMinus1,+     throwErrnoPathIfMinus1_ )++import System.OsPath.Types+import Control.Monad+import GHC.IO.Encoding.UTF8 ( mkUTF8 )+import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )+import System.OsPath.Posix+import System.OsPath.Data.ByteString.Short+import Prelude hiding (FilePath)+import System.OsString.Internal.Types (PosixString(..))+#if !MIN_VERSION_base(4, 11, 0)+import Data.Monoid ((<>))+#endif+++withFilePath :: PosixPath -> (CString -> IO a) -> IO a+withFilePath = useAsCString . getPosixString++peekFilePath :: CString -> IO PosixPath+peekFilePath = fmap PosixString . packCString++peekFilePathLen :: CStringLen -> IO PosixPath+peekFilePathLen = fmap PosixString . packCStringLen+++throwErrnoPathIfMinus1Retry :: (Eq a, Num a)+                            => String -> PosixPath -> IO a -> IO a+throwErrnoPathIfMinus1Retry loc path f = do+  throwErrnoPathIfRetry (== -1) loc path f++throwErrnoPathIfMinus1Retry_ :: (Eq a, Num a)+                             => String -> PosixPath -> IO a -> IO ()+throwErrnoPathIfMinus1Retry_ loc path f =+  void $ throwErrnoPathIfRetry (== -1) loc path f++throwErrnoPathIfNullRetry :: String -> PosixPath -> IO (Ptr a) -> IO (Ptr a)+throwErrnoPathIfNullRetry loc path f =+  throwErrnoPathIfRetry (== nullPtr) loc path f++throwErrnoPathIfRetry :: (a -> Bool) -> String -> PosixPath -> IO a -> IO a+throwErrnoPathIfRetry pr loc rpath f =+  do+    res <- f+    if pr res+      then do+        err <- getErrno+        if err == eINTR+          then throwErrnoPathIfRetry pr loc rpath f+          else throwErrnoPath loc rpath+      else return res++-- | as 'throwErrno', but exceptions include the given path when appropriate.+--+throwErrnoPath :: String -> PosixPath -> IO a+throwErrnoPath loc path =+  do+    errno <- getErrno+    ioError (errnoToIOError loc errno Nothing (Just (_toStr path)))++-- | as 'throwErrnoIf', but exceptions include the given path when+--   appropriate.+--+throwErrnoPathIf :: (a -> Bool) -> String -> PosixPath -> IO a -> IO a+throwErrnoPathIf cond loc path f =+  do+    res <- f+    if cond res then throwErrnoPath loc path else return res++-- | as 'throwErrnoIf_', but exceptions include the given path when+--   appropriate.+--+throwErrnoPathIf_ :: (a -> Bool) -> String -> PosixPath -> IO a -> IO ()+throwErrnoPathIf_ cond loc path f  = void $ throwErrnoPathIf cond loc path f++-- | as 'throwErrnoIfNull', but exceptions include the given path when+--   appropriate.+--+throwErrnoPathIfNull :: String -> PosixPath -> IO (Ptr a) -> IO (Ptr a)+throwErrnoPathIfNull  = throwErrnoPathIf (== nullPtr)++-- | as 'throwErrnoIfMinus1', but exceptions include the given path when+--   appropriate.+--+throwErrnoPathIfMinus1 :: (Eq a, Num a) => String -> PosixPath -> IO a -> IO a+throwErrnoPathIfMinus1 = throwErrnoPathIf (== -1)++-- | as 'throwErrnoIfMinus1_', but exceptions include the given path when+--   appropriate.+--+throwErrnoPathIfMinus1_ :: (Eq a, Num a) => String -> PosixPath -> IO a -> IO ()+throwErrnoPathIfMinus1_  = throwErrnoPathIf_ (== -1)++-- | as 'throwErrnoTwoPathsIfMinus1_', but exceptions include two paths when appropriate.+--+throwErrnoTwoPathsIfMinus1_ :: (Eq a, Num a) => String -> PosixPath -> PosixPath -> IO a -> IO ()+throwErrnoTwoPathsIfMinus1_  loc path1 path2 =+    throwErrnoIfMinus1_ (loc <> " '" <> _toStr path1 <> "' to '" <> _toStr path2 <> "'")+++_toStr :: PosixPath -> String+_toStr fp = either (error . show) id $ decodeWith (mkUTF8 TransliterateCodingFailure) fp+
+ System/Posix/PosixString.hs view
@@ -0,0 +1,70 @@+{-# LANGUAGE CPP #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.PosixString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- <http://pubs.opengroup.org/onlinepubs/9699919799/ POSIX.1-2008>+-- support with 'ByteString' file paths and environment strings.+--+-- This module exports exactly the same API as "System.Posix", except+-- that all file paths and environment strings are represented by+-- 'ByteString' instead of 'String'.  The "System.Posix" API+-- implicitly translates all file paths and environment strings using+-- the locale encoding, whereas this version of the API does no+-- encoding or decoding and works directly in terms of raw bytes.+--+-- Note that if you do need to interpret file paths or environment+-- strings as text, then some Unicode encoding or decoding should be+-- applied first.+--+-----------------------------------------------------------------------------++module System.Posix.PosixString (+  System.OsString.Posix.PosixString,+  System.OsPath.Posix.PosixPath,+  module System.Posix.Types,+  module System.Posix.Signals,+  module System.Posix.Directory.PosixPath,+  module System.Posix.Files.PosixString,+  module System.Posix.Unistd,+  module System.Posix.IO.PosixString,+  module System.Posix.Env.PosixString,+  module System.Posix.Process.PosixString,+  module System.Posix.Temp.PosixString,+  -- module System.Posix.Terminal.ByteString,+  module System.Posix.Time,+  module System.Posix.User,+  module System.Posix.Resource,+  module System.Posix.Semaphore,+  module System.Posix.SharedMem,+--  module System.Posix.DynamicLinker.ByteString,+-- XXX 'Module' type clashes with GHC+--  module System.Posix.DynamicLinker.Module.ByteString+ ) where++import System.OsPath.Posix+import System.OsString.Posix+import System.Posix.Types+import System.Posix.Signals+import System.Posix.Directory.PosixPath+import System.Posix.Files.PosixString+import System.Posix.Unistd+import System.Posix.Process.PosixString+import System.Posix.IO.PosixString+import System.Posix.Env.PosixString+import System.Posix.Temp.PosixString+-- import System.Posix.Terminal.ByteString+import System.Posix.Time+import System.Posix.User+import System.Posix.Resource+import System.Posix.Semaphore+import System.Posix.SharedMem+-- XXX: bad planning, we have two constructors called "Default"+-- import System.Posix.DynamicLinker.ByteString hiding (Default)+--import System.Posix.DynamicLinker.Module.ByteString
System/Posix/Process.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Process@@ -76,6 +72,11 @@ import System.Posix.Process.Common import System.Posix.Internals ( withFilePath ) +#if !defined(HAVE_EXECV)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ -- | @'executeFile' cmd args env@ calls one of the --   @execv*@ family, depending on whether or not the current --   PATH is to be searched for the command, and whether or not an@@ -89,6 +90,14 @@             -> [String]                     -- ^ Arguments             -> Maybe [(String, String)]     -- ^ Environment             -> IO a+#if !defined(HAVE_EXECV)++{-# WARNING executeFile+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_EXECV@)" #-}+executeFile _ _ _ _ = ioError (ioeSetLocation unsupportedOperation "executeFile")++#else+ executeFile path search args Nothing = do   withFilePath path $ \s ->     withMany withFilePath (path:args) $ \cstrs ->@@ -123,3 +132,4 @@ foreign import ccall unsafe "execve"   c_execve :: CString -> Ptr CString -> Ptr CString -> IO CInt +#endif // HAVE_EXECV
System/Posix/Process/ByteString.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif  ----------------------------------------------------------------------------- -- |@@ -88,6 +84,11 @@  import System.Posix.ByteString.FilePath +#if !defined(HAVE_EXECV)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ -- | @'executeFile' cmd args env@ calls one of the --   @execv*@ family, depending on whether or not the current --   PATH is to be searched for the command, and whether or not an@@ -101,6 +102,14 @@             -> [ByteString]                 -- ^ Arguments             -> Maybe [(ByteString, ByteString)]     -- ^ Environment             -> IO a+#if !defined(HAVE_EXECV)++{-# WARNING executeFile+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_EXECV@)" #-}+executeFile _ _ _ _ = ioError (ioeSetLocation unsupportedOperation "executeFile")++#else+ executeFile path search args Nothing = do   withFilePath path $ \s ->     withMany withFilePath (path:args) $ \cstrs ->@@ -134,3 +143,5 @@  foreign import ccall unsafe "execve"   c_execve :: CString -> Ptr CString -> Ptr CString -> IO CInt++#endif // HAVE_EXECV
System/Posix/Process/Common.hsc view
@@ -44,6 +44,7 @@     -- ** Process times     ProcessTimes(..),     getProcessTimes,+    clocksPerSec,      -- ** Scheduling priority     nice,@@ -81,8 +82,22 @@  import Control.Exception.Base ( bracket, getMaskingState, MaskingState(..) ) -- used by forkProcess import GHC.TopHandler   ( runIO )-import GHC.IO ( unsafeUnmask, uninterruptibleMask_ ) +#if defined(HAVE_GETPID)+import GHC.IO ( unsafeUnmask, uninterruptibleMask_  )+#else+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++#if !defined(HAVE_GETPID)++getProcessID :: IO ProcessID+{-# WARNING getProcessID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getProcessID = ioError (ioeSetLocation unsupportedOperation "getProcessID")++#else -- ----------------------------------------------------------------------------- -- Process environment @@ -94,7 +109,18 @@ foreign import ccall unsafe "getpid"    c_getpid :: IO CPid --- | 'getProcessID' calls @getppid@ to obtain the 'ProcessID' for+#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++getParentProcessID :: IO ProcessID+{-# WARNING getParentProcessID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getParentProcessID = ioError (ioeSetLocation unsupportedOperation "getParentProcessID")++#else++-- | 'getParentProcessID' calls @getppid@ to obtain the 'ProcessID' for --   the parent of the current process. getParentProcessID :: IO ProcessID getParentProcessID = c_getppid@@ -102,6 +128,17 @@ foreign import ccall unsafe "getppid"   c_getppid :: IO CPid +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++getProcessGroupID :: IO ProcessGroupID+{-# WARNING getProcessGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getProcessGroupID = ioError (ioeSetLocation unsupportedOperation "getProcessGroupID")++#else+ -- | 'getProcessGroupID' calls @getpgrp@ to obtain the --   'ProcessGroupID' for the current process. getProcessGroupID :: IO ProcessGroupID@@ -110,6 +147,17 @@ foreign import ccall unsafe "getpgrp"   c_getpgrp :: IO CPid +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++getProcessGroupIDOf :: ProcessID -> IO ProcessGroupID+{-# WARNING getProcessGroupIDOf+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getProcessGroupIDOf _ = ioError (ioeSetLocation unsupportedOperation "getProcessGroupIDOf")++#else+ -- | @'getProcessGroupIDOf' pid@ calls @getpgid@ to obtain the --   'ProcessGroupID' for process @pid@. getProcessGroupIDOf :: ProcessID -> IO ProcessGroupID@@ -119,6 +167,8 @@ foreign import ccall unsafe "getpgid"   c_getpgid :: CPid -> IO CPid +#endif // HAVE_GETPID+ {-    To be added in the future, after the deprecation period for the    existing createProcessGroup has elapsed:@@ -132,6 +182,15 @@   return pgid -} +#if !defined(HAVE_GETPID)++createProcessGroupFor :: ProcessID -> IO ProcessGroupID+{-# WARNING createProcessGroupFor+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+createProcessGroupFor _ = ioError (ioeSetLocation unsupportedOperation "createProcessGroupFor")++#else+ -- | @'createProcessGroupFor' pid@ calls @setpgid@ to make --   process @pid@ a new process group leader. createProcessGroupFor :: ProcessID -> IO ProcessGroupID@@ -139,12 +198,25 @@   throwErrnoIfMinus1_ "createProcessGroupFor" (c_setpgid pid 0)   return pid +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++joinProcessGroup :: ProcessGroupID -> IO ()+{-# WARNING joinProcessGroup+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+joinProcessGroup _ = ioError (ioeSetLocation unsupportedOperation "joinProcessGroup")++#else+ -- | @'joinProcessGroup' pgid@ calls @setpgid@ to set the --   'ProcessGroupID' of the current process to @pgid@. joinProcessGroup :: ProcessGroupID -> IO () joinProcessGroup pgid =   throwErrnoIfMinus1_ "joinProcessGroup" (c_setpgid 0 pgid) +#endif // HAVE_GETPID+ {-    To be added in the future, after the deprecation period for the    existing setProcessGroupID has elapsed:@@ -156,6 +228,15 @@   throwErrnoIfMinus1_ "setProcessGroupID" (c_setpgid 0 pgid) -} +#if !defined(HAVE_GETPID)++setProcessGroupIDOf :: ProcessID -> ProcessGroupID -> IO ()+{-# WARNING setProcessGroupIDOf+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+setProcessGroupIDOf _ _ = ioError (ioeSetLocation unsupportedOperation "setProcessGroupIDOf")++#else+ -- | @'setProcessGroupIDOf' pid pgid@ calls @setpgid@ to set the --   'ProcessGroupIDOf' for process @pid@ to @pgid@. setProcessGroupIDOf :: ProcessID -> ProcessGroupID -> IO ()@@ -165,6 +246,17 @@ foreign import ccall unsafe "setpgid"   c_setpgid :: CPid -> CPid -> IO CInt +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++createSession :: IO ProcessGroupID+{-# WARNING createSession+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+createSession = ioError (ioeSetLocation unsupportedOperation "createSession")++#else+ -- | 'createSession' calls @setsid@ to create a new session --   with the current process as session leader. createSession :: IO ProcessGroupID@@ -173,6 +265,8 @@ foreign import ccall unsafe "setsid"   c_setsid :: IO CPid +#endif // HAVE_GETPID+ -- ----------------------------------------------------------------------------- -- Process times @@ -186,6 +280,8 @@                  , childSystemTime :: ClockTick                  } +#if defined(HAVE_TIMES)+ -- | 'getProcessTimes' calls @times@ to obtain time-accounting --   information for the current process and its children. getProcessTimes :: IO ProcessTimes@@ -208,10 +304,46 @@ foreign import capi unsafe "HsUnix.h times"   c_times :: Ptr CTms -> IO CClock +-- | Returns the value from the @CLOCK_PER_SEC@ macro, which is required by POSIX.+clocksPerSec :: ClockTick+#ifdef HAVE_CLOCKS_PER_SEC+clocksPerSec = c_clocks_per_sec++foreign import capi unsafe "HsUnix.h __hsunix_clocks_per_second"+  c_clocks_per_sec :: CClock+#else+{-# WARNING clocksPerSec+    "CLOCK_PER_SEC not defined, defaulting to the value 1000000 as indicated by POSIX (CPP guard: @#if HAVE_CLOCKS_PER_SEC@)" #-}+clocksPerSec = 1000000+#endif // HAVE_CLOCKS_PER_SEC++#else++getProcessTimes :: IO ProcessTimes+{-# WARNING getProcessTimes+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TIMES@)" #-}+getProcessTimes = ioError (ioeSetLocation unsupportedOperation "getProcessTimes")++clocksPerSec :: ClockTick+{-# WARNING clocksPerSec+    "CLOCK_PER_SEC not defined, defaulting to the value 1000000 as indicated by POSIX (CPP guard: @#if HAVE_CLOCKS_PER_SEC@)" #-}+clocksPerSec = 1000000++#endif // HAVE_TIMES+ -- ----------------------------------------------------------------------------- -- Process scheduling priority +#if !defined(HAVE_GETPID)+ nice :: Int -> IO ()+{-# WARNING nice+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+nice _ = ioError (ioeSetLocation unsupportedOperation "nice")++#else++nice :: Int -> IO () nice prio = do   resetErrno   res <- c_nice (fromIntegral prio)@@ -222,10 +354,28 @@ foreign import ccall unsafe "nice"   c_nice :: CInt -> IO CInt +#endif // HAVE_GETPID+ getProcessPriority      :: ProcessID      -> IO Int getProcessGroupPriority :: ProcessGroupID -> IO Int getUserPriority         :: UserID         -> IO Int +#if !defined(HAVE_GETPID)++{-# WARNING getProcessPriority+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getProcessPriority _ = ioError (ioeSetLocation unsupportedOperation "getProcessPriority")++{-# WARNING getProcessGroupPriority+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getProcessGroupPriority _ = ioError (ioeSetLocation unsupportedOperation "getProcessGroupPriority")++{-# WARNING getUserPriority+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getUserPriority _ = ioError (ioeSetLocation unsupportedOperation "getUserPriority")++#else+ getProcessPriority pid = do   r <- throwErrnoIfMinus1 "getProcessPriority" $          c_getpriority (#const PRIO_PROCESS) (fromIntegral pid)@@ -244,10 +394,28 @@ foreign import ccall unsafe "getpriority"   c_getpriority :: CInt -> CInt -> IO CInt +#endif // HAVE_GETPID+ setProcessPriority      :: ProcessID      -> Int -> IO () setProcessGroupPriority :: ProcessGroupID -> Int -> IO () setUserPriority         :: UserID         -> Int -> IO () +#if !defined(HAVE_GETPID)++{-# WARNING setProcessPriority+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+setProcessPriority _ _ = ioError (ioeSetLocation unsupportedOperation "setProcessPriority")++{-# WARNING setProcessGroupPriority+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+setProcessGroupPriority _ _ = ioError (ioeSetLocation unsupportedOperation "setProcessGroupPriority")++{-# WARNING setUserPriority+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+setUserPriority _ _ = ioError (ioeSetLocation unsupportedOperation "setUserPriority")++#else+ setProcessPriority pid val =   throwErrnoIfMinus1_ "setProcessPriority" $     c_setpriority (#const PRIO_PROCESS) (fromIntegral pid) (fromIntegral val)@@ -263,6 +431,8 @@ foreign import ccall unsafe "setpriority"   c_setpriority :: CInt -> CInt -> CInt -> IO CInt +#endif // HAVE_GETPID+ -- ----------------------------------------------------------------------------- -- Forking, execution @@ -279,9 +449,27 @@ threads are not copied into the child process, it's easy to go wrong: e.g. by accessing some shared resource that was held by another thread in the parent.++GHC note: 'forkProcess' is not currently very well supported when using multiple+capabilities (@+RTS -N@), although it is supported with @-threaded@ as+long as only one capability is being used. -} +#if !defined(HAVE_GETPID)+ forkProcess :: IO () -> IO ProcessID+{-# WARNING forkProcess+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+forkProcess _ = ioError (ioeSetLocation unsupportedOperation "forkProcess")++forkProcessWithUnmask :: ((forall a . IO a -> IO a) -> IO ()) -> IO ProcessID+{-# WARNING forkProcessWithUnmask+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+forkProcessWithUnmask _ = ioError (ioeSetLocation unsupportedOperation "forkProcessWithUnmask")++#else++forkProcess :: IO () -> IO ProcessID forkProcess action = do   -- wrap action to re-establish caller's masking state, as   -- 'forkProcessPrim' starts in 'MaskedInterruptible' state by@@ -305,6 +493,17 @@ forkProcessWithUnmask :: ((forall a . IO a -> IO a) -> IO ()) -> IO ProcessID forkProcessWithUnmask action = forkProcess (action unsafeUnmask) +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++getProcessStatus :: Bool -> Bool -> ProcessID -> IO (Maybe ProcessStatus)+{-# WARNING getProcessStatus+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getProcessStatus _ _ _ = ioError (ioeSetLocation unsupportedOperation "getProcessStatus")++#else+ -- ----------------------------------------------------------------------------- -- Waiting for process termination @@ -328,6 +527,20 @@ foreign import ccall interruptible "waitpid"   c_waitpid :: CPid -> Ptr CInt -> CInt -> IO CPid +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++getGroupProcessStatus :: Bool+                      -> Bool+                      -> ProcessGroupID+                      -> IO (Maybe (ProcessID, ProcessStatus))+{-# WARNING getGroupProcessStatus+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getGroupProcessStatus _ _ _ = ioError (ioeSetLocation unsupportedOperation "getGroupProcessStatus")++#else+ -- | @'getGroupProcessStatus' blk stopped pgid@ calls @waitpid@, --   returning @'Just' (pid, tc)@, the 'ProcessID' and 'ProcessStatus' --   for any process in group @pgid@ if one is available, or 'Nothing'@@ -351,6 +564,17 @@       _  -> do ps <- readWaitStatus wstatp                return (Just (pid, ps)) +#endif // HAVE_GETPID++#if !defined(HAVE_GETPID)++getAnyProcessStatus :: Bool -> Bool -> IO (Maybe (ProcessID, ProcessStatus))+{-# WARNING getAnyProcessStatus+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+getAnyProcessStatus _ _ = ioError (ioeSetLocation unsupportedOperation "getAnyProcessStatus")++#else+ -- | @'getAnyProcessStatus' blk stopped@ calls @waitpid@, returning --   @'Just' (pid, tc)@, the 'ProcessID' and 'ProcessStatus' for any --   child process if a child process has exited, or 'Nothing' if@@ -364,6 +588,10 @@ getAnyProcessStatus :: Bool -> Bool -> IO (Maybe (ProcessID, ProcessStatus)) getAnyProcessStatus block stopped = getGroupProcessStatus block stopped 1 +#endif // HAVE_GETPID++#if defined(HAVE_GETPID)+ waitOptions :: Bool -> Bool -> CInt --             block   stopped waitOptions False False = (#const WNOHANG)@@ -378,14 +606,26 @@   wstat <- peek wstatp   decipherWaitStatus wstat +#endif // HAVE_GETPID+ -- ----------------------------------------------------------------------------- -- Exiting  -- | @'exitImmediately' status@ calls @_exit@ to terminate the process --   with the indicated exit @status@.---   The operation never returns.-exitImmediately :: ExitCode -> IO ()-exitImmediately exitcode = c_exit (exitcode2Int exitcode)+--   The operation never returns. Since it does not use the Haskell exception+--   system and it cannot be caught.+--+--   Note: Prior to @unix-2.8.0.0@ the type-signature of 'exitImmediately' was+--   @ExitCode -> IO ()@.+--+-- @since 2.8.0.0+exitImmediately :: ExitCode -> IO a+exitImmediately status = do+    _ <- c_exit (exitcode2Int status)+    -- The above will exit the program, but need the following to satisfy+    -- the type signature.+    exitImmediately status   where     exitcode2Int ExitSuccess = 0     exitcode2Int (ExitFailure n) = fromIntegral n@@ -393,6 +633,20 @@ foreign import ccall unsafe "exit"   c_exit :: CInt -> IO () +#if !defined(HAVE_GETPID)++createProcessGroup :: ProcessID -> IO ProcessGroupID+{-# WARNING createProcessGroup+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+createProcessGroup _ = ioError (ioeSetLocation unsupportedOperation "createProcessGroup")++setProcessGroupID :: ProcessID -> ProcessGroupID -> IO ()+{-# WARNING setProcessGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+setProcessGroupID _ _ = ioError (ioeSetLocation unsupportedOperation "setProcessGroupID")++#else+ -- ----------------------------------------------------------------------------- -- Deprecated or subject to change @@ -418,3 +672,5 @@   throwErrnoIfMinus1_ "setProcessGroupID" (c_setpgid pid pgid)  -- -----------------------------------------------------------------------------++#endif // HAVE_GETPID
− System/Posix/Process/Internals.hs
@@ -1,78 +0,0 @@-{-# LANGUAGE CApiFFI #-}-{-# LANGUAGE Trustworthy #-}--module System.Posix.Process.Internals (-       pPrPr_disableITimers, c_execvpe,-       decipherWaitStatus, ProcessStatus(..) ) where--import Foreign-import Foreign.C-import System.Exit-import System.IO.Error-import GHC.Conc (Signal)---- | The exit status of a process-data ProcessStatus-   = Exited ExitCode        -- ^ the process exited by calling-                            -- @exit()@ or returning from @main@-   | Terminated Signal Bool -- ^ the process was terminated by a-                            -- signal, the @Bool@ is @True@ if a core-                            -- dump was produced-                            ---                            -- @since 2.7.0.0-   | Stopped Signal         -- ^ the process was stopped by a signal-   deriving (Eq, Ord, Show)---- this function disables the itimer, which would otherwise cause confusing--- signals to be sent to the new process.-foreign import capi unsafe "Rts.h stopTimer"-  pPrPr_disableITimers :: IO ()--foreign import ccall unsafe "__hsunix_execvpe"-  c_execvpe :: CString -> Ptr CString -> Ptr CString -> IO CInt--decipherWaitStatus :: CInt -> IO ProcessStatus-decipherWaitStatus wstat =-  if c_WIFEXITED wstat /= 0-      then do-        let exitstatus = c_WEXITSTATUS wstat-        if exitstatus == 0-           then return (Exited ExitSuccess)-           else return (Exited (ExitFailure (fromIntegral exitstatus)))-      else do-        if c_WIFSIGNALED wstat /= 0-           then do-                let termsig    = c_WTERMSIG wstat-                let coredumped = c_WCOREDUMP wstat /= 0-                return (Terminated termsig coredumped)-           else do-                if c_WIFSTOPPED wstat /= 0-                   then do-                        let stopsig = c_WSTOPSIG wstat-                        return (Stopped stopsig)-                   else do-                        ioError (mkIOError illegalOperationErrorType-                                   "waitStatus" Nothing Nothing)---foreign import capi unsafe "HsUnix.h WIFEXITED"-  c_WIFEXITED :: CInt -> CInt--foreign import capi unsafe "HsUnix.h WEXITSTATUS"-  c_WEXITSTATUS :: CInt -> CInt--foreign import capi unsafe "HsUnix.h WIFSIGNALED"-  c_WIFSIGNALED :: CInt -> CInt--foreign import capi unsafe "HsUnix.h WTERMSIG"-  c_WTERMSIG :: CInt -> CInt--foreign import capi unsafe "HsUnix.h WIFSTOPPED"-  c_WIFSTOPPED :: CInt -> CInt--foreign import capi unsafe "HsUnix.h WSTOPSIG"-  c_WSTOPSIG :: CInt -> CInt--foreign import capi unsafe "HsUnix.h WCOREDUMP"-  c_WCOREDUMP :: CInt -> CInt-
+ System/Posix/Process/Internals.hsc view
@@ -0,0 +1,94 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE Trustworthy #-}++#include "HsUnix.h"++module System.Posix.Process.Internals (+       pPrPr_disableITimers, c_execvpe,+       decipherWaitStatus, ProcessStatus(..) ) where++import Foreign+import Foreign.C+import System.Exit+import System.IO.Error+import GHC.Conc (Signal)++#if !defined(HAVE_GETPID)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++-- | The exit status of a process+data ProcessStatus+   = Exited ExitCode        -- ^ the process exited by calling+                            -- @exit()@ or returning from @main@+   | Terminated Signal Bool -- ^ the process was terminated by a+                            -- signal, the @Bool@ is @True@ if a core+                            -- dump was produced+                            --+                            -- @since 2.7.0.0+   | Stopped Signal         -- ^ the process was stopped by a signal+   deriving (Eq, Ord, Show)++-- this function disables the itimer, which would otherwise cause confusing+-- signals to be sent to the new process.+foreign import capi unsafe "Rts.h stopTimer"+  pPrPr_disableITimers :: IO ()++foreign import ccall unsafe "__hsunix_execvpe"+  c_execvpe :: CString -> Ptr CString -> Ptr CString -> IO CInt++#if !defined(HAVE_GETPID)++{-# WARNING decipherWaitStatus "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_GETPID@)" #-}+decipherWaitStatus :: CInt -> IO ProcessStatus+decipherWaitStatus _ = ioError (ioeSetLocation unsupportedOperation "decipherWaitStatus")++#else++decipherWaitStatus :: CInt -> IO ProcessStatus+decipherWaitStatus wstat =+  if c_WIFEXITED wstat /= 0+      then do+        let exitstatus = c_WEXITSTATUS wstat+        if exitstatus == 0+           then return (Exited ExitSuccess)+           else return (Exited (ExitFailure (fromIntegral exitstatus)))+      else do+        if c_WIFSIGNALED wstat /= 0+           then do+                let termsig    = c_WTERMSIG wstat+                let coredumped = c_WCOREDUMP wstat /= 0+                return (Terminated termsig coredumped)+           else do+                if c_WIFSTOPPED wstat /= 0+                   then do+                        let stopsig = c_WSTOPSIG wstat+                        return (Stopped stopsig)+                   else do+                        ioError (mkIOError illegalOperationErrorType+                                   "waitStatus" Nothing Nothing)+++foreign import capi unsafe "HsUnix.h WIFEXITED"+  c_WIFEXITED :: CInt -> CInt++foreign import capi unsafe "HsUnix.h WEXITSTATUS"+  c_WEXITSTATUS :: CInt -> CInt++foreign import capi unsafe "HsUnix.h WIFSIGNALED"+  c_WIFSIGNALED :: CInt -> CInt++foreign import capi unsafe "HsUnix.h WTERMSIG"+  c_WTERMSIG :: CInt -> CInt++foreign import capi unsafe "HsUnix.h WIFSTOPPED"+  c_WIFSTOPPED :: CInt -> CInt++foreign import capi unsafe "HsUnix.h WSTOPSIG"+  c_WSTOPSIG :: CInt -> CInt++foreign import capi unsafe "HsUnix.h WCOREDUMP"+  c_WCOREDUMP :: CInt -> CInt++#endif // HAVE_GETPID
+ System/Posix/Process/PosixString.hsc view
@@ -0,0 +1,134 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Process.PosixString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX process support.  See also the System.Cmd and System.Process+-- modules in the process package.+--+-----------------------------------------------------------------------------++module System.Posix.Process.PosixString (+    -- * Processes++    -- ** Forking and executing+    forkProcess,+    forkProcessWithUnmask,+    executeFile,++    -- ** Exiting+    exitImmediately,++    -- ** Process environment+    getProcessID,+    getParentProcessID,++    -- ** Process groups+    getProcessGroupID,+    getProcessGroupIDOf,+    createProcessGroupFor,+    joinProcessGroup,+    setProcessGroupIDOf,++    -- ** Sessions+    createSession,++    -- ** Process times+    ProcessTimes(..),+    getProcessTimes,++    -- ** Scheduling priority+    nice,+    getProcessPriority,+    getProcessGroupPriority,+    getUserPriority,+    setProcessPriority,+    setProcessGroupPriority,+    setUserPriority,++    -- ** Process status+    ProcessStatus(..),+    getProcessStatus,+    getAnyProcessStatus,+    getGroupProcessStatus,++    -- ** Deprecated+    createProcessGroup,+    setProcessGroupID,++ ) where++#include "HsUnix.h"++import Foreign+import System.Posix.Process.Internals+import System.Posix.Process (ProcessTimes(..), setProcessGroupID, createProcessGroup, getGroupProcessStatus, getAnyProcessStatus, getProcessStatus, setUserPriority, setProcessGroupPriority, setProcessPriority, getUserPriority, getProcessGroupPriority, getProcessPriority, nice, getProcessTimes, createSession, setProcessGroupIDOf, joinProcessGroup, createProcessGroupFor, getProcessGroupIDOf, getProcessGroupID, getParentProcessID, getProcessID, exitImmediately, forkProcessWithUnmask, forkProcess)++import Foreign.C hiding (+     throwErrnoPath,+     throwErrnoPathIf,+     throwErrnoPathIf_,+     throwErrnoPathIfNull,+     throwErrnoPathIfMinus1,+     throwErrnoPathIfMinus1_ )++import System.OsPath.Types+import System.OsString.Internal.Types (PosixString(..))+import qualified System.OsPath.Data.ByteString.Short as BC++import System.Posix.PosixPath.FilePath++-- | @'executeFile' cmd args env@ calls one of the+--   @execv*@ family, depending on whether or not the current+--   PATH is to be searched for the command, and whether or not an+--   environment is provided to supersede the process's current+--   environment.  The basename (leading directory names suppressed) of+--   the command is passed to @execv*@ as @arg[0]@;+--   the argument list passed to 'executeFile' therefore+--   begins with @arg[1]@.+executeFile :: PosixPath                        -- ^ Command+            -> Bool                                 -- ^ Search PATH?+            -> [PosixString]                         -- ^ Arguments+            -> Maybe [(PosixString, PosixString)]     -- ^ Environment+            -> IO a+executeFile path search args Nothing = do+  withFilePath path $ \s ->+    withMany withFilePath (path:args) $ \cstrs ->+      withArray0 nullPtr cstrs $ \arr -> do+        pPrPr_disableITimers+        if search+           then throwErrnoPathIfMinus1_ "executeFile" path (c_execvp s arr)+           else throwErrnoPathIfMinus1_ "executeFile" path (c_execv s arr)+        return undefined -- never reached++executeFile path search args (Just env) = do+  withFilePath path $ \s ->+    withMany withFilePath (path:args) $ \cstrs ->+      withArray0 nullPtr cstrs $ \arg_arr ->+    let env' = map (\ (PosixString name, PosixString val) -> PosixString $ name `BC.append` (_equal `BC.cons` val)) env in+    withMany withFilePath env' $ \cenv ->+      withArray0 nullPtr cenv $ \env_arr -> do+        pPrPr_disableITimers+        if search+           then throwErrnoPathIfMinus1_ "executeFile" path+                   (c_execvpe s arg_arr env_arr)+           else throwErrnoPathIfMinus1_ "executeFile" path+                   (c_execve s arg_arr env_arr)+        return undefined -- never reached++foreign import ccall unsafe "execvp"+  c_execvp :: CString -> Ptr CString -> IO CInt++foreign import ccall unsafe "execv"+  c_execv :: CString -> Ptr CString -> IO CInt++foreign import ccall unsafe "execve"+  c_execve :: CString -> Ptr CString -> Ptr CString -> IO CInt++_equal :: Word8+_equal = 0x3d
System/Posix/Resource.hsc view
@@ -1,9 +1,10 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709-{-# LANGUAGE Safe #-}-#else+#if __GLASGOW_HASKELL__ >= 905 {-# LANGUAGE Trustworthy #-}+#else+{-# LANGUAGE Safe #-} #endif+ ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Resource@@ -31,6 +32,14 @@ import Foreign import Foreign.C +#if !defined(HAVE_STRUCT_RLIMIT)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+#if __GLASGOW_HASKELL__ >= 905+import GHC.Exts ( considerAccessible )+#endif+ -- ----------------------------------------------------------------------------- -- Resource limits @@ -44,18 +53,32 @@ #ifdef RLIMIT_AS   | ResourceTotalMemory #endif-  deriving Eq+  deriving (Eq, Show)  data ResourceLimits   = ResourceLimits { softLimit, hardLimit :: ResourceLimit }-  deriving Eq+  deriving (Eq, Show)  data ResourceLimit   = ResourceLimitInfinity   | ResourceLimitUnknown   | ResourceLimit Integer-  deriving Eq+  deriving (Eq, Show) +#if !defined(HAVE_STRUCT_RLIMIT)++getResourceLimit :: Resource -> IO ResourceLimits+{-# WARNING getResourceLimit+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_STRUCT_RLIMIT@)" #-}+getResourceLimit _ = ioError (ioeSetLocation unsupportedOperation "getResourceLimit")++setResourceLimit :: Resource -> ResourceLimits -> IO ()+{-# WARNING setResourceLimit+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_STRUCT_RLIMIT@)" #-}+setResourceLimit _ _ = ioError (ioeSetLocation unsupportedOperation "setResourceLimit")++#else+ data {-# CTYPE "struct rlimit" #-} RLimit  foreign import capi unsafe "HsUnix.h getrlimit"@@ -100,13 +123,21 @@ unpackRLimit (#const RLIM_INFINITY)  = ResourceLimitInfinity unpackRLimit other #if defined(RLIM_SAVED_MAX)-    | ((#const RLIM_SAVED_MAX) :: CRLim) /= (#const RLIM_INFINITY) &&-      other == (#const RLIM_SAVED_MAX) = ResourceLimitUnknown+    | ((#const RLIM_SAVED_MAX) :: CRLim) /= (#const RLIM_INFINITY)+    , other == (#const RLIM_SAVED_MAX)+    = ResourceLimitUnknown #endif #if defined(RLIM_SAVED_CUR)-    | ((#const RLIM_SAVED_CUR) :: CRLim) /= (#const RLIM_INFINITY) &&-      other == (#const RLIM_SAVED_CUR) = ResourceLimitUnknown+    | ((#const RLIM_SAVED_CUR) :: CRLim) /= (#const RLIM_INFINITY)+    , other == (#const RLIM_SAVED_CUR)+#if __GLASGOW_HASKELL__ >= 905+    , considerAccessible #endif+    = ResourceLimitUnknown+    -- (*) This pattern match is redundant if RLIM_SAVED_MAX and RLIM_SAVED_CUR+    -- are both defined and are equal. This redundancy is only detected by GHC+    -- starting from version 9.5, so we use 'considerAccessible'.+#endif     | otherwise = ResourceLimit (fromIntegral other)  packRLimit :: ResourceLimit -> Bool -> CRLim@@ -164,3 +195,5 @@ showRLim ResourceLimitUnknown  = "unknown" showRLim (ResourceLimit other)  = show other -}++#endif // HAVE_STRUCT_RLIMIT
System/Posix/Semaphore.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif {-# LANGUAGE CApiFFI #-} ----------------------------------------------------------------------------- -- |@@ -24,18 +20,24 @@      semPost, semGetValue)     where +#include "HsUnix.h" #include <semaphore.h> #include <fcntl.h>  import Foreign.C import Foreign.ForeignPtr hiding (newForeignPtr) import Foreign.Concurrent-import Foreign.Marshal import Foreign.Ptr-import Foreign.Storable import System.Posix.Types import Control.Concurrent import Data.Bits+#if !defined(HAVE_SEM_GETVALUE)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#else+import Foreign.Marshal+import Foreign.Storable+#endif  data OpenSemFlags = OpenSemFlags { semCreate :: Bool,                                    -- ^ If true, create the semaphore if it@@ -106,15 +108,24 @@  -- | Return the semaphore's current value. semGetValue :: Semaphore -> IO Int+#ifdef HAVE_SEM_GETVALUE semGetValue (Semaphore fptr) = withForeignPtr fptr semGetValue'     where semGetValue' sem = alloca (semGetValue_ sem) + semGetValue_ :: Ptr () -> Ptr CInt -> IO Int semGetValue_ sem ptr = do throwErrnoIfMinus1Retry_ "semGetValue" $                             sem_getvalue sem ptr                           cint <- peek ptr                           return $ fromEnum cint +foreign import capi safe "semaphore.h sem_getvalue"+        sem_getvalue :: Ptr () -> Ptr CInt -> IO Int+#else+{-# WARNING semGetValue "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SEM_GETVALUE@)" #-}+semGetValue _ = ioError (ioeSetLocation unsupportedOperation "semGetValue")+#endif+ foreign import capi safe "semaphore.h sem_open"         sem_open :: CString -> CInt -> CMode -> CUInt -> IO (Ptr ()) foreign import capi safe "semaphore.h sem_close"@@ -128,5 +139,3 @@         sem_trywait :: Ptr () -> IO CInt foreign import capi safe "semaphore.h sem_post"         sem_post :: Ptr () -> IO CInt-foreign import capi safe "semaphore.h sem_getvalue"-        sem_getvalue :: Ptr () -> Ptr CInt -> IO Int
System/Posix/SharedMem.hsc view
@@ -1,8 +1,4 @@-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.SharedMem@@ -24,7 +20,9 @@ #include "HsUnix.h"  #include <sys/types.h>+#if defined(HAVE_SHM_OPEN) || defined(HAVE_SHM_UNLINK) #include <sys/mman.h>+#endif #include <fcntl.h>  import System.Posix.Types@@ -67,6 +65,7 @@                        shm_open cname cflags mode                  return $ Fd fd #else+{-# WARNING shmOpen "System.Posix.SharedMem: shm_open: not available" #-} shmOpen = error "System.Posix.SharedMem:shm_open: not available" #endif @@ -77,6 +76,7 @@     where shmUnlink' cname =               throwErrnoIfMinus1_ "shmUnlink" $ shm_unlink cname #else+{-# WARNING shmUnlink "System.Posix.SharedMem:shm_unlink: not available" #-} shmUnlink = error "System.Posix.SharedMem:shm_unlink: not available" #endif 
System/Posix/Signals.hsc view
@@ -101,6 +101,10 @@ import Foreign.Marshal import Foreign.Ptr import Foreign.Storable+#if !defined(HAVE_SIGNAL_H)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif import System.IO.Unsafe (unsafePerformIO) import System.Posix.Types import System.Posix.Internals@@ -112,154 +116,241 @@  import GHC.Conc hiding (Signal) +#if !defined(HAVE_SIGNAL_H)+import Control.Exception ( throw )+#endif+ -- ----------------------------------------------------------------------------- -- Specific signals  nullSignal :: Signal nullSignal = 0 +-- | Process abort signal. sigABRT   :: CInt sigABRT   = CONST_SIGABRT++-- | Alarm clock. sigALRM   :: CInt sigALRM   = CONST_SIGALRM++-- | Access to an undefined portion of a memory object. sigBUS    :: CInt sigBUS    = CONST_SIGBUS++-- | Child process terminated, stopped, or continued. sigCHLD   :: CInt sigCHLD   = CONST_SIGCHLD++-- | Continue executing, if stopped. sigCONT   :: CInt sigCONT   = CONST_SIGCONT++-- | Erroneous arithmetic operation. sigFPE    :: CInt sigFPE    = CONST_SIGFPE++-- | Hangup. sigHUP    :: CInt sigHUP    = CONST_SIGHUP++-- | Illegal instruction. sigILL    :: CInt sigILL    = CONST_SIGILL++-- | Terminal interrupt signal. sigINT    :: CInt sigINT    = CONST_SIGINT++-- | Kill (cannot be caught or ignored). sigKILL   :: CInt sigKILL   = CONST_SIGKILL++-- | Write on a pipe with no one to read it. sigPIPE   :: CInt sigPIPE   = CONST_SIGPIPE++-- | Terminal quit signal. sigQUIT   :: CInt sigQUIT   = CONST_SIGQUIT++-- | Invalid memory reference. sigSEGV   :: CInt sigSEGV   = CONST_SIGSEGV++-- | Stop executing (cannot be caught or ignored). sigSTOP   :: CInt sigSTOP   = CONST_SIGSTOP++-- | Termination signal. sigTERM   :: CInt sigTERM   = CONST_SIGTERM++-- | Terminal stop signal. sigTSTP   :: CInt sigTSTP   = CONST_SIGTSTP++-- | Background process attempting read. sigTTIN   :: CInt sigTTIN   = CONST_SIGTTIN++-- | Background process attempting write. sigTTOU   :: CInt sigTTOU   = CONST_SIGTTOU++-- | User-defined signal 1. sigUSR1   :: CInt sigUSR1   = CONST_SIGUSR1++-- | User-defined signal 2. sigUSR2   :: CInt sigUSR2   = CONST_SIGUSR2+ #if CONST_SIGPOLL != -1+-- | Pollable event. sigPOLL   :: CInt sigPOLL   = CONST_SIGPOLL #endif++-- | Profiling timer expired. sigPROF   :: CInt sigPROF   = CONST_SIGPROF++-- | Bad system call. sigSYS    :: CInt sigSYS    = CONST_SIGSYS++-- | Trace/breakpoint trap. sigTRAP   :: CInt sigTRAP   = CONST_SIGTRAP++-- | High bandwidth data is available at a socket. sigURG    :: CInt sigURG    = CONST_SIGURG++-- | Virtual timer expired. sigVTALRM :: CInt sigVTALRM = CONST_SIGVTALRM++-- | CPU time limit exceeded. sigXCPU   :: CInt sigXCPU   = CONST_SIGXCPU++-- | File size limit exceeded. sigXFSZ   :: CInt sigXFSZ   = CONST_SIGXFSZ +-- | Alias for 'sigABRT'. internalAbort ::Signal internalAbort = sigABRT +-- | Alias for 'sigALRM'. realTimeAlarm :: Signal realTimeAlarm = sigALRM +-- | Alias for 'sigBUS'. busError :: Signal busError = sigBUS +-- | Alias for 'sigCHLD'. processStatusChanged :: Signal processStatusChanged = sigCHLD +-- | Alias for 'sigCONT'. continueProcess :: Signal continueProcess = sigCONT +-- | Alias for 'sigFPE'. floatingPointException :: Signal floatingPointException = sigFPE +-- | Alias for 'sigHUP'. lostConnection :: Signal lostConnection = sigHUP +-- | Alias for 'sigILL'. illegalInstruction :: Signal illegalInstruction = sigILL +-- | Alias for 'sigINT'. keyboardSignal :: Signal keyboardSignal = sigINT +-- | Alias for 'sigKILL'. killProcess :: Signal killProcess = sigKILL +-- | Alias for 'sigPIPE'. openEndedPipe :: Signal openEndedPipe = sigPIPE +-- | Alias for 'sigQUIT'. keyboardTermination :: Signal keyboardTermination = sigQUIT +-- | Alias for 'sigSEGV'. segmentationViolation :: Signal segmentationViolation = sigSEGV +-- | Alias for 'sigSTOP'. softwareStop :: Signal softwareStop = sigSTOP +-- | Alias for 'sigTERM'. softwareTermination :: Signal softwareTermination = sigTERM +-- | Alias for 'sigTSTP'. keyboardStop :: Signal keyboardStop = sigTSTP +-- | Alias for 'sigTTIN'. backgroundRead :: Signal backgroundRead = sigTTIN +-- | Alias for 'sigTTOU'. backgroundWrite :: Signal backgroundWrite = sigTTOU +-- | Alias for 'sigUSR1'. userDefinedSignal1 :: Signal userDefinedSignal1 = sigUSR1 +-- | Alias for 'sigUSR2'. userDefinedSignal2 :: Signal userDefinedSignal2 = sigUSR2  #if CONST_SIGPOLL != -1+-- | Alias for 'sigPOLL'. pollableEvent :: Signal pollableEvent = sigPOLL #endif +-- | Alias for 'sigPROF'. profilingTimerExpired :: Signal profilingTimerExpired = sigPROF +-- | Alias for 'sigSYS'. badSystemCall :: Signal badSystemCall = sigSYS +-- | Alias for 'sigTRAP'. breakpointTrap :: Signal breakpointTrap = sigTRAP +-- | Alias for 'sigURG'. urgentDataAvailable :: Signal urgentDataAvailable = sigURG +-- | Alias for 'sigVTALRM'. virtualTimerExpired :: Signal virtualTimerExpired = sigVTALRM +-- | Alias for 'sigXCPU'. cpuTimeLimitExceeded :: Signal cpuTimeLimitExceeded = sigXCPU +-- | Alias for 'sigXFSZ'. fileSizeLimitExceeded :: Signal fileSizeLimitExceeded = sigXFSZ @@ -269,25 +360,53 @@ -- | @signalProcess int pid@ calls @kill@ to signal process @pid@ --   with interrupt signal @int@. signalProcess :: Signal -> ProcessID -> IO ()+#if !defined(HAVE_SIGNAL_H)++{-# WARNING signalProcess+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+signalProcess _ _ = ioError (ioeSetLocation unsupportedOperation "signalProcess")++#else+ signalProcess sig pid  = throwErrnoIfMinus1_ "signalProcess" (c_kill pid sig)  foreign import ccall unsafe "kill"   c_kill :: CPid -> CInt -> IO CInt +#endif // HAVE_SIGNAL_H + -- | @signalProcessGroup int pgid@ calls @kill@ to signal --  all processes in group @pgid@ with interrupt signal @int@. signalProcessGroup :: Signal -> ProcessGroupID -> IO ()+#if !defined(HAVE_SIGNAL_H)++{-# WARNING signalProcessGroup+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+signalProcessGroup _ _ = ioError (ioeSetLocation unsupportedOperation "signalProcessGroup")++#else+ signalProcessGroup sig pgid   = throwErrnoIfMinus1_ "signalProcessGroup" (c_killpg pgid sig)  foreign import ccall unsafe "killpg"   c_killpg :: CPid -> CInt -> IO CInt +#endif // HAVE_SIGNAL_H+ -- | @raiseSignal int@ calls @kill@ to signal the current process --   with interrupt signal @int@. raiseSignal :: Signal -> IO ()+#if !defined(HAVE_SIGNAL_H)++{-# WARNING raiseSignal+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+raiseSignal _ = ioError (ioeSetLocation unsupportedOperation "raiseSignal")++#else+ raiseSignal sig = throwErrnoIfMinus1_ "raiseSignal" (c_raise sig)  -- See also note in GHC's rts/RtsUtils.c@@ -301,15 +420,28 @@   c_raise :: CInt -> IO CInt #endif +#endif // HAVE_SIGNAL_H  type Signal = CInt  -- | The actions to perform when a signal is received. data Handler = Default+                 -- ^ Sets the disposition of the signal to @SIG_DFL@, which+                 -- means we want the default action associated with the+                 -- signal. For example, the default action for @SIGTERM@ (and+                 -- various other signals) is to terminate the process.              | Ignore+                 -- ^ Set the disposition of the signal to @SIG_IGN@, which+                 -- means we want to /ignore/ the signal.  Ignored signals will+                 -- not be delivered to the process, and if also /blocked/ will+                 -- not be added to the pending set for later delivery (if/when+                 -- unblocked).  Some signals (e.g. @SIGSTOP@ and @SIGKILL@)+                 -- cannot be caught or ignored.              -- not yet: | Hold              | Catch (IO ())+                 -- ^ signal handler is not reset              | CatchOnce (IO ())+                 -- ^ signal handler is automatically reset (via @SA_RESETHAND@)              | CatchInfo (SignalInfo -> IO ())     -- ^ @since 2.7.0.0              | CatchInfoOnce (SignalInfo -> IO ()) -- ^ @since 2.7.0.0   deriving (Typeable)@@ -350,8 +482,16 @@                -> IO Handler            -- ^ old handler  #ifdef __PARALLEL_HASKELL__+{-# WARNING installHandler "installHandler: not available for Parallel Haskell"+ - #-} installHandler =   error "installHandler: not available for Parallel Haskell"+#elif !defined(HAVE_SIGNAL_H)++{-# WARNING installHandler+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+installHandler _ _ _ = ioError (ioeSetLocation unsupportedOperation "installHandler")+ #else  installHandler sig handler _maybe_mask = do@@ -447,6 +587,15 @@  #endif /* !__PARALLEL_HASKELL__ */ +#if !defined(HAVE_ALARM)++scheduleAlarm :: Int -> IO Int+{-# WARNING scheduleAlarm+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_ALARM@)" #-}+scheduleAlarm _ = ioError (ioeSetLocation unsupportedOperation "scheduleAlarm")++#else+ -- ----------------------------------------------------------------------------- -- Alarms @@ -460,9 +609,23 @@ foreign import ccall unsafe "alarm"   c_alarm :: CUInt -> IO CUInt +#endif // HAVE_ALARM+ -- ----------------------------------------------------------------------------- -- The NOCLDSTOP flag +#if !defined(HAVE_SIGNAL_H)++{-# WARNING setStoppedChildFlag "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+setStoppedChildFlag :: Bool -> IO Bool+setStoppedChildFlag _ = ioError (ioeSetLocation unsupportedOperation "setStoppedChildFlag")++{-# WARNING queryStoppedChildFlag "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+queryStoppedChildFlag :: IO Bool+queryStoppedChildFlag = ioError (ioeSetLocation unsupportedOperation "queryStoppedChildFlag")++#else+ foreign import ccall "&nocldstop" nocldstop :: Ptr Int  -- | Tells the system whether or not to set the @SA_NOCLDSTOP@ flag when@@ -479,12 +642,57 @@     rc <- peek nocldstop     return (rc == (0::Int)) +#endif+ -- ----------------------------------------------------------------------------- -- Manipulating signal sets +#if defined(HAVE_SIGNAL_H)+ newtype SignalSet = SignalSet (ForeignPtr CSigset) +#else++data SignalSet++#endif // HAVE_SIGNAL_H++#if !defined(HAVE_SIGNAL_H)+ emptySignalSet :: SignalSet+{-# WARNING emptySignalSet+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+emptySignalSet = throw (ioeSetLocation unsupportedOperation "emptySignalSet")++fullSignalSet :: SignalSet+{-# WARNING fullSignalSet+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+fullSignalSet = throw (ioeSetLocation unsupportedOperation "fullSignalSet")++reservedSignals :: SignalSet+{-# WARNING reservedSignals+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+reservedSignals = throw (ioeSetLocation unsupportedOperation "reservedSignals")++infixr `addSignal`, `deleteSignal`+addSignal :: Signal -> SignalSet -> SignalSet+{-# WARNING addSignal+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+addSignal _ _ = throw (ioeSetLocation unsupportedOperation "addSignal")++deleteSignal :: Signal -> SignalSet -> SignalSet+{-# WARNING deleteSignal+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+deleteSignal _ _ = throw (ioeSetLocation unsupportedOperation "deleteSignal")++inSignalSet :: Signal -> SignalSet -> Bool+{-# WARNING inSignalSet+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+inSignalSet _ _ = throw (ioeSetLocation unsupportedOperation "inSignalSet")++#else++emptySignalSet :: SignalSet emptySignalSet = unsafePerformIO $ do   fp <- mallocForeignPtrBytes sizeof_sigset_t   throwErrnoIfMinus1_ "emptySignalSet" (withForeignPtr fp $ c_sigemptyset)@@ -528,6 +736,32 @@     r <- throwErrnoIfMinus1 "inSignalSet" (c_sigismember p sig)     return (r /= 0) +#endif // HAVE_SIGNAL_H++#if !defined(HAVE_SIGNAL_H)++getSignalMask :: IO SignalSet+{-# WARNING getSignalMask+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+getSignalMask = ioError (ioeSetLocation unsupportedOperation "getSignalMask")++setSignalMask :: SignalSet -> IO ()+{-# WARNING setSignalMask+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+setSignalMask _ = ioError (ioeSetLocation unsupportedOperation "setSignalMask")++blockSignals :: SignalSet -> IO ()+{-# WARNING blockSignals+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+blockSignals _ = ioError (ioeSetLocation unsupportedOperation "blockSignals")++unblockSignals :: SignalSet -> IO ()+{-# WARNING unblockSignals+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+unblockSignals _ = ioError (ioeSetLocation unsupportedOperation "unblockSignals")++#else+ -- | @getSignalMask@ calls @sigprocmask@ to determine the --   set of interrupts which are currently being blocked. getSignalMask :: IO SignalSet@@ -559,6 +793,22 @@ unblockSignals :: SignalSet -> IO () unblockSignals set = sigProcMask "unblockSignals" (CONST_SIG_UNBLOCK :: CInt) set +#endif // HAVE_SIGNAL_H++#if !defined(HAVE_SIGNAL_H)++getPendingSignals :: IO SignalSet+{-# WARNING getPendingSignals+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+getPendingSignals = ioError (ioeSetLocation unsupportedOperation "getPendingSignals")++awaitSignal :: Maybe SignalSet -> IO ()+{-# WARNING awaitSignal+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SIGNAL_H@)" #-}+awaitSignal _ = ioError (ioeSetLocation unsupportedOperation "awaitSignal")++#else+ -- | @getPendingSignals@ calls @sigpending@ to obtain --   the set of interrupts which have been received but are currently blocked. getPendingSignals :: IO SignalSet@@ -594,21 +844,13 @@   -- XXX My manpage says it can also return EFAULT. And why is ignoring   -- EINTR the right thing to do? -foreign import ccall unsafe "sigsuspend"-  c_sigsuspend :: Ptr CSigset -> IO CInt+#endif // HAVE_SIGNAL_H -#if defined(darwin_HOST_OS) && __GLASGOW_HASKELL__ < 706--- see http://ghc.haskell.org/trac/ghc/ticket/7359#comment:3--- To be removed when support for GHC 7.4.x is dropped-foreign import ccall unsafe "__hscore_sigdelset"-  c_sigdelset   :: Ptr CSigset -> CInt -> IO CInt+#if defined(HAVE_SIGNAL_H) -foreign import ccall unsafe "__hscore_sigfillset"-  c_sigfillset  :: Ptr CSigset -> IO CInt+foreign import ccall unsafe "sigsuspend"+  c_sigsuspend :: Ptr CSigset -> IO CInt -foreign import ccall unsafe "__hscore_sigismember"-  c_sigismember :: Ptr CSigset -> CInt -> IO CInt-#else foreign import capi unsafe "signal.h sigdelset"   c_sigdelset   :: Ptr CSigset -> CInt -> IO CInt @@ -617,7 +859,8 @@  foreign import capi unsafe "signal.h sigismember"   c_sigismember :: Ptr CSigset -> CInt -> IO CInt-#endif  foreign import ccall unsafe "sigpending"   c_sigpending :: Ptr CSigset -> IO CInt++#endif // HAVE_SIGNAL_H
System/Posix/Temp.hsc view
@@ -1,9 +1,5 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Temp@@ -34,6 +30,19 @@ import System.Posix.Types import System.Posix.Internals (withFilePath, peekFilePath) +#if !defined(HAVE_MKSTEMP)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++#if !defined(HAVE_MKSTEMP)++{-# WARNING mkstemp "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_MKSTEMP@)" #-}+mkstemp :: String -> IO (FilePath, Handle)+mkstemp _ = ioError (ioeSetLocation unsupportedOperation "mkstemp")++#else+ foreign import capi unsafe "HsUnix.h mkstemp"   c_mkstemp :: CString -> IO CInt @@ -53,6 +62,8 @@     h <- fdToHandle (Fd fd)     return (name, h) +#endif // HAVE_MKSTEMP+ #if HAVE_MKSTEMPS foreign import capi unsafe "HsUnix.h mkstemps"   c_mkstemps :: CString -> CInt -> IO CInt@@ -78,6 +89,7 @@     h <- fdToHandle (Fd fd)     return (name, h) #else+{-# WARNING mkstemps "System.Posix.Temp.mkstemps: not available on this platform" #-} mkstemps = error "System.Posix.Temp.mkstemps: not available on this platform" #endif @@ -103,7 +115,7 @@     return name #else   name <- mktemp template-  h <- createDirectory name (toEnum 0o700)+  _ <- createDirectory name (toEnum 0o700)   return name #endif @@ -118,7 +130,6 @@ mktemp :: String -> IO String mktemp template = do   withFilePath template $ \ ptr -> do-    ptr <- throwErrnoIfNull "mktemp" (c_mktemp ptr)-    peekFilePath ptr+    ptr' <- throwErrnoIfNull "mktemp" (c_mktemp ptr)+    peekFilePath ptr' #endif-
System/Posix/Temp/ByteString.hsc view
@@ -1,9 +1,5 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Temp.ByteString@@ -39,6 +35,19 @@ import System.Posix.IO import System.Posix.Types +#if !defined(HAVE_MKSTEMP)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++#if !defined(HAVE_MKSTEMP)++{-# WARNING mkstemp "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_MKSTEMP@)" #-}+mkstemp :: ByteString -> IO (RawFilePath, Handle)+mkstemp _ = ioError (ioeSetLocation unsupportedOperation "mkstemp")++#else+ foreign import capi unsafe "HsUnix.h mkstemp"   c_mkstemp :: CString -> IO CInt @@ -58,6 +67,8 @@     h <- fdToHandle (Fd fd)     return (name, h) +#endif // HAVE_MKSTEMP+ #if HAVE_MKSTEMPS foreign import capi unsafe "HsUnix.h mkstemps"   c_mkstemps :: CString -> CInt -> IO CInt@@ -79,6 +90,7 @@     h <- fdToHandle (Fd fd)     return (name, h) #else+{-# WARNING mkstemps "System.Posix.Temp.mkstemps: not available on this platform"  #-} mkstemps = error "System.Posix.Temp.mkstemps: not available on this platform" #endif @@ -103,7 +115,7 @@     return name #else   name <- mktemp template-  h <- createDirectory (BC.unpack name) (toEnum 0o700)+  _ <- createDirectory (BC.unpack name) (toEnum 0o700)   return name #endif @@ -118,7 +130,6 @@ mktemp :: ByteString -> IO RawFilePath mktemp template = do   withFilePath template $ \ ptr -> do-    ptr <- throwErrnoIfNull "mktemp" (c_mktemp ptr)-    peekFilePath ptr+    ptr' <- throwErrnoIfNull "mktemp" (c_mktemp ptr)+    peekFilePath ptr' #endif-
+ System/Posix/Temp/PosixString.hsc view
@@ -0,0 +1,123 @@+{-# LANGUAGE CApiFFI #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Temp.PosixString+-- Copyright   :  (c) Volker Stolz <vs@foldr.org>+--                    Deian Stefan <deian@cs.stanford.edu>+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org, vs@foldr.org, deian@cs.stanford.edu+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX temporary file and directory creation functions.+--+-----------------------------------------------------------------------------++module System.Posix.Temp.PosixString (+        mkstemp, mkstemps, mkdtemp+    ) where++#include "HsUnix.h"++import qualified System.OsPath.Data.ByteString.Short as BC+import Data.Word++import Foreign.C++import System.OsPath.Types+import System.IO+import System.Posix.PosixPath.FilePath+import System.OsString.Internal.Types (PosixString(..))+#if !HAVE_MKDTEMP+import System.Posix.Directory.PosixPath (createDirectory)+#endif+import System.Posix.IO.PosixString+import System.Posix.Types++foreign import capi unsafe "HsUnix.h mkstemp"+  c_mkstemp :: CString -> IO CInt++-- | Make a unique filename and open it for reading\/writing. The returned+-- 'PosixPath' is the (possibly relative) path of the created file, which is+-- padded with 6 random characters. The argument is the desired prefix of the+-- filepath of the temporary file to be created.+--+-- If you aren't using GHC or Hugs then this function simply wraps mktemp and+-- so shouldn't be considered safe.+mkstemp :: PosixString -> IO (PosixPath, Handle)+mkstemp (PosixString template') = do+  let template = PosixString $ template' `BC.append` (BC.pack [_X,_X,_X,_X,_X,_X])+  withFilePath template $ \ ptr -> do+    fd <- throwErrnoIfMinus1 "mkstemp" (c_mkstemp ptr)+    name <- peekFilePath ptr+    h <- fdToHandle (Fd fd)+    return (name, h)++#if HAVE_MKSTEMPS+foreign import capi unsafe "HsUnix.h mkstemps"+  c_mkstemps :: CString -> CInt -> IO CInt+#endif++-- |'mkstemps' - make a unique filename with a given prefix and suffix+-- and open it for reading\/writing (only safe on GHC & Hugs).+-- The returned 'PosixPath' is the (possibly relative) path of+-- the created file, which contains  6 random characters in between+-- the prefix and suffix.+mkstemps :: PosixString -> PosixString -> IO (PosixPath, Handle)+#if HAVE_MKSTEMPS+mkstemps (PosixString prefix) (PosixString suffix) = do+  let template = PosixString $ prefix `BC.append` (BC.pack [_X,_X,_X,_X,_X,_X]) `BC.append` suffix+      lenOfsuf = (fromIntegral $ BC.length suffix) :: CInt+  withFilePath template $ \ ptr -> do+    fd <- throwErrnoIfMinus1 "mkstemps" (c_mkstemps ptr lenOfsuf)+    name <- peekFilePath ptr+    h <- fdToHandle (Fd fd)+    return (name, h)+#else+mkstemps = error "System.Posix.Temp.mkstemps: not available on this platform"+#endif++#if HAVE_MKDTEMP+foreign import capi unsafe "HsUnix.h mkdtemp"+  c_mkdtemp :: CString -> IO CString+#endif++-- | Make a unique directory. The returned 'PosixPath' is the path of the+-- created directory, which is padded with 6 random characters. The argument is+-- the desired prefix of the filepath of the temporary directory to be created.+--+-- If you aren't using GHC or Hugs then this function simply wraps mktemp and+-- so shouldn't be considered safe.+mkdtemp :: PosixString -> IO PosixPath+mkdtemp (PosixString template') = do+  let template = PosixString $ template' `BC.append` (BC.pack [_X,_X,_X,_X,_X,_X])+#if HAVE_MKDTEMP+  withFilePath template $ \ ptr -> do+    _ <- throwErrnoIfNull "mkdtemp" (c_mkdtemp ptr)+    name <- peekFilePath ptr+    return name+#else+  name <- mktemp template+  h <- createDirectory name (toEnum 0o700)+  return name+#endif++#if !HAVE_MKDTEMP++foreign import ccall unsafe "mktemp"+  c_mktemp :: CString -> IO CString++-- | Make a unique file name It is required that the template have six trailing+-- \'X\'s. This function should be considered deprecated.+{-# WARNING mktemp "This function is unsafe; use mkstemp instead" #-}+mktemp :: PosixString -> IO PosixPath+mktemp template = do+  withFilePath template $ \ ptr -> do+    ptr <- throwErrnoIfNull "mktemp" (c_mktemp ptr)+    peekFilePath ptr+#endif++_X :: Word8+_X = 0x58+
System/Posix/Terminal.hsc view
@@ -1,9 +1,5 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Terminal@@ -84,7 +80,7 @@  import System.Posix.Internals (peekFilePath) -#if !HAVE_CTERMID+#if !(HAVE_CTERMID && defined(HAVE_TERMIOS_H)) import System.IO.Error ( ioeSetLocation ) import GHC.IO.Exception ( unsupportedOperation ) #endif@@ -111,7 +107,7 @@ -- provide @ctermid(3)@ (use @#if HAVE_CTERMID@ CPP guard to -- detect availability). getControllingTerminalName :: IO FilePath-#if HAVE_CTERMID+#if HAVE_CTERMID && defined(HAVE_TERMIOS_H) getControllingTerminalName = do   s <- throwErrnoIfNull "getControllingTerminalName" (c_ctermid nullPtr)   peekFilePath s@@ -134,17 +130,12 @@   s <- throwErrnoIfNull "getSlaveTerminalName" (c_ptsname fd)   peekFilePath s -# if __GLASGOW_HASKELL__ < 800--- see comment in cbits/HsUnix.c-foreign import ccall unsafe "__hsunix_ptsname"-  c_ptsname :: CInt -> IO CString-# else foreign import capi unsafe "HsUnix.h ptsname"   c_ptsname :: CInt -> IO CString-# endif #else getSlaveTerminalName _ =     ioError (errnoToIOError "getSlaveTerminalName" eNOSYS Nothing Nothing)+{-# WARNING getSlaveTerminalName "getSlaveTerminalName: not available on this platform" #-} #endif  -- -----------------------------------------------------------------------------@@ -170,12 +161,12 @@             -> IO CInt #else openPseudoTerminal = do-  (Fd master) <- openFd "/dev/ptmx" ReadWrite Nothing+  (Fd master) <- openFd "/dev/ptmx" ReadWrite                         defaultFileFlags{noctty=True}   throwErrnoIfMinus1_ "openPseudoTerminal" (c_grantpt master)   throwErrnoIfMinus1_ "openPseudoTerminal" (c_unlockpt master)   slaveName <- getSlaveTerminalName (Fd master)-  slave <- openFd slaveName ReadWrite Nothing defaultFileFlags{noctty=True}+  slave <- openFd slaveName ReadWrite defaultFileFlags{noctty=True}   pushModule slave "ptem"   pushModule slave "ldterm" # ifndef __hpux@@ -183,6 +174,10 @@ # endif /* __hpux */   return (Fd master, slave) +# ifndef HAVE_PTSNAME+{-# WARNING openPseudoTerminal "openPseudoTerminal: not available on this platform (neither OPENPTY nor PTSNAME available)" #-}+# endif  /* HAVE_PTSNAME */+ -- Push a STREAMS module, for System V systems. pushModule :: Fd -> String -> IO () pushModule (Fd fd) name =@@ -194,26 +189,16 @@   c_push_module :: CInt -> CString -> IO CInt  #ifdef HAVE_PTSNAME-# if __GLASGOW_HASKELL__ < 800--- see comment in cbits/HsUnix.c-foreign import ccall unsafe "__hsunix_grantpt"-  c_grantpt :: CInt -> IO CInt--foreign import ccall unsafe "__hsunix_unlockpt"-  c_unlockpt :: CInt -> IO CInt-# else foreign import capi unsafe "HsUnix.h grantpt"   c_grantpt :: CInt -> IO CInt  foreign import capi unsafe "HsUnix.h unlockpt"   c_unlockpt :: CInt -> IO CInt-# endif #else c_grantpt :: CInt -> IO CInt-c_grantpt _ = return (fromIntegral 0)+c_grantpt _ = pure 0  c_unlockpt :: CInt -> IO CInt-c_unlockpt _ = return (fromIntegral 0)+c_unlockpt _ = pure 0 #endif /* HAVE_PTSNAME */ #endif /* !HAVE_OPENPTY */-
System/Posix/Terminal/ByteString.hsc view
@@ -1,9 +1,5 @@ {-# LANGUAGE CApiFFI #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Terminal.ByteString@@ -92,7 +88,7 @@  import System.Posix.ByteString.FilePath -#if !HAVE_CTERMID+#if !(HAVE_CTERMID && defined(HAVE_TERMIOS_H)) import System.IO.Error ( ioeSetLocation ) import GHC.IO.Exception ( unsupportedOperation ) #endif@@ -119,7 +115,7 @@ -- provide @ctermid(3)@ (use @#if HAVE_CTERMID@ CPP guard to -- detect availability). getControllingTerminalName :: IO RawFilePath-#if HAVE_CTERMID+#if HAVE_CTERMID && defined(HAVE_TERMIOS_H) getControllingTerminalName = do   s <- throwErrnoIfNull "getControllingTerminalName" (c_ctermid nullPtr)   peekFilePath s@@ -142,15 +138,10 @@   s <- throwErrnoIfNull "getSlaveTerminalName" (c_ptsname fd)   peekFilePath s -# if __GLASGOW_HASKELL__ < 800--- see comment in cbits/HsUnix.c-foreign import ccall unsafe "__hsunix_ptsname"-  c_ptsname :: CInt -> IO CString-# else foreign import capi unsafe "HsUnix.h ptsname"   c_ptsname :: CInt -> IO CString-# endif #else+{-# WARNING getSlaveTerminalName "getSlaveTerminalName: not available on this platform" #-} getSlaveTerminalName _ =     ioError (errnoToIOError "getSlaveTerminalName" eNOSYS Nothing Nothing) #endif@@ -178,12 +169,12 @@             -> IO CInt #else openPseudoTerminal = do-  (Fd master) <- openFd (B.pack "/dev/ptmx") ReadWrite Nothing+  (Fd master) <- openFd (B.pack "/dev/ptmx") ReadWrite                         defaultFileFlags{noctty=True}   throwErrnoIfMinus1_ "openPseudoTerminal" (c_grantpt master)   throwErrnoIfMinus1_ "openPseudoTerminal" (c_unlockpt master)   slaveName <- getSlaveTerminalName (Fd master)-  slave <- openFd slaveName ReadWrite Nothing defaultFileFlags{noctty=True}+  slave <- openFd slaveName ReadWrite defaultFileFlags{noctty=True}   pushModule slave "ptem"   pushModule slave "ldterm" # ifndef __hpux@@ -202,20 +193,11 @@   c_push_module :: CInt -> CString -> IO CInt  #if HAVE_PTSNAME-# if __GLASGOW_HASKELL__ < 800--- see comment in cbits/HsUnix.c-foreign import ccall unsafe "__hsunix_grantpt"-  c_grantpt :: CInt -> IO CInt--foreign import ccall unsafe "__hsunix_unlockpt"-  c_unlockpt :: CInt -> IO CInt-# else foreign import capi unsafe "HsUnix.h grantpt"   c_grantpt :: CInt -> IO CInt  foreign import capi unsafe "HsUnix.h unlockpt"   c_unlockpt :: CInt -> IO CInt-# endif #else c_grantpt :: CInt -> IO CInt c_grantpt _ = return (fromIntegral (0::Int))
System/Posix/Terminal/Common.hsc view
@@ -1,4 +1,6 @@ {-# LANGUAGE CApiFFI #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE Trustworthy #-}  -----------------------------------------------------------------------------@@ -48,7 +50,82 @@   minInput,   withMinInput, -  BaudRate(..),+  BaudRate+    ( ..+    , B0+    , B50+    , B75+    , B110+    , B134+    , B150+    , B200+    , B300+    , B600+    , B1200+    , B1800+    , B2400+    , B4800+    , B9600+    , B19200+    , B38400+#ifdef B7200+    , B7200+#endif+#ifdef B14400+    , B14400+#endif+#ifdef B28800+    , B28800+#endif+#ifdef B57600+    , B57600+#endif+#ifdef B76800+    , B76800+#endif+#ifdef B115200+    , B115200+#endif+#ifdef B230400+    , B230400+#endif+#ifdef B460800+    , B460800+#endif+#ifdef B500000+    , B500000+#endif+#ifdef B576000+    , B576000+#endif+#ifdef B921600+    , B921600+#endif+#ifdef B1000000+    , B1000000+#endif+#ifdef B1152000+    , B1152000+#endif+#ifdef B1500000+    , B1500000+#endif+#ifdef B2000000+    , B2000000+#endif+#ifdef B2500000+    , B2500000+#endif+#ifdef B3000000+    , B3000000+#endif+#ifdef B3500000+    , B3500000+#endif+#ifdef B4000000+    , B4000000+#endif+    ),   inputSpeed,   withInputSpeed,   outputSpeed,@@ -84,11 +161,14 @@ import System.Posix.Types import System.Posix.Internals ( CTermios ) -#if !HAVE_TCDRAIN+#if (!defined(HAVE_TCDRAIN)) || (!defined(HAVE_TERMIOS_H))+import Control.Exception ( throw ) import System.IO.Error ( ioeSetLocation ) import GHC.IO.Exception ( unsupportedOperation ) #endif +#if defined(HAVE_TERMIOS_H)+ -- ----------------------------------------------------------------------------- -- Terminal attributes @@ -100,48 +180,98 @@ withTerminalAttributes :: TerminalAttributes -> (Ptr CTermios -> IO a) -> IO a withTerminalAttributes (TerminalAttributes termios) = withForeignPtr termios +#else +data TerminalAttributes++#endif // HAVE_TERMIOS_H++ data TerminalMode         -- input flags-   = InterruptOnBreak           -- BRKINT-   | MapCRtoLF                  -- ICRNL-   | IgnoreBreak                -- IGNBRK-   | IgnoreCR                   -- IGNCR-   | IgnoreParityErrors         -- IGNPAR-   | MapLFtoCR                  -- INLCR-   | CheckParity                -- INPCK-   | StripHighBit               -- ISTRIP-   | StartStopInput             -- IXOFF-   | StartStopOutput            -- IXON-   | MarkParityErrors           -- PARMRK+   = InterruptOnBreak           -- ^ @BRKINT@ - Signal interrupt on break+   | MapCRtoLF                  -- ^ @ICRNL@ - Map CR to NL on input+   | IgnoreBreak                -- ^ @IGNBRK@ - Ignore break condition+   | IgnoreCR                   -- ^ @IGNCR@ - Ignore CR+   | IgnoreParityErrors         -- ^ @IGNPAR@ - Ignore characters with parity errors+   | MapLFtoCR                  -- ^ @INLCR@ - Map NL to CR on input+   | CheckParity                -- ^ @INPCK@ - Enable input parity check+   | StripHighBit               -- ^ @ISTRIP@ - Strip character+   | RestartOnAny               -- ^ @IXANY@ - Enable any character to restart output+   | StartStopInput             -- ^ @IXOFF@ - Enable start/stop input control+   | StartStopOutput            -- ^ @IXON@ - Enable start/stop output control+   | MarkParityErrors           -- ^ @PARMRK@ - Mark parity errors          -- output flags-   | ProcessOutput              -- OPOST-        -- ToDo: ONLCR, OCRNL, ONOCR, ONLRET, OFILL,-        --       NLDLY(NL0,NL1), CRDLY(CR0,CR1,CR2,CR2)-        --       TABDLY(TAB0,TAB1,TAB2,TAB3)-        --       BSDLY(BS0,BS1), VTDLY(VT0,VT1), FFDLY(FF0,FF1)+   | ProcessOutput              -- ^ @OPOST@ - Post-process output+   | MapLFtoCRLF                -- ^ @ONLCR@ - (XSI) Map NL to CR-NL on output+                                --+                                -- @since 2.8.0.0+   | OutputMapCRtoLF            -- ^ @OCRNL@ - (XSI) Map CR to NL on output+                                --+                                -- @since 2.8.0.0+   | NoCRAtColumnZero           -- ^ @ONOCR@ - (XSI) No CR output at column 0+                                --+                                -- @since 2.8.0.0+   | ReturnMeansLF              -- ^ @ONLRET@ - (XSI) NL performs CR function+                                --+                                -- @since 2.8.0.0+   | TabDelayMask0              -- ^ @TABDLY(TAB0)@ - (XSI) Select horizontal-tab delays: type 0+                                --+                                -- @since 2.8.0.0+   | TabDelayMask3              -- ^ @TABDLY(TAB3)@ - (XSI) Select horizontal-tab delays: type 3+                                --+                                -- @since 2.8.0.0          -- control flags-   | LocalMode                  -- CLOCAL-   | ReadEnable                 -- CREAD-   | TwoStopBits                -- CSTOPB-   | HangupOnClose              -- HUPCL-   | EnableParity               -- PARENB-   | OddParity                  -- PARODD+   | LocalMode                  -- ^ @CLOCAL@ - Ignore modem status lines+   | ReadEnable                 -- ^ @CREAD@ - Enable receiver+   | TwoStopBits                -- ^ @CSTOPB@ - Send two stop bits, else one+   | HangupOnClose              -- ^ @HUPCL@ - Hang up on last close+   | EnableParity               -- ^ @PARENB@ - Parity enable+   | OddParity                  -- ^ @PARODD@ - Odd parity, else even          -- local modes-   | EnableEcho                 -- ECHO-   | EchoErase                  -- ECHOE-   | EchoKill                   -- ECHOK-   | EchoLF                     -- ECHONL-   | ProcessInput               -- ICANON-   | ExtendedFunctions          -- IEXTEN-   | KeyboardInterrupts         -- ISIG-   | NoFlushOnInterrupt         -- NOFLSH-   | BackgroundWriteInterrupt   -- TOSTOP+   | EnableEcho                 -- ^ @ECHO@ - Enable echo+   | EchoErase                  -- ^ @ECHOE@ - Echo erase character as error-correcting backspace+   | EchoKill                   -- ^ @ECHOK@ - Echo KILL+   | EchoLF                     -- ^ @ECHONL@ - Echo NL+   | ProcessInput               -- ^ @ICANON@ - Canonical input (erase and kill processing)+   | ExtendedFunctions          -- ^ @IEXTEN@ - Enable extended input character processing+   | KeyboardInterrupts         -- ^ @ISIG@ - Enable signals+   | NoFlushOnInterrupt         -- ^ @NOFLSH@ - Disable flush after interrupt or quit+   | BackgroundWriteInterrupt   -- ^ @TOSTOP@ - Send @SIGTTOU@ for background output +#if !defined(HAVE_TERMIOS_H)+ withoutMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes+{-# WARNING withoutMode+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withoutMode _ _ = throw (ioeSetLocation unsupportedOperation "withoutMode")++withMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes+{-# WARNING withMode+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withMode _ _ = throw (ioeSetLocation unsupportedOperation "withMode")++terminalMode :: TerminalMode -> TerminalAttributes -> Bool+{-# WARNING terminalMode+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+terminalMode _ _ = throw (ioeSetLocation unsupportedOperation "terminalMode")++bitsPerByte :: TerminalAttributes -> Int+{-# WARNING bitsPerByte+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+bitsPerByte _ = throw (ioeSetLocation unsupportedOperation "bitsPerByte")++withBits :: TerminalAttributes -> Int -> TerminalAttributes+{-# WARNING withBits+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withBits _ _ = throw (ioeSetLocation unsupportedOperation "withBits")++#else++withoutMode :: TerminalAttributes -> TerminalMode -> TerminalAttributes withoutMode termios InterruptOnBreak = clearInputFlag (#const BRKINT) termios withoutMode termios MapCRtoLF = clearInputFlag (#const ICRNL) termios withoutMode termios IgnoreBreak = clearInputFlag (#const IGNBRK) termios@@ -150,10 +280,17 @@ withoutMode termios MapLFtoCR = clearInputFlag (#const INLCR) termios withoutMode termios CheckParity = clearInputFlag (#const INPCK) termios withoutMode termios StripHighBit = clearInputFlag (#const ISTRIP) termios+withoutMode termios RestartOnAny = clearInputFlag (#const IXANY) termios withoutMode termios StartStopInput = clearInputFlag (#const IXOFF) termios withoutMode termios StartStopOutput = clearInputFlag (#const IXON) termios withoutMode termios MarkParityErrors = clearInputFlag (#const PARMRK) termios withoutMode termios ProcessOutput = clearOutputFlag (#const OPOST) termios+withoutMode termios MapLFtoCRLF = clearOutputFlag (#const ONLCR) termios+withoutMode termios OutputMapCRtoLF = clearOutputFlag (#const OCRNL) termios+withoutMode termios NoCRAtColumnZero = clearOutputFlag (#const ONOCR) termios+withoutMode termios ReturnMeansLF = clearOutputFlag (#const ONLRET) termios+withoutMode termios TabDelayMask0 = clearOutputFlag (#const TAB0) termios+withoutMode termios TabDelayMask3 = clearOutputFlag (#const TAB3) termios withoutMode termios LocalMode = clearControlFlag (#const CLOCAL) termios withoutMode termios ReadEnable = clearControlFlag (#const CREAD) termios withoutMode termios TwoStopBits = clearControlFlag (#const CSTOPB) termios@@ -179,10 +316,17 @@ withMode termios MapLFtoCR = setInputFlag (#const INLCR) termios withMode termios CheckParity = setInputFlag (#const INPCK) termios withMode termios StripHighBit = setInputFlag (#const ISTRIP) termios+withMode termios RestartOnAny = setInputFlag (#const IXANY) termios withMode termios StartStopInput = setInputFlag (#const IXOFF) termios withMode termios StartStopOutput = setInputFlag (#const IXON) termios withMode termios MarkParityErrors = setInputFlag (#const PARMRK) termios withMode termios ProcessOutput = setOutputFlag (#const OPOST) termios+withMode termios MapLFtoCRLF = setOutputFlag (#const ONLCR) termios+withMode termios OutputMapCRtoLF = setOutputFlag (#const OCRNL) termios+withMode termios NoCRAtColumnZero = setOutputFlag (#const ONOCR) termios+withMode termios ReturnMeansLF = setOutputFlag (#const ONLRET) termios+withMode termios TabDelayMask0 = setOutputFlag (#const TAB0) termios+withMode termios TabDelayMask3 = setOutputFlag (#const TAB3) termios withMode termios LocalMode = setControlFlag (#const CLOCAL) termios withMode termios ReadEnable = setControlFlag (#const CREAD) termios withMode termios TwoStopBits = setControlFlag (#const CSTOPB) termios@@ -208,10 +352,17 @@ terminalMode MapLFtoCR = testInputFlag (#const INLCR) terminalMode CheckParity = testInputFlag (#const INPCK) terminalMode StripHighBit = testInputFlag (#const ISTRIP)+terminalMode RestartOnAny = testInputFlag (#const IXANY) terminalMode StartStopInput = testInputFlag (#const IXOFF) terminalMode StartStopOutput = testInputFlag (#const IXON) terminalMode MarkParityErrors = testInputFlag (#const PARMRK) terminalMode ProcessOutput = testOutputFlag (#const OPOST)+terminalMode MapLFtoCRLF = testOutputFlag (#const ONLCR)+terminalMode OutputMapCRtoLF = testOutputFlag (#const OCRNL)+terminalMode NoCRAtColumnZero = testOutputFlag (#const ONOCR)+terminalMode ReturnMeansLF = testOutputFlag (#const ONLRET)+terminalMode TabDelayMask0 = testOutputFlag (#const TAB0)+terminalMode TabDelayMask3 = testOutputFlag (#const TAB3) terminalMode LocalMode = testControlFlag (#const CLOCAL) terminalMode ReadEnable = testControlFlag (#const CREAD) terminalMode TwoStopBits = testControlFlag (#const CSTOPB)@@ -256,6 +407,8 @@     mask 8 = (#const CS8)     mask _ = error "withBits bit value out of range [5..8]" +#endif // HAVE_TERMIOS_H+ data ControlCharacter   = EndOfFile           -- VEOF   | EndOfLine           -- VEOL@@ -267,7 +420,102 @@   | Stop                -- VSTOP   | Suspend             -- VSUSP +#if !defined(HAVE_TERMIOS_H)+ controlChar :: TerminalAttributes -> ControlCharacter -> Maybe Char+{-# WARNING controlChar+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+controlChar _ _ = throw (ioeSetLocation unsupportedOperation "controlChar")++withCC :: TerminalAttributes+       -> (ControlCharacter, Char)+       -> TerminalAttributes+{-# WARNING withCC+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withCC _ _ = throw (ioeSetLocation unsupportedOperation "withCC")++withoutCC :: TerminalAttributes+          -> ControlCharacter+          -> TerminalAttributes+{-# WARNING withoutCC+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withoutCC _ _ = throw (ioeSetLocation unsupportedOperation "withoutCC")++inputTime :: TerminalAttributes -> Int+{-# WARNING inputTime+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+inputTime _ = throw (ioeSetLocation unsupportedOperation "inputTime")++withTime :: TerminalAttributes -> Int -> TerminalAttributes+{-# WARNING withTime+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withTime _ _ = throw (ioeSetLocation unsupportedOperation "withTime")++minInput :: TerminalAttributes -> Int+{-# WARNING minInput+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+minInput _ = throw (ioeSetLocation unsupportedOperation "minInput")++withMinInput :: TerminalAttributes -> Int -> TerminalAttributes+{-# WARNING withMinInput+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withMinInput _ _ = throw (ioeSetLocation unsupportedOperation "withMinInput")++-- | Placeholder implementation+newtype BaudRate = BaudRate Int deriving (Eq, Ord, Show, Enum, Real, Num)++-- | Hang up+pattern B0 :: BaudRate+pattern B0 = BaudRate 0+-- | 50 baud+pattern B50 :: BaudRate+pattern B50 = BaudRate 50+-- | 75 baud+pattern B75 :: BaudRate+pattern B75 = BaudRate 75+-- | 110 baud+pattern B110 :: BaudRate+pattern B110 = BaudRate 110+-- | 134.5 baud+pattern B134 :: BaudRate+pattern B134 = BaudRate 134+-- | 150 baud+pattern B150 :: BaudRate+pattern B150 = BaudRate 150+-- | 200 baud+pattern B200 :: BaudRate+pattern B200 = BaudRate 200+-- | 300 baud+pattern B300 :: BaudRate+pattern B300 = BaudRate 300+-- | 600 baud+pattern B600 :: BaudRate+pattern B600 = BaudRate 600+-- | 1200 baud+pattern B1200 :: BaudRate+pattern B1200 = BaudRate 1200+-- | 1800 baud+pattern B1800 :: BaudRate+pattern B1800 = BaudRate 1800+-- | 2400 baud+pattern B2400 :: BaudRate+pattern B2400 = BaudRate 2400+-- | 4800 baud+pattern B4800 :: BaudRate+pattern B4800 = BaudRate 4800+-- | 9600 baud+pattern B9600 :: BaudRate+pattern B9600 = BaudRate 9600+-- | 19200 baud+pattern B19200 :: BaudRate+pattern B19200 = BaudRate 19200+-- | 38400 baud+pattern B38400 :: BaudRate+pattern B38400 = BaudRate 38400++#else++controlChar :: TerminalAttributes -> ControlCharacter -> Maybe Char controlChar termios cc = unsafePerformIO $ do   withTerminalAttributes termios $ \p -> do     let c_cc = (#ptr struct termios, c_cc) p@@ -316,39 +564,209 @@     let c_cc = (#ptr struct termios, c_cc) p     pokeElemOff c_cc (#const VMIN) (fromIntegral count :: CCc) -data BaudRate-  = B0-  | B50-  | B75-  | B110-  | B134-  | B150-  | B200-  | B300-  | B600-  | B1200-  | B1800-  | B2400-  | B4800-  | B9600-  | B19200-  | B38400-  | B57600-  | B115200-  deriving (Eq, Show)+-- | Serial line baudrate.  The set of supported speeds is system-dependent.+-- Portable use of the provided pattern synonyms that are outside the list+-- mandated by POSIX requires @#ifdef@ guards.+--+-- Applications may need to be prepared to encounter speeds not known at+-- compile time, these can be handled generically via the 'BaudRate'+-- constructor.  In other words, the provided pattern synonyms are not+-- necessarily a @COMPLETE@ set.+--+-- All non-zero /pseudo-terminal/ baud rates are functionally equivalent, and+-- the @pty@ driver may accept any speed within a suitable range.  Requested+-- speeds may be rounded up or down to fit into the supported range.+--+newtype BaudRate = BaudRate CSpeed deriving (Eq, Ord, Show, Enum, Real, Num) +-- | Hang up+pattern B0 :: BaudRate+pattern B0 = BaudRate (#const B0)+-- | 50 baud+pattern B50 :: BaudRate+pattern B50 = BaudRate (#const B50)+-- | 75 baud+pattern B75 :: BaudRate+pattern B75 = BaudRate (#const B75)+-- | 110 baud+pattern B110 :: BaudRate+pattern B110 = BaudRate (#const B110)+-- | 134.5 baud+pattern B134 :: BaudRate+pattern B134 = BaudRate (#const B134)+-- | 150 baud+pattern B150 :: BaudRate+pattern B150 = BaudRate (#const B150)+-- | 200 baud+pattern B200 :: BaudRate+pattern B200 = BaudRate (#const B200)+-- | 300 baud+pattern B300 :: BaudRate+pattern B300 = BaudRate (#const B300)+-- | 600 baud+pattern B600 :: BaudRate+pattern B600 = BaudRate (#const B600)+-- | 1200 baud+pattern B1200 :: BaudRate+pattern B1200 = BaudRate (#const B1200)+-- | 1800 baud+pattern B1800 :: BaudRate+pattern B1800 = BaudRate (#const B1800)+-- | 2400 baud+pattern B2400 :: BaudRate+pattern B2400 = BaudRate (#const B2400)+-- | 4800 baud+pattern B4800 :: BaudRate+pattern B4800 = BaudRate (#const B4800)+-- | 9600 baud+pattern B9600 :: BaudRate+pattern B9600 = BaudRate (#const B9600)+-- | 19200 baud+pattern B19200 :: BaudRate+pattern B19200 = BaudRate (#const B19200)+-- | 38400 baud+pattern B38400 :: BaudRate+pattern B38400 = BaudRate (#const B38400)++#ifdef B7200+-- | 7200 baud, non-POSIX system-dependent extension+pattern B7200 :: BaudRate+pattern B7200 = BaudRate (#const B7200)+#endif+#ifdef B14400+-- | 14400 baud, non-POSIX system-dependent extension+pattern B14400 :: BaudRate+pattern B14400 = BaudRate (#const B14400)+#endif+#ifdef B28800+-- | 28800 baud, non-POSIX system-dependent extension+pattern B28800 :: BaudRate+pattern B28800 = BaudRate (#const B28800)+#endif+#ifdef B57600+-- | 57600 baud, non-POSIX system-dependent extension+pattern B57600 :: BaudRate+pattern B57600 = BaudRate (#const B57600)+#endif+#ifdef B76800+-- | 76800 baud, non-POSIX system-dependent extension+pattern B76800 :: BaudRate+pattern B76800 = BaudRate (#const B76800)+#endif+#ifdef B115200+-- | 115200 baud, non-POSIX system-dependent extension+pattern B115200 :: BaudRate+pattern B115200 = BaudRate (#const B115200)+#endif+#ifdef B230400+-- | 230400 baud, non-POSIX system-dependent extension+pattern B230400 :: BaudRate+pattern B230400 = BaudRate (#const B230400)+#endif+#ifdef B460800+-- | 460800 baud, non-POSIX system-dependent extension+pattern B460800 :: BaudRate+pattern B460800 = BaudRate (#const B460800)+#endif+#ifdef B500000+-- | 500000 baud, non-POSIX system-dependent extension+pattern B500000 :: BaudRate+pattern B500000 = BaudRate (#const B500000)+#endif+#ifdef B576000+-- | 576000 baud, non-POSIX system-dependent extension+pattern B576000 :: BaudRate+pattern B576000 = BaudRate (#const B576000)+#endif+#ifdef B921600+-- | 921600 baud, non-POSIX system-dependent extension+pattern B921600 :: BaudRate+pattern B921600 = BaudRate (#const B921600)+#endif+#ifdef B1000000+-- | 1000000 baud, non-POSIX system-dependent extension+pattern B1000000 :: BaudRate+pattern B1000000 = BaudRate (#const B1000000)+#endif+#ifdef B1152000+-- | 1152000 baud, non-POSIX system-dependent extension+pattern B1152000 :: BaudRate+pattern B1152000 = BaudRate (#const B1152000)+#endif+#ifdef B1500000+-- | 1500000 baud, non-POSIX system-dependent extension+pattern B1500000 :: BaudRate+pattern B1500000 = BaudRate (#const B1500000)+#endif+#ifdef B2000000+-- | 2000000 baud, non-POSIX system-dependent extension+pattern B2000000 :: BaudRate+pattern B2000000 = BaudRate (#const B2000000)+#endif+#ifdef B2500000+-- | 2500000 baud, non-POSIX system-dependent extension+pattern B2500000 :: BaudRate+pattern B2500000 = BaudRate (#const B2500000)+#endif+#ifdef B3000000+-- | 3000000 baud, non-POSIX system-dependent extension+pattern B3000000 :: BaudRate+pattern B3000000 = BaudRate (#const B3000000)+#endif+#ifdef B3500000+-- | 3500000 baud, non-POSIX system-dependent extension+pattern B3500000 :: BaudRate+pattern B3500000 = BaudRate (#const B3500000)+#endif+#ifdef B4000000+-- | 4000000 baud, non-POSIX system-dependent extension+pattern B4000000 :: BaudRate+pattern B4000000 = BaudRate (#const B4000000)+#endif++#endif // HAVE_TERMIOS_H++#if !defined(HAVE_TERMIOS_H)+ inputSpeed :: TerminalAttributes -> BaudRate+{-# WARNING inputSpeed+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+inputSpeed _ = throw (ioeSetLocation unsupportedOperation "inputSpeed")++withInputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes+{-# WARNING withInputSpeed+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withInputSpeed _ _ = throw (ioeSetLocation unsupportedOperation "withInputSpeed")++outputSpeed :: TerminalAttributes -> BaudRate+{-# WARNING outputSpeed+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+outputSpeed _ = throw (ioeSetLocation unsupportedOperation "outputSpeed")++withOutputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes+{-# WARNING withOutputSpeed+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+withOutputSpeed _ _ = throw (ioeSetLocation unsupportedOperation "withOutputSpeed")++getTerminalAttributes :: Fd -> IO TerminalAttributes+{-# WARNING getTerminalAttributes+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+getTerminalAttributes _ = ioError (ioeSetLocation unsupportedOperation "getTerminalAttributes")++#else++inputSpeed :: TerminalAttributes -> BaudRate inputSpeed termios = unsafePerformIO $ do   withTerminalAttributes termios $ \p -> do     w <- c_cfgetispeed p-    return (word2Baud w)+    return (BaudRate w)  foreign import capi unsafe "termios.h cfgetispeed"   c_cfgetispeed :: Ptr CTermios -> IO CSpeed  withInputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes-withInputSpeed termios br = unsafePerformIO $ do-  withNewTermios termios $ \p -> c_cfsetispeed p (baud2Word br)+withInputSpeed termios (BaudRate br) = unsafePerformIO $ do+  withNewTermios termios $ \p -> c_cfsetispeed p br  foreign import capi unsafe "termios.h cfsetispeed"   c_cfsetispeed :: Ptr CTermios -> CSpeed -> IO CInt@@ -358,14 +776,14 @@ outputSpeed termios = unsafePerformIO $ do   withTerminalAttributes termios $ \p ->  do     w <- c_cfgetospeed p-    return (word2Baud w)+    return (BaudRate w)  foreign import capi unsafe "termios.h cfgetospeed"   c_cfgetospeed :: Ptr CTermios -> IO CSpeed  withOutputSpeed :: TerminalAttributes -> BaudRate -> TerminalAttributes-withOutputSpeed termios br = unsafePerformIO $ do-  withNewTermios termios $ \p -> c_cfsetospeed p (baud2Word br)+withOutputSpeed termios (BaudRate br) = unsafePerformIO $ do+  withNewTermios termios $ \p -> c_cfsetospeed p br  foreign import capi unsafe "termios.h cfsetospeed"   c_cfsetospeed :: Ptr CTermios -> CSpeed -> IO CInt@@ -382,11 +800,35 @@ foreign import capi unsafe "termios.h tcgetattr"   c_tcgetattr :: CInt -> Ptr CTermios -> IO CInt +#endif // HAVE_TERMIOS_H+ data TerminalState   = Immediately   | WhenDrained   | WhenFlushed +#if !defined(HAVE_TERMIOS_H)++setTerminalAttributes :: Fd+                      -> TerminalAttributes+                      -> TerminalState+                      -> IO ()+{-# WARNING setTerminalAttributes+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+setTerminalAttributes _ _ _ = ioError (ioeSetLocation unsupportedOperation "setTerminalAttributes")++sendBreak :: Fd -> Int -> IO ()+{-# WARNING sendBreak+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+sendBreak _ _ = ioError (ioeSetLocation unsupportedOperation "sendBreak")++drainOutput :: Fd -> IO ()+{-# WARNING drainOutput+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+drainOutput _ = ioError (ioeSetLocation unsupportedOperation "drainOutput")++#else+ -- | @setTerminalAttributes fd attr ts@ calls @tcsetattr@ to change --   the @TerminalAttributes@ associated with @Fd@ @fd@ to --   @attr@, when the terminal is in the state indicated by @ts@.@@ -435,11 +877,22 @@ drainOutput _ = ioError (ioeSetLocation unsupportedOperation "drainOutput") #endif +#endif // HAVE_TERMIOS_H+ data QueueSelector   = InputQueue          -- TCIFLUSH   | OutputQueue         -- TCOFLUSH   | BothQueues          -- TCIOFLUSH +#if !defined(HAVE_TERMIOS_H)++discardData :: Fd -> QueueSelector -> IO ()+{-# WARNING discardData+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+discardData _ _ = ioError (ioeSetLocation unsupportedOperation "discardData")++#else+ -- | @discardData fd queues@ calls @tcflush@ to discard --   pending input and\/or output for @Fd@ @fd@, --   as indicated by the @QueueSelector@ @queues@.@@ -455,12 +908,33 @@ foreign import capi unsafe "termios.h tcflush"   c_tcflush :: CInt -> CInt -> IO CInt +#endif // HAVE_TERMIOS_H+ data FlowAction   = SuspendOutput       -- ^ TCOOFF   | RestartOutput       -- ^ TCOON   | TransmitStop        -- ^ TCIOFF   | TransmitStart       -- ^ TCION +#if !defined(HAVE_TERMIOS_H)++controlFlow :: Fd -> FlowAction -> IO ()+{-# WARNING controlFlow+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+controlFlow _ _ = ioError (ioeSetLocation unsupportedOperation "controlFlow")++getTerminalProcessGroupID :: Fd -> IO ProcessGroupID+{-# WARNING getTerminalProcessGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+getTerminalProcessGroupID _ = ioError (ioeSetLocation unsupportedOperation "getTerminalProcessGroupID")++setTerminalProcessGroupID :: Fd -> ProcessGroupID -> IO ()+{-# WARNING setTerminalProcessGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_TERMIOS_H@)" #-}+setTerminalProcessGroupID _ _ = ioError (ioeSetLocation unsupportedOperation "setTerminalProcessGroupID")++#else+ -- | @controlFlow fd action@ calls @tcflow@ to control the --   flow of data on @Fd@ @fd@, as indicated by --   @action@.@@ -498,6 +972,8 @@ foreign import ccall unsafe "tcsetpgrp"   c_tcsetpgrp :: CInt -> CPid -> IO CInt +#endif // HAVE_TERMIOS_H+ -- ----------------------------------------------------------------------------- -- file descriptor queries @@ -517,6 +993,8 @@  -- Convert Haskell ControlCharacter to Int +#if defined(HAVE_TERMIOS_H)+ cc2Word :: ControlCharacter -> Int cc2Word EndOfFile = (#const VEOF) cc2Word EndOfLine = (#const VEOL)@@ -528,65 +1006,6 @@ cc2Word Start     = (#const VSTART) cc2Word Stop      = (#const VSTOP) --- Convert Haskell BaudRate to unsigned integral type (Word)--baud2Word :: BaudRate -> CSpeed-baud2Word B0 = (#const B0)-baud2Word B50 = (#const B50)-baud2Word B75 = (#const B75)-baud2Word B110 = (#const B110)-baud2Word B134 = (#const B134)-baud2Word B150 = (#const B150)-baud2Word B200 = (#const B200)-baud2Word B300 = (#const B300)-baud2Word B600 = (#const B600)-baud2Word B1200 = (#const B1200)-baud2Word B1800 = (#const B1800)-baud2Word B2400 = (#const B2400)-baud2Word B4800 = (#const B4800)-baud2Word B9600 = (#const B9600)-baud2Word B19200 = (#const B19200)-baud2Word B38400 = (#const B38400)-#ifdef B57600-baud2Word B57600 = (#const B57600)-#else-baud2Word B57600 = error "B57600 not available on this system"-#endif-#ifdef B115200-baud2Word B115200 = (#const B115200)-#else-baud2Word B115200 = error "B115200 not available on this system"-#endif---- And convert a word back to a baud rate--- We really need some cpp macros here.--word2Baud :: CSpeed -> BaudRate-word2Baud x =-    if x == (#const B0) then B0-    else if x == (#const B50) then B50-    else if x == (#const B75) then B75-    else if x == (#const B110) then B110-    else if x == (#const B134) then B134-    else if x == (#const B150) then B150-    else if x == (#const B200) then B200-    else if x == (#const B300) then B300-    else if x == (#const B600) then B600-    else if x == (#const B1200) then B1200-    else if x == (#const B1800) then B1800-    else if x == (#const B2400) then B2400-    else if x == (#const B4800) then B4800-    else if x == (#const B9600) then B9600-    else if x == (#const B19200) then B19200-    else if x == (#const B38400) then B38400-#ifdef B57600-    else if x == (#const B57600) then B57600-#endif-#ifdef B115200-    else if x == (#const B115200) then B115200-#endif-    else error "unknown baud rate"- -- Clear termios i_flag  clearInputFlag :: CTcflag -> TerminalAttributes -> TerminalAttributes@@ -725,3 +1144,5 @@     _ <- action p1     return ()   return $ makeTerminalAttributes fp1++#endif // HAVE_TERMIOS_H
+ System/Posix/Terminal/PosixString.hsc view
@@ -0,0 +1,211 @@+{-# LANGUAGE CApiFFI #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.Terminal.PosixString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX Terminal support+--+-----------------------------------------------------------------------------++module System.Posix.Terminal.PosixString (+  -- * Terminal support++  -- ** Terminal attributes+  TerminalAttributes,+  getTerminalAttributes,+  TerminalState(..),+  setTerminalAttributes,++  TerminalMode(..),+  withoutMode,+  withMode,+  terminalMode,+  bitsPerByte,+  withBits,++  ControlCharacter(..),+  controlChar,+  withCC,+  withoutCC,++  inputTime,+  withTime,+  minInput,+  withMinInput,++  BaudRate(..),+  inputSpeed,+  withInputSpeed,+  outputSpeed,+  withOutputSpeed,++  -- ** Terminal operations+  sendBreak,+  drainOutput,+  QueueSelector(..),+  discardData,+  FlowAction(..),+  controlFlow,++  -- ** Process groups+  getTerminalProcessGroupID,+  setTerminalProcessGroupID,++  -- ** Testing a file descriptor+  queryTerminal,+  getTerminalName,+  getControllingTerminalName,++  -- ** Pseudoterminal operations+  openPseudoTerminal,+  getSlaveTerminalName+  ) where++#include "HsUnix.h"++import Foreign+import System.Posix.Types+import System.Posix.Terminal.Common+#ifndef HAVE_OPENPTY+import qualified System.OsPath.Data.ByteString.Short as SBS+import System.Posix.IO.ByteString (defaultFileFlags, openFd, noctty, OpenMode(ReadWrite))+import Data.ByteString.Char8 as B ( pack, )+import qualified System.OsPath.Data.ByteString.Short as BC+import System.OsString.Internal.Types (PosixString(..))+#endif++import Foreign.C hiding (+     throwErrnoPath,+     throwErrnoPathIf,+     throwErrnoPathIf_,+     throwErrnoPathIfNull,+     throwErrnoPathIfMinus1,+     throwErrnoPathIfMinus1_ )++import System.OsPath.Types+import System.Posix.PosixPath.FilePath++#if !(HAVE_CTERMID && defined(HAVE_TERMIOS_H))+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++-- | @getTerminalName fd@ calls @ttyname@ to obtain a name associated+--   with the terminal for @Fd@ @fd@. If @fd@ is associated+--   with a terminal, @getTerminalName@ returns the name of the+--   terminal.+getTerminalName :: Fd -> IO PosixPath+getTerminalName (Fd fd) = do+  s <- throwErrnoIfNull "getTerminalName" (c_ttyname fd)+  peekFilePath s++foreign import ccall unsafe "ttyname"+  c_ttyname :: CInt -> IO CString++-- | @getControllingTerminalName@ calls @ctermid@ to obtain+--   a name associated with the controlling terminal for the process.  If a+--   controlling terminal exists,+--   @getControllingTerminalName@ returns the name of the+--   controlling terminal.+--+-- Throws 'IOError' (\"unsupported operation\") if platform does not+-- provide @ctermid(3)@ (use @#if HAVE_CTERMID@ CPP guard to+-- detect availability).+getControllingTerminalName :: IO PosixPath+#if HAVE_CTERMID && defined(HAVE_TERMIOS_H)+getControllingTerminalName = do+  s <- throwErrnoIfNull "getControllingTerminalName" (c_ctermid nullPtr)+  peekFilePath s++foreign import capi unsafe "termios.h ctermid"+  c_ctermid :: CString -> IO CString+#else+{-# WARNING getControllingTerminalName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_CTERMID@)" #-}+getControllingTerminalName = ioError (ioeSetLocation unsupportedOperation "getControllingTerminalName")+#endif++-- | @getSlaveTerminalName@ calls @ptsname@ to obtain the name of the+-- slave terminal associated with a pseudoterminal pair.  The file+-- descriptor to pass in must be that of the master.+getSlaveTerminalName :: Fd -> IO PosixPath++#ifdef HAVE_PTSNAME+getSlaveTerminalName (Fd fd) = do+  s <- throwErrnoIfNull "getSlaveTerminalName" (c_ptsname fd)+  peekFilePath s++foreign import capi unsafe "HsUnix.h ptsname"+  c_ptsname :: CInt -> IO CString+#else+{-# WARNING getSlaveTerminalName "getSlaveTerminalName: not available on this platform" #-}+getSlaveTerminalName _ =+    ioError (errnoToIOError "getSlaveTerminalName" eNOSYS Nothing Nothing)+#endif++-- -----------------------------------------------------------------------------+-- openPseudoTerminal needs to be here because it depends on+-- getSlaveTerminalName.++-- | @openPseudoTerminal@ creates a pseudoterminal (pty) pair, and+-- returns the newly created pair as a (@master@, @slave@) tuple.+openPseudoTerminal :: IO (Fd, Fd)++#ifdef HAVE_OPENPTY+openPseudoTerminal =+  alloca $ \p_master ->+    alloca $ \p_slave -> do+      throwErrnoIfMinus1_ "openPty"+          (c_openpty p_master p_slave nullPtr nullPtr nullPtr)+      master <- peek p_master+      slave <- peek p_slave+      return (Fd master, Fd slave)++foreign import ccall unsafe "openpty"+  c_openpty :: Ptr CInt -> Ptr CInt -> CString -> Ptr CTermios -> Ptr a+            -> IO CInt+#else+openPseudoTerminal = do+  (Fd master) <- openFd (B.pack "/dev/ptmx") ReadWrite+                        defaultFileFlags{noctty=True}+  throwErrnoIfMinus1_ "openPseudoTerminal" (c_grantpt master)+  throwErrnoIfMinus1_ "openPseudoTerminal" (c_unlockpt master)+  slaveName <- getSlaveTerminalName (Fd master)+  slave <- openFd (SBS.fromShort . getPosixString $ slaveName) ReadWrite defaultFileFlags{noctty=True}+  pushModule slave "ptem"+  pushModule slave "ldterm"+# ifndef __hpux+  pushModule slave "ttcompat"+# endif /* __hpux */+  return (Fd master, slave)++-- Push a STREAMS module, for System V systems.+pushModule :: Fd -> String -> IO ()+pushModule (Fd fd) name =+  withCString name $ \p_name ->+    throwErrnoIfMinus1_ "openPseudoTerminal"+                        (c_push_module fd p_name)++foreign import ccall unsafe "__hsunix_push_module"+  c_push_module :: CInt -> CString -> IO CInt++#if HAVE_PTSNAME+foreign import capi unsafe "HsUnix.h grantpt"+  c_grantpt :: CInt -> IO CInt++foreign import capi unsafe "HsUnix.h unlockpt"+  c_unlockpt :: CInt -> IO CInt+#else+c_grantpt :: CInt -> IO CInt+c_grantpt _ = return (fromIntegral (0::Int))++c_unlockpt :: CInt -> IO CInt+c_unlockpt _ = return (fromIntegral (0::Int))+#endif /* HAVE_PTSNAME */+#endif /* !HAVE_OPENPTY */
System/Posix/Time.hs view
@@ -1,10 +1,5 @@ {-# LANGUAGE CApiFFI #-}-{-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Time
System/Posix/Unistd.hsc view
@@ -1,10 +1,6 @@ {-# LANGUAGE CApiFFI #-} {-# LANGUAGE NondecreasingIndentation #-}-#if __GLASGOW_HASKELL__ >= 709 {-# LANGUAGE Safe #-}-#else-{-# LANGUAGE Trustworthy #-}-#endif ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Unistd@@ -156,6 +152,7 @@ -- /GHC Note/: the comment for 'usleep' also applies here. nanosleep :: Integer -> IO () #ifndef HAVE_NANOSLEEP+{-# WARNING nanosleep "nanosleep: not available on this platform" #-} nanosleep = error "nanosleep: not available on this platform" #else nanosleep 0 = return ()
System/Posix/User.hsc view
@@ -1,4 +1,4 @@-{-# LANGUAGE Trustworthy, CApiFFI #-}+{-# LANGUAGE Trustworthy, CApiFFI, PatternSynonyms, ViewPatterns #-} ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.User@@ -25,13 +25,25 @@     getEffectiveUserName,      -- *** The group database-    GroupEntry(..),+    groupName,+    groupPassword,+    groupID,+    groupMembers,+    pattern GroupEntry,     getGroupEntryForID,     getGroupEntryForName,     getAllGroupEntries,      -- *** The user database-    UserEntry(..),+    userName,+    userPassword,+    userID,+    userGroupID,+    userGecos,+    homeDirectory,+    userShell,+    pattern UserEntry,+     getUserEntryForID,     getUserEntryForName,     getAllUserEntries,@@ -53,23 +65,203 @@ import Foreign.Ptr import Foreign.Marshal import Foreign.Storable+import System.Posix.User.Common ( UserEntry, GroupEntry+#if defined(HAVE_PWD_H)+      , unpackUserEntry, unpackGroupEntry, LKUPTYPE(..), CPasswd, CGroup+#endif+  )+import qualified System.Posix.User.Common as User -#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R) || defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)-import Control.Concurrent.MVar  ( MVar, newMVar, withMVar )+#if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)+#if defined(freebsd_HOST_OS)+import Control.Concurrent (runInBoundThread, rtsSupportsBoundThreads) #endif-#ifdef HAVE_GETPWENT+import Control.Concurrent.MVar ( MVar, newMVar, withMVar ) import Control.Exception #endif import Control.Monad import System.IO.Error+import qualified Data.ByteString.Char8 as C8 --- internal types-data {-# CTYPE "struct passwd" #-} CPasswd-data {-# CTYPE "struct group"  #-} CGroup+#if !defined(HAVE_PWD_H)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif ++#if !defined(HAVE_PWD_H)++getRealUserID :: IO UserID+{-# WARNING getRealUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getRealUserID = ioError (ioeSetLocation unsupportedOperation "getRealUserID")++getRealGroupID :: IO GroupID+{-# WARNING getRealGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getRealGroupID = ioError (ioeSetLocation unsupportedOperation "getRealGroupID")++getEffectiveUserID :: IO UserID+{-# WARNING getEffectiveUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getEffectiveUserID = ioError (ioeSetLocation unsupportedOperation "getEffectiveUserID")++getEffectiveGroupID :: IO GroupID+{-# WARNING getEffectiveGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getEffectiveGroupID = ioError (ioeSetLocation unsupportedOperation "getEffectiveGroupID")++getGroups :: IO [GroupID]+{-# WARNING getGroups+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getGroups = ioError (ioeSetLocation unsupportedOperation "getGroups")++setGroups :: [GroupID] -> IO ()+{-# WARNING setGroups+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setGroups _ = ioError (ioeSetLocation unsupportedOperation "setGroups")++getLoginName :: IO String+{-# WARNING getLoginName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getLoginName = ioError (ioeSetLocation unsupportedOperation "getLoginName")++setUserID :: UserID -> IO ()+{-# WARNING setUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setUserID _ = ioError (ioeSetLocation unsupportedOperation "setUserID")++setEffectiveUserID :: UserID -> IO ()+{-# WARNING setEffectiveUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setEffectiveUserID _ = ioError (ioeSetLocation unsupportedOperation "setEffectiveUserID")++setGroupID :: GroupID -> IO ()+{-# WARNING setGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setGroupID _ = ioError (ioeSetLocation unsupportedOperation "setGroupID")++setEffectiveGroupID :: GroupID -> IO ()+{-# WARNING setEffectiveGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setEffectiveGroupID _ = ioError (ioeSetLocation unsupportedOperation "setEffectiveGroupID")++getEffectiveUserName :: IO String+{-# WARNING getEffectiveUserName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getEffectiveUserName = ioError (ioeSetLocation unsupportedOperation "getEffectiveUserName")++#else -- -------------------------------------------------------------------------------- user environemnt+-- Thread safety of passwd/group database access APIs:+--+-- All supported unix platforms have @get(pw|gr)(nam|[ug]id)_r(3)@, which+-- store the result in a caller provided buffer, which solves the most+-- immediate thread-safety issues.+--+-- Things are more complicated for getpwent(3) and getgrent(3).+--+-- * On Linux systems, these read a global open file, opened via+--   setpwent(3) and closed via endpwent(3).  Only one thread at+--   a time can safely iterate through the file.+--+-- * On macOS (through Catalina 10.15), there is no getpwent_r(3) or+--   getgrent_r(3), so a lock is also required for safe buffer sharing.+--+-- * On FreeBSD, in the default configuration with passwd lookups configured+--   in nsswitch.conf to use "compat" rather than "files", the getpwnam_r(3)+--   and getpwuid_r(3) functions reset the iterator index used by getpwent(3).+--   A bug [report](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=252094)+--   has been filed to track this long-standing issue.  A similar issue affects+--   getgrent(3), this time regardless of the nsswitch.conf setting.  This too+--   should be fixed at some point in the future.  The state in question is+--   thread-specific, so both issues only affect overlapping use of the @*ent@+--   and @*(nam|[ug]id)_r(3)@ functions in the /same/ thread.+--+-- * Despite rather similar manpages for getpwent(3) and getpwnam(3), ... as+--   on FreeBSD, the above issue is not seen on NetBSD or macOS.+--+--   This is not an issue with 1-to-1 thread models, where the code executing+--   @get(pw|gr)ent@ has exclusive use of its thread, but it is a real issue+--   for Haskell with its many-to-1 green threads, because multiple `forkIO`+--   threads may take turns using the same underlying OS thread, breaking the+--   thread-safety of the @*_r@ functions, which mutate the file-offset of the+--   open file shared with any overlapping execution of @*ent(3)@ in the same+--   thread.+--+-- Consequently, correct portable support for @get(pw|gr)ent(3)@ is rather+-- non-trivial.  In the threaded runtime, we can run these functions in a+-- /bound thread/ (via 'forkOS'), thereby avoiding the FreeBSD issues.  We+-- still need a lock to serialise multiple threads calling these functions+-- on at least macOS for lack of @_r@ equivalents.  While on FreeBSD we could+-- use @getpwent_r(3)@ and @getgrent_r(3)@ in a bound thread without any+-- locks, implementing this special case is likely not worthwhile.+--+-- In the non-threaded runtime, `forkOS` is not available, and so on FreeBSD+-- systems we have to also lock the @*(nam|[ug]id)_r(3)@ functions to avoid+-- concurrent use with @*ent(3)@.+--+-- FWIW, the below Perl one-liners will quickly show whether interleaved calls+-- of getpwuid() or getgrgid() disturb iteration through all the entries. If+-- each line of output is distinct, there is likely no issue.  If the same+-- passwd or group entry repeats multiple times, the system is affected.+--+-- > for ($i=0;$i<3;++$i) {getpwuid(0); print join(":",getpwent()),"\n"}+-- > for ($i=0;$i<3;++$i) {getgrgid(0); print join(":",getgrent()),"\n"}+--+-- XXX: It has been suggested, not without some merit, that attempts to+-- enumerate /all/ users or /all/ groups are fundamentally flawed.  Modern+-- unix systems have a variety nsswitch backends, some of which instantiate+-- users on demand or may enumerate slowly or not at all.  We could shed a+-- lot of complexity by deprecating the "get all" functions and simply+-- always returning an empty list.+-- +#if defined(HAVE_GETPWENT)+pwlock :: MVar ()+pwlock = unsafePerformIO $ newMVar ()+{-# NOINLINE pwlock #-}++lockpw :: LKUPTYPE -> IO a -> IO a+#if defined(freebsd_HOST_OS)+lockpw GETONE+    | rtsSupportsBoundThreads = id+    | otherwise = withMVar pwlock . const+lockpw GETALL+    | rtsSupportsBoundThreads = runInBoundThread . withMVar pwlock . const+    | otherwise = withMVar pwlock . const+#else+lockpw GETONE = id+lockpw GETALL = withMVar pwlock . const+#endif+#else+lockpw _ = id+#endif++#if defined(HAVE_GETGRENT)+grlock :: MVar ()+grlock = unsafePerformIO $ newMVar ()+{-# NOINLINE grlock #-}++lockgr :: LKUPTYPE -> IO a -> IO a+#if defined(freebsd_HOST_OS)+lockgr GETONE+    | rtsSupportsBoundThreads = id+    | otherwise = withMVar grlock . const+lockgr GETALL+    | rtsSupportsBoundThreads = runInBoundThread . withMVar grlock . const+    | otherwise = withMVar grlock . const+#else+lockgr GETONE = id+lockgr GETALL = withMVar grlock . const+#endif+#else+lockgr _ = id+#endif++-- -----------------------------------------------------------------------------+-- user environment+ -- | @getRealUserID@ calls @getuid@ to obtain the real @UserID@ --   associated with the current process. getRealUserID :: IO UserID@@ -127,7 +319,6 @@   c_setgroups :: CInt -> Ptr CGid -> IO CInt  - -- | @getLoginName@ calls @getlogin@ to obtain the login name --   associated with the current process. getLoginName :: IO String@@ -186,32 +377,69 @@     pw <- getUserEntryForID euid     return (userName pw) +#endif // HAVE_PWD_H+ -- ----------------------------------------------------------------------------- -- The group database (grp.h) -data GroupEntry =- GroupEntry {-  groupName    :: String,       -- ^ The name of this group (gr_name)-  groupPassword :: String,      -- ^ The password for this group (gr_passwd)-  groupID      :: GroupID,      -- ^ The unique numeric ID for this group (gr_gid)-  groupMembers :: [String]      -- ^ A list of zero or more usernames that are members (gr_mem)- } deriving (Show, Read, Eq)+groupName :: GroupEntry -> String+groupName (GroupEntry gn _ _ _) = gn +groupPassword :: GroupEntry -> String+groupPassword (GroupEntry _ gp _ _) = gp++groupID :: GroupEntry -> GroupID+groupID (GroupEntry _ _ id' _) = id'++groupMembers :: GroupEntry -> [String]+groupMembers (GroupEntry _ _ _ gm) = gm++-- | Manually constructing 'GroupEntry' in String modules is discouraged. It will truncate+-- Chars to 8bit. Use 'System.Posix.User.ByteString' instead.+pattern GroupEntry :: String          -- ^ The name of this group (gr_name)+                   -> String          -- ^ The password for this group (gr_passwd)+                   -> GroupID         -- ^ The unique numeric ID for this group (gr_gid)+                   -> [String]        -- ^ A list of zero or more usernames that are members (gr_mem)+                   -> GroupEntry+pattern GroupEntry gn gp gi gm <- User.GroupEntry (C8.unpack -> gn) (C8.unpack -> gp) gi (fmap C8.unpack -> gm) where+  GroupEntry gn gp gi gm = User.GroupEntry (C8.pack gn) (C8.pack gp) gi (C8.pack <$> gm)+{-# COMPLETE GroupEntry #-}++#if !defined(HAVE_PWD_H)++getGroupEntryForID :: GroupID -> IO GroupEntry+{-# WARNING getGroupEntryForID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getGroupEntryForID _ = ioError (ioeSetLocation unsupportedOperation "getGroupEntryForID")++getGroupEntryForName :: String -> IO GroupEntry+{-# WARNING getGroupEntryForName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getGroupEntryForName _ = ioError (ioeSetLocation unsupportedOperation "getGroupEntryForName")++getAllGroupEntries :: IO [GroupEntry]+{-# WARNING getAllGroupEntries+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getAllGroupEntries = ioError (ioeSetLocation unsupportedOperation "getAllGroupEntries")++#else+ -- | @getGroupEntryForID gid@ calls @getgrgid_r@ to obtain --   the @GroupEntry@ information associated with @GroupID@ --   @gid@. This operation may fail with 'isDoesNotExistError' --   if no such group exists. getGroupEntryForID :: GroupID -> IO GroupEntry #ifdef HAVE_GETGRGID_R-getGroupEntryForID gid =-  allocaBytes (#const sizeof(struct group)) $ \pgr ->-   doubleAllocWhileERANGE "getGroupEntryForID" "group" grBufSize unpackGroupEntry $-     c_getgrgid_r gid pgr+getGroupEntryForID gid = lockgr GETONE $+    allocaBytes (#const sizeof(struct group)) $ \pgr ->+        doubleAllocWhileERANGE "getGroupEntryForID" "group"+            grBufSize unpackGroupEntry $ c_getgrgid_r gid pgr -foreign import capi unsafe "HsUnix.h getgrgid_r"+foreign import capi safe "HsUnix.h getgrgid_r"   c_getgrgid_r :: CGid -> Ptr CGroup -> CString                  -> CSize -> Ptr (Ptr CGroup) -> IO CInt #else+{-# WARNING getGroupEntryForID "System.Posix.User.getGroupEntryForID: not supported" #-} getGroupEntryForID = error "System.Posix.User.getGroupEntryForID: not supported" #endif @@ -221,16 +449,17 @@ --   if no such group exists. getGroupEntryForName :: String -> IO GroupEntry #ifdef HAVE_GETGRNAM_R-getGroupEntryForName name =-  allocaBytes (#const sizeof(struct group)) $ \pgr ->-    withCAString name $ \ pstr ->-      doubleAllocWhileERANGE "getGroupEntryForName" "group" grBufSize unpackGroupEntry $-        c_getgrnam_r pstr pgr+getGroupEntryForName name = lockgr GETONE $+    allocaBytes (#const sizeof(struct group)) $ \pgr ->+        withCAString name $ \ pstr ->+            doubleAllocWhileERANGE "getGroupEntryForName" "group"+                grBufSize unpackGroupEntry $ c_getgrnam_r pstr pgr -foreign import capi unsafe "HsUnix.h getgrnam_r"+foreign import capi safe "HsUnix.h getgrnam_r"   c_getgrnam_r :: CString -> Ptr CGroup -> CString                  -> CSize -> Ptr (Ptr CGroup) -> IO CInt #else+{-# WARNING getGroupEntryForName "System.Posix.User.getGroupEntryForName: not supported" #-} getGroupEntryForName = error "System.Posix.User.getGroupEntryForName: not supported" #endif @@ -244,24 +473,21 @@ -- getAllGroupEntries :: IO [GroupEntry] #ifdef HAVE_GETGRENT-getAllGroupEntries =-    withMVar lock $ \_ -> bracket_ c_setgrent c_endgrent $ worker []-    where worker accum =-              do resetErrno-                 ppw <- throwErrnoIfNullAndError "getAllGroupEntries" $-                        c_getgrent-                 if ppw == nullPtr-                     then return (reverse accum)-                     else do thisentry <- unpackGroupEntry ppw-                             worker (thisentry : accum)+getAllGroupEntries = lockgr GETALL $ bracket_ c_setgrent c_endgrent $ worker []+  where+    worker accum = do+        resetErrno+        ppw <- throwErrnoIfNullAndError "getAllGroupEntries" $ c_getgrent+        if ppw == nullPtr+            then return (reverse accum)+            else do thisentry <- unpackGroupEntry ppw+                    worker (thisentry : accum) -foreign import ccall unsafe "getgrent"-  c_getgrent :: IO (Ptr CGroup)-foreign import ccall unsafe "setgrent"-  c_setgrent :: IO ()-foreign import ccall unsafe "endgrent"-  c_endgrent :: IO ()+foreign import ccall safe "getgrent" c_getgrent :: IO (Ptr CGroup)+foreign import ccall safe "setgrent" c_setgrent :: IO ()+foreign import ccall safe "endgrent" c_endgrent :: IO () #else+{-# WARNING getAllGroupEntries "System.Posix.User.getAllGroupEntries: not supported" #-} getAllGroupEntries = error "System.Posix.User.getAllGroupEntries: not supported" #endif @@ -274,65 +500,74 @@ #endif #endif -unpackGroupEntry :: Ptr CGroup -> IO GroupEntry-unpackGroupEntry ptr = do-   name    <- (#peek struct group, gr_name) ptr >>= peekCAString-   passwd  <- (#peek struct group, gr_passwd) ptr >>= peekCAString-   gid     <- (#peek struct group, gr_gid) ptr-   mem     <- (#peek struct group, gr_mem) ptr-   members <- peekArray0 nullPtr mem >>= mapM peekCAString-   return (GroupEntry name passwd gid members)+#endif // HAVE_PWD_H  -- ----------------------------------------------------------------------------- -- The user database (pwd.h) -data UserEntry =- UserEntry {-   userName      :: String,     -- ^ Textual name of this user (pw_name)-   userPassword  :: String,     -- ^ Password -- may be empty or fake if shadow is in use (pw_passwd)-   userID        :: UserID,     -- ^ Numeric ID for this user (pw_uid)-   userGroupID   :: GroupID,    -- ^ Primary group ID (pw_gid)-   userGecos     :: String,     -- ^ Usually the real name for the user (pw_gecos)-   homeDirectory :: String,     -- ^ Home directory (pw_dir)-   userShell     :: String      -- ^ Default shell (pw_shell)- } deriving (Show, Read, Eq)+userName :: UserEntry -> String+userName (UserEntry n _ _ _ _ _ _) = n ------ getpwuid and getpwnam leave results in a static object. Subsequent--- calls modify the same object, which isn't threadsafe. We attempt to--- mitigate this issue, on platforms that don't provide the safe _r versions------ Also, getpwent/setpwent require a global lock since they maintain--- an internal file position pointer.-#if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R) || defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)-lock :: MVar ()-lock = unsafePerformIO $ newMVar ()-{-# NOINLINE lock #-}-#endif+userPassword :: UserEntry -> String+userPassword (UserEntry _ p _ _ _ _ _) = p --- | @getUserEntryForID gid@ calls @getpwuid_r@ to obtain+userID :: UserEntry -> UserID+userID (UserEntry _ _ id' _ _ _ _) = id'++userGroupID :: UserEntry -> GroupID+userGroupID (UserEntry _ _ _ gid _ _ _) = gid++userGecos :: UserEntry -> String+userGecos (UserEntry _ _ _ _ ge _ _) = ge++homeDirectory :: UserEntry -> String+homeDirectory (UserEntry _ _ _ _ _ hd _) = hd++userShell :: UserEntry -> String+userShell (UserEntry _ _ _ _ _ _ us) = us++-- | Manually constructing 'UserEntry' in String modules is discouraged. It will truncate+-- Chars to 8bit. Use 'System.Posix.User.ByteString' instead.+pattern UserEntry :: String         -- ^ Textual name of this user (pw_name)+                  -> String         -- ^ Password -- may be empty or fake if shadow is in use (pw_passwd)+                  -> UserID         -- ^ Numeric ID for this user (pw_uid)+                  -> GroupID        -- ^ Primary group ID (pw_gid)+                  -> String         -- ^ Usually the real name for the user (pw_gecos)+                  -> String         -- ^ Home directory (pw_dir)+                  -> String         -- ^ Default shell (pw_shell)+                  -> UserEntry+pattern UserEntry un up ui ugi ug hd us <- User.UserEntry (C8.unpack -> un)+                                                       (C8.unpack -> up)+                                                       ui+                                                       ugi+                                                       (C8.unpack -> ug)+                                                       (C8.unpack -> hd)+                                                       (C8.unpack -> us) where+  UserEntry un up ui ugi ug hd us = User.UserEntry (C8.pack un)+                                                (C8.pack up)+                                                ui+                                                ugi+                                                (C8.pack ug)+                                                (C8.pack hd)+                                                (C8.pack us)+{-# COMPLETE UserEntry #-}++-- | @getUserEntryForID uid@ calls @getpwuid_r@ to obtain --   the @UserEntry@ information associated with @UserID@ --   @uid@. This operation may fail with 'isDoesNotExistError' --   if no such user exists. getUserEntryForID :: UserID -> IO UserEntry #ifdef HAVE_GETPWUID_R-getUserEntryForID uid =-  allocaBytes (#const sizeof(struct passwd)) $ \ppw ->-    doubleAllocWhileERANGE "getUserEntryForID" "user" pwBufSize unpackUserEntry $-      c_getpwuid_r uid ppw+getUserEntryForID uid = lockpw GETONE $+    allocaBytes (#const sizeof(struct passwd)) $ \ppw ->+        doubleAllocWhileERANGE "getUserEntryForID" "user"+            pwBufSize unpackUserEntry $ c_getpwuid_r uid ppw -foreign import capi unsafe "HsUnix.h getpwuid_r"+foreign import capi safe "HsUnix.h getpwuid_r"   c_getpwuid_r :: CUid -> Ptr CPasswd ->                         CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt-#elif HAVE_GETPWUID-getUserEntryForID uid = do-  withMVar lock $ \_ -> do-    ppw <- throwErrnoIfNull "getUserEntryForID" $ c_getpwuid uid-    unpackUserEntry ppw--foreign import ccall unsafe "getpwuid"-  c_getpwuid :: CUid -> IO (Ptr CPasswd) #else+{-# WARNING getUserEntryForID "System.Posix.User.getUserEntryForID: not supported" #-} getUserEntryForID = error "System.Posix.User.getUserEntryForID: not supported" #endif @@ -342,25 +577,17 @@ --   if no such user exists. getUserEntryForName :: String -> IO UserEntry #if HAVE_GETPWNAM_R-getUserEntryForName name =-  allocaBytes (#const sizeof(struct passwd)) $ \ppw ->-    withCAString name $ \ pstr ->-      doubleAllocWhileERANGE "getUserEntryForName" "user" pwBufSize unpackUserEntry $-        c_getpwnam_r pstr ppw+getUserEntryForName name = lockpw GETONE $+    allocaBytes (#const sizeof(struct passwd)) $ \ppw ->+        withCAString name $ \ pstr ->+            doubleAllocWhileERANGE "getUserEntryForName" "user"+                pwBufSize unpackUserEntry $ c_getpwnam_r pstr ppw -foreign import capi unsafe "HsUnix.h getpwnam_r"+foreign import capi safe "HsUnix.h getpwnam_r"   c_getpwnam_r :: CString -> Ptr CPasswd                -> CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt-#elif HAVE_GETPWNAM-getUserEntryForName name = do-  withCAString name $ \ pstr -> do-    withMVar lock $ \_ -> do-      ppw <- throwErrnoIfNull "getUserEntryForName" $ c_getpwnam pstr-      unpackUserEntry ppw--foreign import ccall unsafe "getpwnam"-  c_getpwnam :: CString -> IO (Ptr CPasswd) #else+{-# WARNING getUserEntryForName "System.Posix.User.getUserEntryForName: not supported" #-} getUserEntryForName = error "System.Posix.User.getUserEntryForName: not supported" #endif @@ -368,24 +595,21 @@ --   repeatedly calling @getpwent@ getAllUserEntries :: IO [UserEntry] #ifdef HAVE_GETPWENT-getAllUserEntries =-    withMVar lock $ \_ -> bracket_ c_setpwent c_endpwent $ worker []-    where worker accum =-              do resetErrno-                 ppw <- throwErrnoIfNullAndError "getAllUserEntries" $-                        c_getpwent-                 if ppw == nullPtr-                     then return (reverse accum)-                     else do thisentry <- unpackUserEntry ppw-                             worker (thisentry : accum)+getAllUserEntries = lockpw GETALL $ bracket_ c_setpwent c_endpwent $ worker []+  where+    worker accum = do+        resetErrno+        ppw <- throwErrnoIfNullAndError "getAllUserEntries" $ c_getpwent+        if ppw == nullPtr+            then return (reverse accum)+            else do thisentry <- unpackUserEntry ppw+                    worker (thisentry : accum) -foreign import capi unsafe "HsUnix.h getpwent"-  c_getpwent :: IO (Ptr CPasswd)-foreign import capi unsafe "HsUnix.h setpwent"-  c_setpwent :: IO ()-foreign import capi unsafe "HsUnix.h endpwent"-  c_endpwent :: IO ()+foreign import ccall safe "getpwent" c_getpwent :: IO (Ptr CPasswd)+foreign import ccall safe "setpwent" c_setpwent :: IO ()+foreign import ccall safe "endpwent" c_endpwent :: IO () #else+{-# WARNING getAllUserEntries "System.Posix.User.getAllUserEntries: not supported" #-} getAllUserEntries = error "System.Posix.User.getAllUserEntries: not supported" #endif @@ -398,7 +622,7 @@ #endif #endif -#ifdef HAVE_SYSCONF+#if defined(HAVE_SYSCONF) && defined(HAVE_PWD_H) foreign import ccall unsafe "sysconf"   c_sysconf :: CInt -> IO CLong @@ -412,6 +636,8 @@                          return $ if v == (-1) then def else v #endif +#if defined(HAVE_PWD_H)+ -- The following function is used by the getgr*_r, c_getpw*_r -- families of functions. These functions return their result -- in a struct that contains strings and they need a buffer@@ -448,20 +674,6 @@     ioError $ flip ioeSetErrorString ("no such " ++ enttype)             $ mkIOError doesNotExistErrorType loc Nothing Nothing -unpackUserEntry :: Ptr CPasswd -> IO UserEntry-unpackUserEntry ptr = do-   name   <- (#peek struct passwd, pw_name)   ptr >>= peekCAString-   passwd <- (#peek struct passwd, pw_passwd) ptr >>= peekCAString-   uid    <- (#peek struct passwd, pw_uid)    ptr-   gid    <- (#peek struct passwd, pw_gid)    ptr-#ifdef HAVE_NO_PASSWD_PW_GECOS-   gecos  <- return ""  -- pw_gecos does not exist on android-#else-   gecos  <- (#peek struct passwd, pw_gecos)  ptr >>= peekCAString-#endif-   dir    <- (#peek struct passwd, pw_dir)    ptr >>= peekCAString-   shell  <- (#peek struct passwd, pw_shell)  ptr >>= peekCAString-   return (UserEntry name passwd uid gid gecos dir shell)  -- Used when a function returns NULL to indicate either an error or -- EOF, depending on whether the global errno is nonzero.@@ -472,3 +684,5 @@     if rc == nullPtr && errno /= eOK        then throwErrno loc        else return rc++#endif // HAVE_PWD_H
+ System/Posix/User/ByteString.hsc view
@@ -0,0 +1,604 @@+{-# LANGUAGE Trustworthy, CApiFFI, PatternSynonyms, ViewPatterns #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.User.ByteString+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX user\/group support+--+-----------------------------------------------------------------------------++module System.Posix.User.ByteString (+    -- * User environment+    -- ** Querying the user environment+    getRealUserID,+    getRealGroupID,+    getEffectiveUserID,+    getEffectiveGroupID,+    getGroups,+    getLoginName,+    getEffectiveUserName,++    -- *** The group database+    GroupEntry(..),++    getGroupEntryForID,+    getGroupEntryForName,+    getAllGroupEntries,++    -- *** The user database+    UserEntry(..),++    getUserEntryForID,+    getUserEntryForName,+    getAllUserEntries,++    -- ** Modifying the user environment+    setUserID,+    setGroupID,+    setEffectiveUserID,+    setEffectiveGroupID,+    setGroups++  ) where++#include "HsUnix.h"++import System.Posix.Types+import System.IO.Unsafe (unsafePerformIO)+import Foreign.C ( CSize(..), CInt(..), CString, CLong(..), getErrno, throwErrno, eOK, throwErrnoIfMinus1_, throwErrnoIfNull, resetErrno, Errno(..), eRANGE, errnoToIOError )+import Foreign.Ptr+import Foreign.Marshal+import Foreign.Storable++import System.Posix.User.Common+#if defined(HAVE_GETPWENT) || defined(HAVE_GETGRENT)+#if defined(freebsd_HOST_OS)+import Control.Concurrent (runInBoundThread, rtsSupportsBoundThreads)+#endif+import Control.Concurrent.MVar ( MVar, newMVar, withMVar )+import Control.Exception+#endif+import Control.Monad+import System.IO.Error+import Data.ByteString ( ByteString, packCString, useAsCString )++#if !defined(HAVE_PWD_H)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+++#if !defined(HAVE_PWD_H)++getRealUserID :: IO UserID+{-# WARNING getRealUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getRealUserID = ioError (ioeSetLocation unsupportedOperation "getRealUserID")++getRealGroupID :: IO GroupID+{-# WARNING getRealGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getRealGroupID = ioError (ioeSetLocation unsupportedOperation "getRealGroupID")++getEffectiveUserID :: IO UserID+{-# WARNING getEffectiveUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getEffectiveUserID = ioError (ioeSetLocation unsupportedOperation "getEffectiveUserID")++getEffectiveGroupID :: IO GroupID+{-# WARNING getEffectiveGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getEffectiveGroupID = ioError (ioeSetLocation unsupportedOperation "getEffectiveGroupID")++getGroups :: IO [GroupID]+{-# WARNING getGroups+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getGroups = ioError (ioeSetLocation unsupportedOperation "getGroups")++setGroups :: [GroupID] -> IO ()+{-# WARNING setGroups+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setGroups _ = ioError (ioeSetLocation unsupportedOperation "setGroups")++getLoginName :: IO ByteString+{-# WARNING getLoginName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getLoginName = ioError (ioeSetLocation unsupportedOperation "getLoginName")++setUserID :: UserID -> IO ()+{-# WARNING setUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setUserID _ = ioError (ioeSetLocation unsupportedOperation "setUserID")++setEffectiveUserID :: UserID -> IO ()+{-# WARNING setEffectiveUserID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setEffectiveUserID _ = ioError (ioeSetLocation unsupportedOperation "setEffectiveUserID")++setGroupID :: GroupID -> IO ()+{-# WARNING setGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setGroupID _ = ioError (ioeSetLocation unsupportedOperation "setGroupID")++setEffectiveGroupID :: GroupID -> IO ()+{-# WARNING setEffectiveGroupID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+setEffectiveGroupID _ = ioError (ioeSetLocation unsupportedOperation "setEffectiveGroupID")++getEffectiveUserName :: IO ByteString+{-# WARNING getEffectiveUserName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getEffectiveUserName = ioError (ioeSetLocation unsupportedOperation "getEffectiveUserName")++#else+-- -----------------------------------------------------------------------------+-- Thread safety of passwd/group database access APIs:+--+-- All supported unix platforms have @get(pw|gr)(nam|[ug]id)_r(3)@, which+-- store the result in a caller provided buffer, which solves the most+-- immediate thread-safety issues.+--+-- Things are more complicated for getpwent(3) and getgrent(3).+--+-- * On Linux systems, these read a global open file, opened via+--   setpwent(3) and closed via endpwent(3).  Only one thread at+--   a time can safely iterate through the file.+--+-- * On macOS (through Catalina 10.15), there is no getpwent_r(3) or+--   getgrent_r(3), so a lock is also required for safe buffer sharing.+--+-- * On FreeBSD, in the default configuration with passwd lookups configured+--   in nsswitch.conf to use "compat" rather than "files", the getpwnam_r(3)+--   and getpwuid_r(3) functions reset the iterator index used by getpwent(3).+--   A bug [report](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=252094)+--   has been filed to track this long-standing issue.  A similar issue affects+--   getgrent(3), this time regardless of the nsswitch.conf setting.  This too+--   should be fixed at some point in the future.  The state in question is+--   thread-specific, so both issues only affect overlapping use of the @*ent@+--   and @*(nam|[ug]id)_r(3)@ functions in the /same/ thread.+--+-- * Despite rather similar manpages for getpwent(3) and getpwnam(3), ... as+--   on FreeBSD, the above issue is not seen on NetBSD or macOS.+--+--   This is not an issue with 1-to-1 thread models, where the code executing+--   @get(pw|gr)ent@ has exclusive use of its thread, but it is a real issue+--   for Haskell with its many-to-1 green threads, because multiple `forkIO`+--   threads may take turns using the same underlying OS thread, breaking the+--   thread-safety of the @*_r@ functions, which mutate the file-offset of the+--   open file shared with any overlapping execution of @*ent(3)@ in the same+--   thread.+--+-- Consequently, correct portable support for @get(pw|gr)ent(3)@ is rather+-- non-trivial.  In the threaded runtime, we can run these functions in a+-- /bound thread/ (via 'forkOS'), thereby avoiding the FreeBSD issues.  We+-- still need a lock to serialise multiple threads calling these functions+-- on at least macOS for lack of @_r@ equivalents.  While on FreeBSD we could+-- use @getpwent_r(3)@ and @getgrent_r(3)@ in a bound thread without any+-- locks, implementing this special case is likely not worthwhile.+--+-- In the non-threaded runtime, `forkOS` is not available, and so on FreeBSD+-- systems we have to also lock the @*(nam|[ug]id)_r(3)@ functions to avoid+-- concurrent use with @*ent(3)@.+--+-- FWIW, the below Perl one-liners will quickly show whether interleaved calls+-- of getpwuid() or getgrgid() disturb iteration through all the entries. If+-- each line of output is distinct, there is likely no issue.  If the same+-- passwd or group entry repeats multiple times, the system is affected.+--+-- > for ($i=0;$i<3;++$i) {getpwuid(0); print join(":",getpwent()),"\n"}+-- > for ($i=0;$i<3;++$i) {getgrgid(0); print join(":",getgrent()),"\n"}+--+-- XXX: It has been suggested, not without some merit, that attempts to+-- enumerate /all/ users or /all/ groups are fundamentally flawed.  Modern+-- unix systems have a variety nsswitch backends, some of which instantiate+-- users on demand or may enumerate slowly or not at all.  We could shed a+-- lot of complexity by deprecating the "get all" functions and simply+-- always returning an empty list.+--++#if defined(HAVE_GETPWENT)+pwlock :: MVar ()+pwlock = unsafePerformIO $ newMVar ()+{-# NOINLINE pwlock #-}++lockpw :: LKUPTYPE -> IO a -> IO a+#if defined(freebsd_HOST_OS)+lockpw GETONE+    | rtsSupportsBoundThreads = id+    | otherwise = withMVar pwlock . const+lockpw GETALL+    | rtsSupportsBoundThreads = runInBoundThread . withMVar pwlock . const+    | otherwise = withMVar pwlock . const+#else+lockpw GETONE = id+lockpw GETALL = withMVar pwlock . const+#endif+#else+lockpw _ = id+#endif++#if defined(HAVE_GETGRENT)+grlock :: MVar ()+grlock = unsafePerformIO $ newMVar ()+{-# NOINLINE grlock #-}++lockgr :: LKUPTYPE -> IO a -> IO a+#if defined(freebsd_HOST_OS)+lockgr GETONE+    | rtsSupportsBoundThreads = id+    | otherwise = withMVar grlock . const+lockgr GETALL+    | rtsSupportsBoundThreads = runInBoundThread . withMVar grlock . const+    | otherwise = withMVar grlock . const+#else+lockgr GETONE = id+lockgr GETALL = withMVar grlock . const+#endif+#else+lockgr _ = id+#endif++-- -----------------------------------------------------------------------------+-- user environment++-- | @getRealUserID@ calls @getuid@ to obtain the real @UserID@+--   associated with the current process.+getRealUserID :: IO UserID+getRealUserID = c_getuid++foreign import ccall unsafe "getuid"+  c_getuid :: IO CUid++-- | @getRealGroupID@ calls @getgid@ to obtain the real @GroupID@+--   associated with the current process.+getRealGroupID :: IO GroupID+getRealGroupID = c_getgid++foreign import ccall unsafe "getgid"+  c_getgid :: IO CGid++-- | @getEffectiveUserID@ calls @geteuid@ to obtain the effective+--   @UserID@ associated with the current process.+getEffectiveUserID :: IO UserID+getEffectiveUserID = c_geteuid++foreign import ccall unsafe "geteuid"+  c_geteuid :: IO CUid++-- | @getEffectiveGroupID@ calls @getegid@ to obtain the effective+--   @GroupID@ associated with the current process.+getEffectiveGroupID :: IO GroupID+getEffectiveGroupID = c_getegid++foreign import ccall unsafe "getegid"+  c_getegid :: IO CGid++-- | @getGroups@ calls @getgroups@ to obtain the list of+--   supplementary @GroupID@s associated with the current process.+getGroups :: IO [GroupID]+getGroups = do+    ngroups <- c_getgroups 0 nullPtr+    allocaArray (fromIntegral ngroups) $ \arr -> do+       throwErrnoIfMinus1_ "getGroups" (c_getgroups ngroups arr)+       groups <- peekArray (fromIntegral ngroups) arr+       return groups++foreign import ccall unsafe "getgroups"+  c_getgroups :: CInt -> Ptr CGid -> IO CInt+++-- | @setGroups@ calls @setgroups@ to set the list of+--   supplementary @GroupID@s associated with the current process.+setGroups :: [GroupID] -> IO ()+setGroups groups = do+    withArrayLen groups $ \ ngroups arr ->+       throwErrnoIfMinus1_ "setGroups" (c_setgroups (fromIntegral ngroups) arr)++foreign import ccall unsafe "setgroups"+  c_setgroups :: CInt -> Ptr CGid -> IO CInt+++-- | @getLoginName@ calls @getlogin@ to obtain the login name+--   associated with the current process.+getLoginName :: IO ByteString+getLoginName =  do+    -- ToDo: use getlogin_r+    str <- throwErrnoIfNull "getLoginName" c_getlogin+    packCString str++foreign import ccall unsafe "getlogin"+  c_getlogin :: IO CString++-- | @setUserID uid@ calls @setuid@ to set the real, effective, and+--   saved set-user-id associated with the current process to @uid@.+setUserID :: UserID -> IO ()+setUserID uid = throwErrnoIfMinus1_ "setUserID" (c_setuid uid)++foreign import ccall unsafe "setuid"+  c_setuid :: CUid -> IO CInt++-- | @setEffectiveUserID uid@ calls @seteuid@ to set the effective+--   user-id associated with the current process to @uid@. This+--   does not update the real user-id or set-user-id.+setEffectiveUserID :: UserID -> IO ()+setEffectiveUserID uid = throwErrnoIfMinus1_ "setEffectiveUserID" (c_seteuid uid)++foreign import ccall unsafe "seteuid"+  c_seteuid :: CUid -> IO CInt++-- | @setGroupID gid@ calls @setgid@ to set the real, effective, and+--   saved set-group-id associated with the current process to @gid@.+setGroupID :: GroupID -> IO ()+setGroupID gid = throwErrnoIfMinus1_ "setGroupID" (c_setgid gid)++foreign import ccall unsafe "setgid"+  c_setgid :: CGid -> IO CInt++-- | @setEffectiveGroupID uid@ calls @setegid@ to set the effective+--   group-id associated with the current process to @gid@. This+--   does not update the real group-id or set-group-id.+setEffectiveGroupID :: GroupID -> IO ()+setEffectiveGroupID gid =+  throwErrnoIfMinus1_ "setEffectiveGroupID" (c_setegid gid)+++foreign import ccall unsafe "setegid"+  c_setegid :: CGid -> IO CInt++-- -----------------------------------------------------------------------------+-- User names++-- | @getEffectiveUserName@ gets the name+--   associated with the effective @UserID@ of the process.+getEffectiveUserName :: IO ByteString+getEffectiveUserName = do+    euid <- getEffectiveUserID+    pw <- getUserEntryForID euid+    return (userName pw)++#endif // HAVE_PWD_H++-- -----------------------------------------------------------------------------+-- The group database (grp.h)+++#if !defined(HAVE_PWD_H)++getGroupEntryForID :: GroupID -> IO GroupEntry+{-# WARNING getGroupEntryForID+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getGroupEntryForID _ = ioError (ioeSetLocation unsupportedOperation "getGroupEntryForID")++getGroupEntryForName :: ByteString -> IO GroupEntry+{-# WARNING getGroupEntryForName+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getGroupEntryForName _ = ioError (ioeSetLocation unsupportedOperation "getGroupEntryForName")++getAllGroupEntries :: IO [GroupEntry]+{-# WARNING getAllGroupEntries+    "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_PWD_H@)" #-}+getAllGroupEntries = ioError (ioeSetLocation unsupportedOperation "getAllGroupEntries")++#else++-- | @getGroupEntryForID gid@ calls @getgrgid_r@ to obtain+--   the @GroupEntry@ information associated with @GroupID@+--   @gid@. This operation may fail with 'isDoesNotExistError'+--   if no such group exists.+getGroupEntryForID :: GroupID -> IO GroupEntry+#ifdef HAVE_GETGRGID_R+getGroupEntryForID gid = lockgr GETONE $+    allocaBytes (#const sizeof(struct group)) $ \pgr ->+        doubleAllocWhileERANGE "getGroupEntryForID" "group"+            grBufSize unpackGroupEntry $ c_getgrgid_r gid pgr++foreign import capi safe "HsUnix.h getgrgid_r"+  c_getgrgid_r :: CGid -> Ptr CGroup -> CString+                 -> CSize -> Ptr (Ptr CGroup) -> IO CInt+#else+{-# WARNING getGroupEntryForID "System.Posix.User.getGroupEntryForID: not supported" #-}+getGroupEntryForID = error "System.Posix.User.getGroupEntryForID: not supported"+#endif++-- | @getGroupEntryForName name@ calls @getgrnam_r@ to obtain+--   the @GroupEntry@ information associated with the group called+--   @name@. This operation may fail with 'isDoesNotExistError'+--   if no such group exists.+getGroupEntryForName :: ByteString -> IO GroupEntry+#ifdef HAVE_GETGRNAM_R+getGroupEntryForName name = lockgr GETONE $+    allocaBytes (#const sizeof(struct group)) $ \pgr ->+        useAsCString name $ \ pstr ->+            doubleAllocWhileERANGE "getGroupEntryForName" "group"+                grBufSize unpackGroupEntry $ c_getgrnam_r pstr pgr++foreign import capi safe "HsUnix.h getgrnam_r"+  c_getgrnam_r :: CString -> Ptr CGroup -> CString+                 -> CSize -> Ptr (Ptr CGroup) -> IO CInt+#else+{-# WARNING getGroupEntryForName "System.Posix.User.getGroupEntryForName: not supported" #-}+getGroupEntryForName = error "System.Posix.User.getGroupEntryForName: not supported"+#endif++-- | @getAllGroupEntries@ returns all group entries on the system by+--   repeatedly calling @getgrent@++--+-- getAllGroupEntries may fail with isDoesNotExistError on Linux due to+-- this bug in glibc:+--   http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=466647+--+getAllGroupEntries :: IO [GroupEntry]+#ifdef HAVE_GETGRENT+getAllGroupEntries = lockgr GETALL $ bracket_ c_setgrent c_endgrent $ worker []+  where+    worker accum = do+        resetErrno+        ppw <- throwErrnoIfNullAndError "getAllGroupEntries" $ c_getgrent+        if ppw == nullPtr+            then return (reverse accum)+            else do thisentry <- unpackGroupEntry ppw+                    worker (thisentry : accum)++foreign import ccall safe "getgrent" c_getgrent :: IO (Ptr CGroup)+foreign import ccall safe "setgrent" c_setgrent :: IO ()+foreign import ccall safe "endgrent" c_endgrent :: IO ()+#else+{-# WARNING getAllGroupEntries "System.Posix.User.getAllGroupEntries: not supported" #-}+getAllGroupEntries = error "System.Posix.User.getAllGroupEntries: not supported"+#endif++#if defined(HAVE_GETGRGID_R) || defined(HAVE_GETGRNAM_R)+grBufSize :: Int+#if defined(HAVE_SYSCONF) && defined(HAVE_SC_GETGR_R_SIZE_MAX)+grBufSize = sysconfWithDefault 1024 (#const _SC_GETGR_R_SIZE_MAX)+#else+grBufSize = 1024+#endif+#endif++#endif // HAVE_PWD_H++-- -----------------------------------------------------------------------------+-- The user database (pwd.h)+++-- | @getUserEntryForID uid@ calls @getpwuid_r@ to obtain+--   the @UserEntry@ information associated with @UserID@+--   @uid@. This operation may fail with 'isDoesNotExistError'+--   if no such user exists.+getUserEntryForID :: UserID -> IO UserEntry+#ifdef HAVE_GETPWUID_R+getUserEntryForID uid = lockpw GETONE $+    allocaBytes (#const sizeof(struct passwd)) $ \ppw ->+        doubleAllocWhileERANGE "getUserEntryForID" "user"+            pwBufSize unpackUserEntry $ c_getpwuid_r uid ppw++foreign import capi safe "HsUnix.h getpwuid_r"+  c_getpwuid_r :: CUid -> Ptr CPasswd ->+                        CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt+#else+{-# WARNING getUserEntryForID "System.Posix.User.getUserEntryForID: not supported" #-}+getUserEntryForID = error "System.Posix.User.getUserEntryForID: not supported"+#endif++-- | @getUserEntryForName name@ calls @getpwnam_r@ to obtain+--   the @UserEntry@ information associated with the user login+--   @name@. This operation may fail with 'isDoesNotExistError'+--   if no such user exists.+getUserEntryForName :: ByteString -> IO UserEntry+#if HAVE_GETPWNAM_R+getUserEntryForName name = lockpw GETONE $+    allocaBytes (#const sizeof(struct passwd)) $ \ppw ->+        useAsCString name $ \ pstr ->+            doubleAllocWhileERANGE "getUserEntryForName" "user"+                pwBufSize unpackUserEntry $ c_getpwnam_r pstr ppw++foreign import capi safe "HsUnix.h getpwnam_r"+  c_getpwnam_r :: CString -> Ptr CPasswd+               -> CString -> CSize -> Ptr (Ptr CPasswd) -> IO CInt+#else+{-# WARNING getUserEntryForName "System.Posix.User.getUserEntryForName: not supported" #-}+getUserEntryForName = error "System.Posix.User.getUserEntryForName: not supported"+#endif++-- | @getAllUserEntries@ returns all user entries on the system by+--   repeatedly calling @getpwent@+getAllUserEntries :: IO [UserEntry]+#ifdef HAVE_GETPWENT+getAllUserEntries = lockpw GETALL $ bracket_ c_setpwent c_endpwent $ worker []+  where+    worker accum = do+        resetErrno+        ppw <- throwErrnoIfNullAndError "getAllUserEntries" $ c_getpwent+        if ppw == nullPtr+            then return (reverse accum)+            else do thisentry <- unpackUserEntry ppw+                    worker (thisentry : accum)++foreign import ccall safe "getpwent" c_getpwent :: IO (Ptr CPasswd)+foreign import ccall safe "setpwent" c_setpwent :: IO ()+foreign import ccall safe "endpwent" c_endpwent :: IO ()+#else+{-# WARNING getAllUserEntries "System.Posix.User.getAllUserEntries: not supported" #-}+getAllUserEntries = error "System.Posix.User.getAllUserEntries: not supported"+#endif++#if defined(HAVE_GETPWUID_R) || defined(HAVE_GETPWNAM_R)+pwBufSize :: Int+#if  defined(HAVE_SYSCONF) && defined(HAVE_SC_GETPW_R_SIZE_MAX)+pwBufSize = sysconfWithDefault 1024 (#const _SC_GETPW_R_SIZE_MAX)+#else+pwBufSize = 1024+#endif+#endif++#if defined(HAVE_SYSCONF) && defined(HAVE_PWD_H)+foreign import ccall unsafe "sysconf"+  c_sysconf :: CInt -> IO CLong++-- We need a default value since sysconf can fail and return -1+-- even when the parameter name is defined in unistd.h.+-- One example of this is _SC_GETPW_R_SIZE_MAX under+-- Mac OS X 10.4.9 on i386.+sysconfWithDefault :: Int -> CInt -> Int+sysconfWithDefault def sc =+    unsafePerformIO $ do v <- fmap fromIntegral $ c_sysconf sc+                         return $ if v == (-1) then def else v+#endif++#if defined(HAVE_PWD_H)++-- The following function is used by the getgr*_r, c_getpw*_r+-- families of functions. These functions return their result+-- in a struct that contains strings and they need a buffer+-- that they can use to store those strings. We have to be+-- careful to unpack the struct containing the result before+-- the buffer is deallocated.+doubleAllocWhileERANGE+  :: String+  -> String -- entry type: "user" or "group"+  -> Int+  -> (Ptr r -> IO a)+  -> (Ptr b -> CSize -> Ptr (Ptr r) -> IO CInt)+  -> IO a+doubleAllocWhileERANGE loc enttype initlen unpack action =+  alloca $ go initlen+ where+  go len res = do+    r <- allocaBytes len $ \buf -> do+           rc <- action buf (fromIntegral len) res+           if rc /= 0+             then return (Left rc)+             else do p <- peek res+                     when (p == nullPtr) $ notFoundErr+                     fmap Right (unpack p)+    case r of+      Right x -> return x+      Left rc | Errno rc == eRANGE ->+        -- ERANGE means this is not an error+        -- we just have to try again with a larger buffer+        go (2 * len) res+      Left rc ->+        ioError (errnoToIOError loc (Errno rc) Nothing Nothing)+  notFoundErr =+    ioError $ flip ioeSetErrorString ("no such " ++ enttype)+            $ mkIOError doesNotExistErrorType loc Nothing Nothing++-- Used when a function returns NULL to indicate either an error or+-- EOF, depending on whether the global errno is nonzero.+throwErrnoIfNullAndError :: String -> IO (Ptr a) -> IO (Ptr a)+throwErrnoIfNullAndError loc act = do+    rc <- act+    errno <- getErrno+    if rc == nullPtr && errno /= eOK+       then throwErrno loc+       else return rc++#endif // HAVE_PWD_H
+ System/Posix/User/Common.hsc view
@@ -0,0 +1,79 @@+{-# LANGUAGE Safe #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  System.Posix.User.Common+-- Copyright   :  (c) The University of Glasgow 2002+-- License     :  BSD-style (see the file libraries/base/LICENSE)+--+-- Maintainer  :  libraries@haskell.org+-- Stability   :  provisional+-- Portability :  non-portable (requires POSIX)+--+-- POSIX user\/group support+--+-----------------------------------------------------------------------------++module System.Posix.User.Common where++import Data.ByteString ( ByteString )+import System.Posix.Types++#include "HsUnix.h"+++#if defined(HAVE_PWD_H)+import Foreign.Ptr+import Foreign.Marshal+import Foreign.Storable+import Data.ByteString ( packCString )++-- internal types+data {-# CTYPE "struct passwd" #-} CPasswd+data {-# CTYPE "struct group"  #-} CGroup++data LKUPTYPE = GETONE | GETALL++unpackGroupEntry :: Ptr CGroup -> IO GroupEntry+unpackGroupEntry ptr = do+   name    <- (#peek struct group, gr_name) ptr >>= packCString+   passwd  <- (#peek struct group, gr_passwd) ptr >>= packCString+   gid     <- (#peek struct group, gr_gid) ptr+   mem     <- (#peek struct group, gr_mem) ptr+   members <- peekArray0 nullPtr mem >>= mapM packCString+   return (GroupEntry name passwd gid members)++unpackUserEntry :: Ptr CPasswd -> IO UserEntry+unpackUserEntry ptr = do+   name   <- (#peek struct passwd, pw_name)   ptr >>= packCString+   passwd <- (#peek struct passwd, pw_passwd) ptr >>= packCString+   uid    <- (#peek struct passwd, pw_uid)    ptr+   gid    <- (#peek struct passwd, pw_gid)    ptr+#ifdef HAVE_NO_PASSWD_PW_GECOS+   gecos  <- return ""  -- pw_gecos does not exist on android+#else+   gecos  <- (#peek struct passwd, pw_gecos)  ptr >>= packCString+#endif+   dir    <- (#peek struct passwd, pw_dir)    ptr >>= packCString+   shell  <- (#peek struct passwd, pw_shell)  ptr >>= packCString+   return (UserEntry name passwd uid gid gecos dir shell)++#endif // HAVE_PWD_H++data UserEntry =+ UserEntry {+   userName      :: ByteString,     -- ^ Textual name of this user (pw_name)+   userPassword  :: ByteString,     -- ^ Password -- may be empty or fake if shadow is in use (pw_passwd)+   userID        :: UserID,         -- ^ Numeric ID for this user (pw_uid)+   userGroupID   :: GroupID,        -- ^ Primary group ID (pw_gid)+   userGecos     :: ByteString,     -- ^ Usually the real name for the user (pw_gecos)+   homeDirectory :: ByteString,     -- ^ Home directory (pw_dir)+   userShell     :: ByteString      -- ^ Default shell (pw_shell)+ } deriving (Show, Read, Eq)++data GroupEntry =+ GroupEntry {+  groupName     :: ByteString,   -- ^ The name of this group (gr_name)+  groupPassword :: ByteString,   -- ^ The password for this group (gr_passwd)+  groupID       :: GroupID,      -- ^ The unique numeric ID for this group (gr_gid)+  groupMembers  :: [ByteString]  -- ^ A list of zero or more usernames that are members (gr_mem)+ } deriving (Show, Read, Eq)
cbits/HsUnix.c view
@@ -16,16 +16,6 @@ void *__hsunix_rtldDefault (void) {return RTLD_DEFAULT;} #endif -#if HAVE_PTSNAME && (__GLASGOW_HASKELL__ < 800)-// On Linux (and others), <stdlib.h> needs to be included while-// `_XOPEN_SOURCE` is already defined. However, GHCs before GHC 8.0-// didn't do that yet for CApiFFI, so we need this workaround here.--char *__hsunix_ptsname(int fd)   { return ptsname(fd);  }-int   __hsunix_grantpt(int fd)   { return grantpt(fd);  }-int   __hsunix_unlockpt(int fd)  { return unlockpt(fd); }-#endif- // push a SVR4 STREAMS module; do nothing if STREAMS not available int __hsunix_push_module(int fd, const char *module) {@@ -36,6 +26,10 @@ #endif } +#ifdef HAVE_CLOCKS_PER_SEC+clock_t __hsunix_clocks_per_second (void) {return CLOCKS_PER_SEC;}+#endif+ /*  * GNU glibc 2.23 and later deprecate `readdir_r` in favour of plain old  * `readdir` which in some upcoming POSIX standard is going to required to be@@ -43,7 +37,7 @@  * Eventually we want to drop `readder_r` all together, but want to be  * compatible with older unixen which may not have a re-entrant `readdir`.  * Solution is to make systems with *known* re-entrant `readir` use that and use- * `readdir_r` whereever we have it and don't *know* that `readdir` is+ * `readdir_r` wherever we have it and don't *know* that `readdir` is  * re-entrant.  */ 
cbits/execvpe.c view
@@ -3,7 +3,7 @@     Our low-level exec() variant. -   Note: __hsunix_execvpe() is very similiar to the function+   Note: __hsunix_execvpe() is very similar to the function          execvpe(3) as provided by glibc 2.11 and later. However, if          execvpe(3) is available, we use that instead. @@ -22,7 +22,6 @@ #include <string.h> #include <errno.h> -#define HSUNIX_EXECVPE_H_NO_COMPAT #include "execvpe.h"  #if !defined(execvpe) && !HAVE_DECL_EXECVPE@@ -72,6 +71,9 @@ { #if HAVE_EXECVPE     return execvpe(name, argv, envp);+#elif !defined(HAVE_EXECV)+    errno = ENOSYS;+    return (-1); #else     register int lp, ln;     register char *p;
changelog.md view
@@ -1,22 +1,71 @@ # Changelog for [`unix` package](http://hackage.haskell.org/package/unix) -## 2.7.2.3  *Unreleased*+## 2.8.0.0 *August 2022*+  * Use ByteString for GroupEntry/UserEntry -  * Resource: Fix warning in case of no RLIM_SAVED_{CUR,MAX}+  * Fix `semTrywait` on darwin -  * Future-proof glibc version check+  * Fix vanishing environment variables in `System.Posix.Env.ByteString.putEnv`/`System.Posix.Env.ByteString.getEnv` -  * Fix the error handling of posix_fallocate in non-FreeBSD+  * Add missing `setEnvironment` and `clearEnv` to `System.Posix.Env.ByteString` -  * Synchronize ByteString and String modules and fix grave bug in 'putEnv'+  * Add support for filepath-1.4.100.0 with `PosixString` variants -  * Fix 'semTrywait: invalid argument (Bad file descriptor)' wrt #218+  * Expose `DirStream`, `CDir`, `CDirent` and `DirStreamOffset` (internal API) -  * Improve error messages+  * Add `fdRead`/`fdWrite` with ByteString payload and deprecate String based `fdRead` -  * Improve tests+  * Add `clocksPerSec` -  * Don't show repo as modified after configure+  * Support wasm32-wasi++  * Implement BaudRate as an `Int` newtype and allow matching via extensible PatternSynonyms++  * Added `readDirStreamMaybe`++  * Warn when functions are used on unsupported platforms++  * Fix the error handling of `posix_fallocate`++  * Export `FileStatus` constructor++  * Various documentation and error message improvements++  * Add openDirStreamFd, openFileAt and createFileAt++  * Add accessors for st_blocks and st_blksize++  * Deal with FreeBSD getpwnam_r(3), ... thread safety.  On FreeBSD these+    are not in fact safe for overlapped execution with a sequence of+    getpwent(3) or getgrent(3) calls when multiple "green" threads share+    the same underlying OS thread.  The *ent(3) calls now run in bound+    threads or else locks are used to avoid overlapped execution.++  * Make passwd/group FFI functions "safe", these are not low-latency APIs.++  * Drop support for non-thread-safe getpwnam(3) and getpwuid(3).  All+    supported platforms have getpwnam_r(3) and getpwuid_r(3).  This was+    already the case for the getgr(nam|gid) calls.++  * Added terminal output flags to `System.Posix.Terminal.Common.TerminalMode`++        IXANY, ONLCR, OCRNL, ONOCR, ONLRET, OFDEL, OFILL, NLDLY(NL0,NL1),+        CRDLY(CR0,CR1,CR2,CR2), TABDLY(TAB0,TAB1,TAB2,TAB3) BSDLY(BS0,BS1),+        VTDLY(VT0,VT1), FFDLY(FF0,FF1)++  * Add support for `O_NOFOLLOW`, `O_CLOEXEC`, `O_DIRECTORY` and `O_SYNC`+    (#6, #57)++  * Refactor API of `openFd` removing `Maybe FileMode` argument,+    which now must be passed as part of `OpenFileFlags`+    (e.g. `defaultFileFlags { creat = Just mode }`)  (#58)++  * Remove deprecated `execvpe(3)` legacy-emulation CPP macro++  * Generalise return type of `exitImmediately` from `ExitCode -> IO ()` to+    `∀a. ExitCode -> IO a` (#130)++  * Add `Read`, `Show`, `Eq`, and `Ord` typeclass instances to `OpenFileFlags` and `OpenMode`. (#75, #141)  ## 2.7.2.2  *May 2017* 
config.guess view
@@ -1,1699 +1,1465 @@ #! /bin/sh # Attempt to guess a canonical system name.-#   Copyright 1992-2021 Free Software Foundation, Inc.--timestamp='2021-01-25'--# This file is free software; you can redistribute it and/or modify it-# under the terms of the GNU General Public License as published by-# the Free Software Foundation; either version 3 of the License, or-# (at your option) any later version.-#-# This program is distributed in the hope that it will be useful, but-# WITHOUT ANY WARRANTY; without even the implied warranty of-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU-# General Public License for more details.-#-# You should have received a copy of the GNU General Public License-# along with this program; if not, see <https://www.gnu.org/licenses/>.-#-# As a special exception to the GNU General Public License, if you-# distribute this file as part of a program that contains a-# configuration script generated by Autoconf, you may include it under-# the same distribution terms that you use for the rest of that-# program.  This Exception is an additional permission under section 7-# of the GNU General Public License, version 3 ("GPLv3").-#-# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.-#-# You can get the latest version of this script from:-# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess-#-# Please send patches to <config-patches@gnu.org>.---me=$(echo "$0" | sed -e 's,.*/,,')--usage="\-Usage: $0 [OPTION]--Output the configuration name of the system \`$me' is run on.--Options:-  -h, --help         print this help, then exit-  -t, --time-stamp   print date of last modification, then exit-  -v, --version      print version number, then exit--Report bugs and patches to <config-patches@gnu.org>."--version="\-GNU config.guess ($timestamp)--Originally written by Per Bothner.-Copyright 1992-2021 Free Software Foundation, Inc.--This is free software; see the source for copying conditions.  There is NO-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."--help="-Try \`$me --help' for more information."--# Parse command line-while test $# -gt 0 ; do-  case $1 in-    --time-stamp | --time* | -t )-       echo "$timestamp" ; exit ;;-    --version | -v )-       echo "$version" ; exit ;;-    --help | --h* | -h )-       echo "$usage"; exit ;;-    -- )     # Stop option processing-       shift; break ;;-    - )	# Use stdin as input.-       break ;;-    -* )-       echo "$me: invalid option $1$help" >&2-       exit 1 ;;-    * )-       break ;;-  esac-done--if test $# != 0; then-  echo "$me: too many arguments$help" >&2-  exit 1-fi--# CC_FOR_BUILD -- compiler used by this script. Note that the use of a-# compiler to aid in system detection is discouraged as it requires-# temporary files to be created and, as you can see below, it is a-# headache to deal with in a portable fashion.--# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still-# use `HOST_CC' if defined, but it is deprecated.--# Portable tmp directory creation inspired by the Autoconf team.--tmp=-# shellcheck disable=SC2172-trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15--set_cc_for_build() {-    # prevent multiple calls if $tmp is already set-    test "$tmp" && return 0-    : "${TMPDIR=/tmp}"-    # shellcheck disable=SC2039-    { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||-	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||-	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||-	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }-    dummy=$tmp/dummy-    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in-	,,)    echo "int x;" > "$dummy.c"-	       for driver in cc gcc c89 c99 ; do-		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then-		       CC_FOR_BUILD="$driver"-		       break-		   fi-	       done-	       if test x"$CC_FOR_BUILD" = x ; then-		   CC_FOR_BUILD=no_compiler_found-	       fi-	       ;;-	,,*)   CC_FOR_BUILD=$CC ;;-	,*,*)  CC_FOR_BUILD=$HOST_CC ;;-    esac-}--# This is needed to find uname on a Pyramid OSx when run in the BSD universe.-# (ghazi@noc.rutgers.edu 1994-08-24)-if test -f /.attbin/uname ; then-	PATH=$PATH:/.attbin ; export PATH-fi--UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown-UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown-UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown-UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown--case "$UNAME_SYSTEM" in-Linux|GNU|GNU/*)-	LIBC=unknown--	set_cc_for_build-	cat <<-EOF > "$dummy.c"-	#include <features.h>-	#if defined(__UCLIBC__)-	LIBC=uclibc-	#elif defined(__dietlibc__)-	LIBC=dietlibc-	#elif defined(__GLIBC__)-	LIBC=gnu-	#else-	#include <stdarg.h>-	/* First heuristic to detect musl libc.  */-	#ifdef __DEFINED_va_list-	LIBC=musl-	#endif-	#endif-	EOF-	eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"--	# Second heuristic to detect musl libc.-	if [ "$LIBC" = unknown ] &&-	   command -v ldd >/dev/null &&-	   ldd --version 2>&1 | grep -q ^musl; then-		LIBC=musl-	fi--	# If the system lacks a compiler, then just pick glibc.-	# We could probably try harder.-	if [ "$LIBC" = unknown ]; then-		LIBC=gnu-	fi-	;;-esac--# Note: order is significant - the case branches are not exclusive.--case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in-    *:NetBSD:*:*)-	# NetBSD (nbsd) targets should (where applicable) match one or-	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,-	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently-	# switched to ELF, *-*-netbsd* would select the old-	# object file format.  This provides both forward-	# compatibility and a consistent mechanism for selecting the-	# object file format.-	#-	# Note: NetBSD doesn't particularly care about the vendor-	# portion of the name.  We always set it to "unknown".-	UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \-	    /sbin/sysctl -n hw.machine_arch 2>/dev/null || \-	    /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \-	    echo unknown))-	case "$UNAME_MACHINE_ARCH" in-	    aarch64eb) machine=aarch64_be-unknown ;;-	    armeb) machine=armeb-unknown ;;-	    arm*) machine=arm-unknown ;;-	    sh3el) machine=shl-unknown ;;-	    sh3eb) machine=sh-unknown ;;-	    sh5el) machine=sh5le-unknown ;;-	    earmv*)-		arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')-		endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')-		machine="${arch}${endian}"-unknown-		;;-	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;-	esac-	# The Operating System including object format, if it has switched-	# to ELF recently (or will in the future) and ABI.-	case "$UNAME_MACHINE_ARCH" in-	    earm*)-		os=netbsdelf-		;;-	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)-		set_cc_for_build-		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \-			| grep -q __ELF__-		then-		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).-		    # Return netbsd for either.  FIX?-		    os=netbsd-		else-		    os=netbsdelf-		fi-		;;-	    *)-		os=netbsd-		;;-	esac-	# Determine ABI tags.-	case "$UNAME_MACHINE_ARCH" in-	    earm*)-		expr='s/^earmv[0-9]/-eabi/;s/eb$//'-		abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")-		;;-	esac-	# The OS release-	# Debian GNU/NetBSD machines have a different userland, and-	# thus, need a distinct triplet. However, they do not need-	# kernel version information, so it can be replaced with a-	# suitable tag, in the style of linux-gnu.-	case "$UNAME_VERSION" in-	    Debian*)-		release='-gnu'-		;;-	    *)-		release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)-		;;-	esac-	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:-	# contains redundant information, the shorter form:-	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.-	echo "$machine-${os}${release}${abi-}"-	exit ;;-    *:Bitrig:*:*)-	UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')-	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"-	exit ;;-    *:OpenBSD:*:*)-	UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')-	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"-	exit ;;-    *:LibertyBSD:*:*)-	UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')-	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"-	exit ;;-    *:MidnightBSD:*:*)-	echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"-	exit ;;-    *:ekkoBSD:*:*)-	echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"-	exit ;;-    *:SolidBSD:*:*)-	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"-	exit ;;-    *:OS108:*:*)-	echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE"-	exit ;;-    macppc:MirBSD:*:*)-	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"-	exit ;;-    *:MirBSD:*:*)-	echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"-	exit ;;-    *:Sortix:*:*)-	echo "$UNAME_MACHINE"-unknown-sortix-	exit ;;-    *:Twizzler:*:*)-	echo "$UNAME_MACHINE"-unknown-twizzler-	exit ;;-    *:Redox:*:*)-	echo "$UNAME_MACHINE"-unknown-redox-	exit ;;-    mips:OSF1:*.*)-	echo mips-dec-osf1-	exit ;;-    alpha:OSF1:*:*)-	case $UNAME_RELEASE in-	*4.0)-		UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')-		;;-	*5.*)-		UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')-		;;-	esac-	# According to Compaq, /usr/sbin/psrinfo has been available on-	# OSF/1 and Tru64 systems produced since 1995.  I hope that-	# covers most systems running today.  This code pipes the CPU-	# types through head -n 1, so we only detect the type of CPU 0.-	ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1)-	case "$ALPHA_CPU_TYPE" in-	    "EV4 (21064)")-		UNAME_MACHINE=alpha ;;-	    "EV4.5 (21064)")-		UNAME_MACHINE=alpha ;;-	    "LCA4 (21066/21068)")-		UNAME_MACHINE=alpha ;;-	    "EV5 (21164)")-		UNAME_MACHINE=alphaev5 ;;-	    "EV5.6 (21164A)")-		UNAME_MACHINE=alphaev56 ;;-	    "EV5.6 (21164PC)")-		UNAME_MACHINE=alphapca56 ;;-	    "EV5.7 (21164PC)")-		UNAME_MACHINE=alphapca57 ;;-	    "EV6 (21264)")-		UNAME_MACHINE=alphaev6 ;;-	    "EV6.7 (21264A)")-		UNAME_MACHINE=alphaev67 ;;-	    "EV6.8CB (21264C)")-		UNAME_MACHINE=alphaev68 ;;-	    "EV6.8AL (21264B)")-		UNAME_MACHINE=alphaev68 ;;-	    "EV6.8CX (21264D)")-		UNAME_MACHINE=alphaev68 ;;-	    "EV6.9A (21264/EV69A)")-		UNAME_MACHINE=alphaev69 ;;-	    "EV7 (21364)")-		UNAME_MACHINE=alphaev7 ;;-	    "EV7.9 (21364A)")-		UNAME_MACHINE=alphaev79 ;;-	esac-	# A Pn.n version is a patched version.-	# A Vn.n version is a released version.-	# A Tn.n version is a released field test version.-	# A Xn.n version is an unreleased experimental baselevel.-	# 1.2 uses "1.2" for uname -r.-	echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)"-	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.-	exitcode=$?-	trap '' 0-	exit $exitcode ;;-    Amiga*:UNIX_System_V:4.0:*)-	echo m68k-unknown-sysv4-	exit ;;-    *:[Aa]miga[Oo][Ss]:*:*)-	echo "$UNAME_MACHINE"-unknown-amigaos-	exit ;;-    *:[Mm]orph[Oo][Ss]:*:*)-	echo "$UNAME_MACHINE"-unknown-morphos-	exit ;;-    *:OS/390:*:*)-	echo i370-ibm-openedition-	exit ;;-    *:z/VM:*:*)-	echo s390-ibm-zvmoe-	exit ;;-    *:OS400:*:*)-	echo powerpc-ibm-os400-	exit ;;-    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)-	echo arm-acorn-riscix"$UNAME_RELEASE"-	exit ;;-    arm*:riscos:*:*|arm*:RISCOS:*:*)-	echo arm-unknown-riscos-	exit ;;-    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)-	echo hppa1.1-hitachi-hiuxmpp-	exit ;;-    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)-	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.-	if test "$( (/bin/universe) 2>/dev/null)" = att ; then-		echo pyramid-pyramid-sysv3-	else-		echo pyramid-pyramid-bsd-	fi-	exit ;;-    NILE*:*:*:dcosx)-	echo pyramid-pyramid-svr4-	exit ;;-    DRS?6000:unix:4.0:6*)-	echo sparc-icl-nx6-	exit ;;-    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)-	case $(/usr/bin/uname -p) in-	    sparc) echo sparc-icl-nx7; exit ;;-	esac ;;-    s390x:SunOS:*:*)-	echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"-	exit ;;-    sun4H:SunOS:5.*:*)-	echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"-	exit ;;-    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)-	echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"-	exit ;;-    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)-	echo i386-pc-auroraux"$UNAME_RELEASE"-	exit ;;-    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)-	set_cc_for_build-	SUN_ARCH=i386-	# If there is a compiler, see if it is configured for 64-bit objects.-	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.-	# This test works for both compilers.-	if test "$CC_FOR_BUILD" != no_compiler_found; then-	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \-		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \-		grep IS_64BIT_ARCH >/dev/null-	    then-		SUN_ARCH=x86_64-	    fi-	fi-	echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"-	exit ;;-    sun4*:SunOS:6*:*)-	# According to config.sub, this is the proper way to canonicalize-	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but-	# it's likely to be more like Solaris than SunOS4.-	echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"-	exit ;;-    sun4*:SunOS:*:*)-	case "$(/usr/bin/arch -k)" in-	    Series*|S4*)-		UNAME_RELEASE=$(uname -v)-		;;-	esac-	# Japanese Language versions have a version number like `4.1.3-JL'.-	echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"-	exit ;;-    sun3*:SunOS:*:*)-	echo m68k-sun-sunos"$UNAME_RELEASE"-	exit ;;-    sun*:*:4.2BSD:*)-	UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)-	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3-	case "$(/bin/arch)" in-	    sun3)-		echo m68k-sun-sunos"$UNAME_RELEASE"-		;;-	    sun4)-		echo sparc-sun-sunos"$UNAME_RELEASE"-		;;-	esac-	exit ;;-    aushp:SunOS:*:*)-	echo sparc-auspex-sunos"$UNAME_RELEASE"-	exit ;;-    # The situation for MiNT is a little confusing.  The machine name-    # can be virtually everything (everything which is not-    # "atarist" or "atariste" at least should have a processor-    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"-    # to the lowercase version "mint" (or "freemint").  Finally-    # the system name "TOS" denotes a system which is actually not-    # MiNT.  But MiNT is downward compatible to TOS, so this should-    # be no problem.-    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)-	echo m68k-atari-mint"$UNAME_RELEASE"-	exit ;;-    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)-	echo m68k-atari-mint"$UNAME_RELEASE"-	exit ;;-    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)-	echo m68k-atari-mint"$UNAME_RELEASE"-	exit ;;-    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)-	echo m68k-milan-mint"$UNAME_RELEASE"-	exit ;;-    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)-	echo m68k-hades-mint"$UNAME_RELEASE"-	exit ;;-    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)-	echo m68k-unknown-mint"$UNAME_RELEASE"-	exit ;;-    m68k:machten:*:*)-	echo m68k-apple-machten"$UNAME_RELEASE"-	exit ;;-    powerpc:machten:*:*)-	echo powerpc-apple-machten"$UNAME_RELEASE"-	exit ;;-    RISC*:Mach:*:*)-	echo mips-dec-mach_bsd4.3-	exit ;;-    RISC*:ULTRIX:*:*)-	echo mips-dec-ultrix"$UNAME_RELEASE"-	exit ;;-    VAX*:ULTRIX*:*:*)-	echo vax-dec-ultrix"$UNAME_RELEASE"-	exit ;;-    2020:CLIX:*:* | 2430:CLIX:*:*)-	echo clipper-intergraph-clix"$UNAME_RELEASE"-	exit ;;-    mips:*:*:UMIPS | mips:*:*:RISCos)-	set_cc_for_build-	sed 's/^	//' << EOF > "$dummy.c"-#ifdef __cplusplus-#include <stdio.h>  /* for printf() prototype */-	int main (int argc, char *argv[]) {-#else-	int main (argc, argv) int argc; char *argv[]; {-#endif-	#if defined (host_mips) && defined (MIPSEB)-	#if defined (SYSTYPE_SYSV)-	  printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);-	#endif-	#if defined (SYSTYPE_SVR4)-	  printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);-	#endif-	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)-	  printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);-	#endif-	#endif-	  exit (-1);-	}-EOF-	$CC_FOR_BUILD -o "$dummy" "$dummy.c" &&-	  dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&-	  SYSTEM_NAME=$("$dummy" "$dummyarg") &&-	    { echo "$SYSTEM_NAME"; exit; }-	echo mips-mips-riscos"$UNAME_RELEASE"-	exit ;;-    Motorola:PowerMAX_OS:*:*)-	echo powerpc-motorola-powermax-	exit ;;-    Motorola:*:4.3:PL8-*)-	echo powerpc-harris-powermax-	exit ;;-    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)-	echo powerpc-harris-powermax-	exit ;;-    Night_Hawk:Power_UNIX:*:*)-	echo powerpc-harris-powerunix-	exit ;;-    m88k:CX/UX:7*:*)-	echo m88k-harris-cxux7-	exit ;;-    m88k:*:4*:R4*)-	echo m88k-motorola-sysv4-	exit ;;-    m88k:*:3*:R3*)-	echo m88k-motorola-sysv3-	exit ;;-    AViiON:dgux:*:*)-	# DG/UX returns AViiON for all architectures-	UNAME_PROCESSOR=$(/usr/bin/uname -p)-	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110-	then-	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \-	       test "$TARGET_BINARY_INTERFACE"x = x-	    then-		echo m88k-dg-dgux"$UNAME_RELEASE"-	    else-		echo m88k-dg-dguxbcs"$UNAME_RELEASE"-	    fi-	else-	    echo i586-dg-dgux"$UNAME_RELEASE"-	fi-	exit ;;-    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)-	echo m88k-dolphin-sysv3-	exit ;;-    M88*:*:R3*:*)-	# Delta 88k system running SVR3-	echo m88k-motorola-sysv3-	exit ;;-    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)-	echo m88k-tektronix-sysv3-	exit ;;-    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)-	echo m68k-tektronix-bsd-	exit ;;-    *:IRIX*:*:*)-	echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"-	exit ;;-    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.-	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id-	exit ;;               # Note that: echo "'$(uname -s)'" gives 'AIX '-    i*86:AIX:*:*)-	echo i386-ibm-aix-	exit ;;-    ia64:AIX:*:*)-	if test -x /usr/bin/oslevel ; then-		IBM_REV=$(/usr/bin/oslevel)-	else-		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"-	fi-	echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"-	exit ;;-    *:AIX:2:3)-	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then-		set_cc_for_build-		sed 's/^		//' << EOF > "$dummy.c"-		#include <sys/systemcfg.h>--		main()-			{-			if (!__power_pc())-				exit(1);-			puts("powerpc-ibm-aix3.2.5");-			exit(0);-			}-EOF-		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")-		then-			echo "$SYSTEM_NAME"-		else-			echo rs6000-ibm-aix3.2.5-		fi-	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then-		echo rs6000-ibm-aix3.2.4-	else-		echo rs6000-ibm-aix3.2-	fi-	exit ;;-    *:AIX:*:[4567])-	IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }')-	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then-		IBM_ARCH=rs6000-	else-		IBM_ARCH=powerpc-	fi-	if test -x /usr/bin/lslpp ; then-		IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |-			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)-	else-		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"-	fi-	echo "$IBM_ARCH"-ibm-aix"$IBM_REV"-	exit ;;-    *:AIX:*:*)-	echo rs6000-ibm-aix-	exit ;;-    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)-	echo romp-ibm-bsd4.4-	exit ;;-    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and-	echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to-	exit ;;                             # report: romp-ibm BSD 4.3-    *:BOSX:*:*)-	echo rs6000-bull-bosx-	exit ;;-    DPX/2?00:B.O.S.:*:*)-	echo m68k-bull-sysv3-	exit ;;-    9000/[34]??:4.3bsd:1.*:*)-	echo m68k-hp-bsd-	exit ;;-    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)-	echo m68k-hp-bsd4.4-	exit ;;-    9000/[34678]??:HP-UX:*:*)-	HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')-	case "$UNAME_MACHINE" in-	    9000/31?)            HP_ARCH=m68000 ;;-	    9000/[34]??)         HP_ARCH=m68k ;;-	    9000/[678][0-9][0-9])-		if test -x /usr/bin/getconf; then-		    sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)-		    sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)-		    case "$sc_cpu_version" in-		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0-		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1-		      532)                      # CPU_PA_RISC2_0-			case "$sc_kernel_bits" in-			  32) HP_ARCH=hppa2.0n ;;-			  64) HP_ARCH=hppa2.0w ;;-			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20-			esac ;;-		    esac-		fi-		if test "$HP_ARCH" = ""; then-		    set_cc_for_build-		    sed 's/^		//' << EOF > "$dummy.c"--		#define _HPUX_SOURCE-		#include <stdlib.h>-		#include <unistd.h>--		int main ()-		{-		#if defined(_SC_KERNEL_BITS)-		    long bits = sysconf(_SC_KERNEL_BITS);-		#endif-		    long cpu  = sysconf (_SC_CPU_VERSION);--		    switch (cpu)-			{-			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;-			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;-			case CPU_PA_RISC2_0:-		#if defined(_SC_KERNEL_BITS)-			    switch (bits)-				{-				case 64: puts ("hppa2.0w"); break;-				case 32: puts ("hppa2.0n"); break;-				default: puts ("hppa2.0"); break;-				} break;-		#else  /* !defined(_SC_KERNEL_BITS) */-			    puts ("hppa2.0"); break;-		#endif-			default: puts ("hppa1.0"); break;-			}-		    exit (0);-		}-EOF-		    (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")-		    test -z "$HP_ARCH" && HP_ARCH=hppa-		fi ;;-	esac-	if test "$HP_ARCH" = hppa2.0w-	then-	    set_cc_for_build--	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating-	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler-	    # generating 64-bit code.  GNU and HP use different nomenclature:-	    #-	    # $ CC_FOR_BUILD=cc ./config.guess-	    # => hppa2.0w-hp-hpux11.23-	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess-	    # => hppa64-hp-hpux11.23--	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |-		grep -q __LP64__-	    then-		HP_ARCH=hppa2.0w-	    else-		HP_ARCH=hppa64-	    fi-	fi-	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"-	exit ;;-    ia64:HP-UX:*:*)-	HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')-	echo ia64-hp-hpux"$HPUX_REV"-	exit ;;-    3050*:HI-UX:*:*)-	set_cc_for_build-	sed 's/^	//' << EOF > "$dummy.c"-	#include <unistd.h>-	int-	main ()-	{-	  long cpu = sysconf (_SC_CPU_VERSION);-	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns-	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct-	     results, however.  */-	  if (CPU_IS_PA_RISC (cpu))-	    {-	      switch (cpu)-		{-		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;-		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;-		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;-		  default: puts ("hppa-hitachi-hiuxwe2"); break;-		}-	    }-	  else if (CPU_IS_HP_MC68K (cpu))-	    puts ("m68k-hitachi-hiuxwe2");-	  else puts ("unknown-hitachi-hiuxwe2");-	  exit (0);-	}-EOF-	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&-		{ echo "$SYSTEM_NAME"; exit; }-	echo unknown-hitachi-hiuxwe2-	exit ;;-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)-	echo hppa1.1-hp-bsd-	exit ;;-    9000/8??:4.3bsd:*:*)-	echo hppa1.0-hp-bsd-	exit ;;-    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)-	echo hppa1.0-hp-mpeix-	exit ;;-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)-	echo hppa1.1-hp-osf-	exit ;;-    hp8??:OSF1:*:*)-	echo hppa1.0-hp-osf-	exit ;;-    i*86:OSF1:*:*)-	if test -x /usr/sbin/sysversion ; then-	    echo "$UNAME_MACHINE"-unknown-osf1mk-	else-	    echo "$UNAME_MACHINE"-unknown-osf1-	fi-	exit ;;-    parisc*:Lites*:*:*)-	echo hppa1.1-hp-lites-	exit ;;-    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)-	echo c1-convex-bsd-	exit ;;-    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)-	if getsysinfo -f scalar_acc-	then echo c32-convex-bsd-	else echo c2-convex-bsd-	fi-	exit ;;-    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)-	echo c34-convex-bsd-	exit ;;-    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)-	echo c38-convex-bsd-	exit ;;-    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)-	echo c4-convex-bsd-	exit ;;-    CRAY*Y-MP:*:*:*)-	echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'-	exit ;;-    CRAY*[A-Z]90:*:*:*)-	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \-	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \-	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \-	      -e 's/\.[^.]*$/.X/'-	exit ;;-    CRAY*TS:*:*:*)-	echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'-	exit ;;-    CRAY*T3E:*:*:*)-	echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'-	exit ;;-    CRAY*SV1:*:*:*)-	echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'-	exit ;;-    *:UNICOS/mp:*:*)-	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'-	exit ;;-    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)-	FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)-	FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')-	FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')-	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"-	exit ;;-    5000:UNIX_System_V:4.*:*)-	FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')-	FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')-	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"-	exit ;;-    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)-	echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"-	exit ;;-    sparc*:BSD/OS:*:*)-	echo sparc-unknown-bsdi"$UNAME_RELEASE"-	exit ;;-    *:BSD/OS:*:*)-	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"-	exit ;;-    arm:FreeBSD:*:*)-	UNAME_PROCESSOR=$(uname -p)-	set_cc_for_build-	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \-	    | grep -q __ARM_PCS_VFP-	then-	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi-	else-	    echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf-	fi-	exit ;;-    *:FreeBSD:*:*)-	UNAME_PROCESSOR=$(/usr/bin/uname -p)-	case "$UNAME_PROCESSOR" in-	    amd64)-		UNAME_PROCESSOR=x86_64 ;;-	    i386)-		UNAME_PROCESSOR=i586 ;;-	esac-	echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"-	exit ;;-    i*:CYGWIN*:*)-	echo "$UNAME_MACHINE"-pc-cygwin-	exit ;;-    *:MINGW64*:*)-	echo "$UNAME_MACHINE"-pc-mingw64-	exit ;;-    *:MINGW*:*)-	echo "$UNAME_MACHINE"-pc-mingw32-	exit ;;-    *:MSYS*:*)-	echo "$UNAME_MACHINE"-pc-msys-	exit ;;-    i*:PW*:*)-	echo "$UNAME_MACHINE"-pc-pw32-	exit ;;-    *:Interix*:*)-	case "$UNAME_MACHINE" in-	    x86)-		echo i586-pc-interix"$UNAME_RELEASE"-		exit ;;-	    authenticamd | genuineintel | EM64T)-		echo x86_64-unknown-interix"$UNAME_RELEASE"-		exit ;;-	    IA64)-		echo ia64-unknown-interix"$UNAME_RELEASE"-		exit ;;-	esac ;;-    i*:UWIN*:*)-	echo "$UNAME_MACHINE"-pc-uwin-	exit ;;-    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)-	echo x86_64-pc-cygwin-	exit ;;-    prep*:SunOS:5.*:*)-	echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"-	exit ;;-    *:GNU:*:*)-	# the GNU system-	echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"-	exit ;;-    *:GNU/*:*:*)-	# other systems with GNU libc and userland-	echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"-	exit ;;-    *:Minix:*:*)-	echo "$UNAME_MACHINE"-unknown-minix-	exit ;;-    aarch64:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    aarch64_be:Linux:*:*)-	UNAME_MACHINE=aarch64_be-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    alpha:Linux:*:*)-	case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in-	  EV5)   UNAME_MACHINE=alphaev5 ;;-	  EV56)  UNAME_MACHINE=alphaev56 ;;-	  PCA56) UNAME_MACHINE=alphapca56 ;;-	  PCA57) UNAME_MACHINE=alphapca56 ;;-	  EV6)   UNAME_MACHINE=alphaev6 ;;-	  EV67)  UNAME_MACHINE=alphaev67 ;;-	  EV68*) UNAME_MACHINE=alphaev68 ;;-	esac-	objdump --private-headers /bin/sh | grep -q ld.so.1-	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    arc:Linux:*:* | arceb:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    arm*:Linux:*:*)-	set_cc_for_build-	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \-	    | grep -q __ARM_EABI__-	then-	    echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	else-	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \-		| grep -q __ARM_PCS_VFP-	    then-		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi-	    else-		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf-	    fi-	fi-	exit ;;-    avr32*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    cris:Linux:*:*)-	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"-	exit ;;-    crisv32:Linux:*:*)-	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"-	exit ;;-    e2k:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    frv:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    hexagon:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    i*86:Linux:*:*)-	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"-	exit ;;-    ia64:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    k1om:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    m32r*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    m68*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    mips:Linux:*:* | mips64:Linux:*:*)-	set_cc_for_build-	IS_GLIBC=0-	test x"${LIBC}" = xgnu && IS_GLIBC=1-	sed 's/^	//' << EOF > "$dummy.c"-	#undef CPU-	#undef mips-	#undef mipsel-	#undef mips64-	#undef mips64el-	#if ${IS_GLIBC} && defined(_ABI64)-	LIBCABI=gnuabi64-	#else-	#if ${IS_GLIBC} && defined(_ABIN32)-	LIBCABI=gnuabin32-	#else-	LIBCABI=${LIBC}-	#endif-	#endif--	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6-	CPU=mipsisa64r6-	#else-	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6-	CPU=mipsisa32r6-	#else-	#if defined(__mips64)-	CPU=mips64-	#else-	CPU=mips-	#endif-	#endif-	#endif--	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)-	MIPS_ENDIAN=el-	#else-	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)-	MIPS_ENDIAN=-	#else-	MIPS_ENDIAN=-	#endif-	#endif-EOF-	eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"-	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }-	;;-    mips64el:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    openrisc*:Linux:*:*)-	echo or1k-unknown-linux-"$LIBC"-	exit ;;-    or32:Linux:*:* | or1k*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    padre:Linux:*:*)-	echo sparc-unknown-linux-"$LIBC"-	exit ;;-    parisc64:Linux:*:* | hppa64:Linux:*:*)-	echo hppa64-unknown-linux-"$LIBC"-	exit ;;-    parisc:Linux:*:* | hppa:Linux:*:*)-	# Look for CPU level-	case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in-	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;-	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;-	  *)    echo hppa-unknown-linux-"$LIBC" ;;-	esac-	exit ;;-    ppc64:Linux:*:*)-	echo powerpc64-unknown-linux-"$LIBC"-	exit ;;-    ppc:Linux:*:*)-	echo powerpc-unknown-linux-"$LIBC"-	exit ;;-    ppc64le:Linux:*:*)-	echo powerpc64le-unknown-linux-"$LIBC"-	exit ;;-    ppcle:Linux:*:*)-	echo powerpcle-unknown-linux-"$LIBC"-	exit ;;-    riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    s390:Linux:*:* | s390x:Linux:*:*)-	echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"-	exit ;;-    sh64*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    sh*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    sparc:Linux:*:* | sparc64:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    tile*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    vax:Linux:*:*)-	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"-	exit ;;-    x86_64:Linux:*:*)-	set_cc_for_build-	LIBCABI=$LIBC-	if test "$CC_FOR_BUILD" != no_compiler_found; then-	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \-		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \-		grep IS_X32 >/dev/null-	    then-		LIBCABI="$LIBC"x32-	    fi-	fi-	echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI"-	exit ;;-    xtensa*:Linux:*:*)-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"-	exit ;;-    i*86:DYNIX/ptx:4*:*)-	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.-	# earlier versions are messed up and put the nodename in both-	# sysname and nodename.-	echo i386-sequent-sysv4-	exit ;;-    i*86:UNIX_SV:4.2MP:2.*)-	# Unixware is an offshoot of SVR4, but it has its own version-	# number series starting with 2...-	# I am not positive that other SVR4 systems won't match this,-	# I just have to hope.  -- rms.-	# Use sysv4.2uw... so that sysv4* matches it.-	echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"-	exit ;;-    i*86:OS/2:*:*)-	# If we were able to find `uname', then EMX Unix compatibility-	# is probably installed.-	echo "$UNAME_MACHINE"-pc-os2-emx-	exit ;;-    i*86:XTS-300:*:STOP)-	echo "$UNAME_MACHINE"-unknown-stop-	exit ;;-    i*86:atheos:*:*)-	echo "$UNAME_MACHINE"-unknown-atheos-	exit ;;-    i*86:syllable:*:*)-	echo "$UNAME_MACHINE"-pc-syllable-	exit ;;-    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)-	echo i386-unknown-lynxos"$UNAME_RELEASE"-	exit ;;-    i*86:*DOS:*:*)-	echo "$UNAME_MACHINE"-pc-msdosdjgpp-	exit ;;-    i*86:*:4.*:*)-	UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')-	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then-		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"-	else-		echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"-	fi-	exit ;;-    i*86:*:5:[678]*)-	# UnixWare 7.x, OpenUNIX and OpenServer 6.-	case $(/bin/uname -X | grep "^Machine") in-	    *486*)	     UNAME_MACHINE=i486 ;;-	    *Pentium)	     UNAME_MACHINE=i586 ;;-	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;-	esac-	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}"-	exit ;;-    i*86:*:3.2:*)-	if test -f /usr/options/cb.name; then-		UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)-		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"-	elif /bin/uname -X 2>/dev/null >/dev/null ; then-		UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))-		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486-		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \-			&& UNAME_MACHINE=i586-		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \-			&& UNAME_MACHINE=i686-		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \-			&& UNAME_MACHINE=i686-		echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"-	else-		echo "$UNAME_MACHINE"-pc-sysv32-	fi-	exit ;;-    pc:*:*:*)-	# Left here for compatibility:-	# uname -m prints for DJGPP always 'pc', but it prints nothing about-	# the processor, so we play safe by assuming i586.-	# Note: whatever this is, it MUST be the same as what config.sub-	# prints for the "djgpp" host, or else GDB configure will decide that-	# this is a cross-build.-	echo i586-pc-msdosdjgpp-	exit ;;-    Intel:Mach:3*:*)-	echo i386-pc-mach3-	exit ;;-    paragon:*:*:*)-	echo i860-intel-osf1-	exit ;;-    i860:*:4.*:*) # i860-SVR4-	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then-	  echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4-	else # Add other i860-SVR4 vendors below as they are discovered.-	  echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4-	fi-	exit ;;-    mini*:CTIX:SYS*5:*)-	# "miniframe"-	echo m68010-convergent-sysv-	exit ;;-    mc68k:UNIX:SYSTEM5:3.51m)-	echo m68k-convergent-sysv-	exit ;;-    M680?0:D-NIX:5.3:*)-	echo m68k-diab-dnix-	exit ;;-    M68*:*:R3V[5678]*:*)-	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;-    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)-	OS_REL=''-	test -r /etc/.relid \-	&& OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \-	  && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }-	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \-	  && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;-    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \-	  && { echo i486-ncr-sysv4; exit; } ;;-    NCR*:*:4.2:* | MPRAS*:*:4.2:*)-	OS_REL='.3'-	test -r /etc/.relid \-	    && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid)-	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \-	    && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }-	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \-	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }-	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \-	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;-    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)-	echo m68k-unknown-lynxos"$UNAME_RELEASE"-	exit ;;-    mc68030:UNIX_System_V:4.*:*)-	echo m68k-atari-sysv4-	exit ;;-    TSUNAMI:LynxOS:2.*:*)-	echo sparc-unknown-lynxos"$UNAME_RELEASE"-	exit ;;-    rs6000:LynxOS:2.*:*)-	echo rs6000-unknown-lynxos"$UNAME_RELEASE"-	exit ;;-    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)-	echo powerpc-unknown-lynxos"$UNAME_RELEASE"-	exit ;;-    SM[BE]S:UNIX_SV:*:*)-	echo mips-dde-sysv"$UNAME_RELEASE"-	exit ;;-    RM*:ReliantUNIX-*:*:*)-	echo mips-sni-sysv4-	exit ;;-    RM*:SINIX-*:*:*)-	echo mips-sni-sysv4-	exit ;;-    *:SINIX-*:*:*)-	if uname -p 2>/dev/null >/dev/null ; then-		UNAME_MACHINE=$( (uname -p) 2>/dev/null)-		echo "$UNAME_MACHINE"-sni-sysv4-	else-		echo ns32k-sni-sysv-	fi-	exit ;;-    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort-			# says <Richard.M.Bartel@ccMail.Census.GOV>-	echo i586-unisys-sysv4-	exit ;;-    *:UNIX_System_V:4*:FTX*)-	# From Gerald Hewes <hewes@openmarket.com>.-	# How about differentiating between stratus architectures? -djm-	echo hppa1.1-stratus-sysv4-	exit ;;-    *:*:*:FTX*)-	# From seanf@swdc.stratus.com.-	echo i860-stratus-sysv4-	exit ;;-    i*86:VOS:*:*)-	# From Paul.Green@stratus.com.-	echo "$UNAME_MACHINE"-stratus-vos-	exit ;;-    *:VOS:*:*)-	# From Paul.Green@stratus.com.-	echo hppa1.1-stratus-vos-	exit ;;-    mc68*:A/UX:*:*)-	echo m68k-apple-aux"$UNAME_RELEASE"-	exit ;;-    news*:NEWS-OS:6*:*)-	echo mips-sony-newsos6-	exit ;;-    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)-	if test -d /usr/nec; then-		echo mips-nec-sysv"$UNAME_RELEASE"-	else-		echo mips-unknown-sysv"$UNAME_RELEASE"-	fi-	exit ;;-    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.-	echo powerpc-be-beos-	exit ;;-    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.-	echo powerpc-apple-beos-	exit ;;-    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.-	echo i586-pc-beos-	exit ;;-    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.-	echo i586-pc-haiku-	exit ;;-    x86_64:Haiku:*:*)-	echo x86_64-unknown-haiku-	exit ;;-    SX-4:SUPER-UX:*:*)-	echo sx4-nec-superux"$UNAME_RELEASE"-	exit ;;-    SX-5:SUPER-UX:*:*)-	echo sx5-nec-superux"$UNAME_RELEASE"-	exit ;;-    SX-6:SUPER-UX:*:*)-	echo sx6-nec-superux"$UNAME_RELEASE"-	exit ;;-    SX-7:SUPER-UX:*:*)-	echo sx7-nec-superux"$UNAME_RELEASE"-	exit ;;-    SX-8:SUPER-UX:*:*)-	echo sx8-nec-superux"$UNAME_RELEASE"-	exit ;;-    SX-8R:SUPER-UX:*:*)-	echo sx8r-nec-superux"$UNAME_RELEASE"-	exit ;;-    SX-ACE:SUPER-UX:*:*)-	echo sxace-nec-superux"$UNAME_RELEASE"-	exit ;;-    Power*:Rhapsody:*:*)-	echo powerpc-apple-rhapsody"$UNAME_RELEASE"-	exit ;;-    *:Rhapsody:*:*)-	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"-	exit ;;-    arm64:Darwin:*:*)-	echo aarch64-apple-darwin"$UNAME_RELEASE"-	exit ;;-    *:Darwin:*:*)-	UNAME_PROCESSOR=$(uname -p)-	case $UNAME_PROCESSOR in-	    unknown) UNAME_PROCESSOR=powerpc ;;-	esac-	if command -v xcode-select > /dev/null 2> /dev/null && \-		! xcode-select --print-path > /dev/null 2> /dev/null ; then-	    # Avoid executing cc if there is no toolchain installed as-	    # cc will be a stub that puts up a graphical alert-	    # prompting the user to install developer tools.-	    CC_FOR_BUILD=no_compiler_found-	else-	    set_cc_for_build-	fi-	if test "$CC_FOR_BUILD" != no_compiler_found; then-	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \-		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \-		   grep IS_64BIT_ARCH >/dev/null-	    then-		case $UNAME_PROCESSOR in-		    i386) UNAME_PROCESSOR=x86_64 ;;-		    powerpc) UNAME_PROCESSOR=powerpc64 ;;-		esac-	    fi-	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc-	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \-		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \-		   grep IS_PPC >/dev/null-	    then-		UNAME_PROCESSOR=powerpc-	    fi-	elif test "$UNAME_PROCESSOR" = i386 ; then-	    # uname -m returns i386 or x86_64-	    UNAME_PROCESSOR=$UNAME_MACHINE-	fi-	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"-	exit ;;-    *:procnto*:*:* | *:QNX:[0123456789]*:*)-	UNAME_PROCESSOR=$(uname -p)-	if test "$UNAME_PROCESSOR" = x86; then-		UNAME_PROCESSOR=i386-		UNAME_MACHINE=pc-	fi-	echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"-	exit ;;-    *:QNX:*:4*)-	echo i386-pc-qnx-	exit ;;-    NEO-*:NONSTOP_KERNEL:*:*)-	echo neo-tandem-nsk"$UNAME_RELEASE"-	exit ;;-    NSE-*:NONSTOP_KERNEL:*:*)-	echo nse-tandem-nsk"$UNAME_RELEASE"-	exit ;;-    NSR-*:NONSTOP_KERNEL:*:*)-	echo nsr-tandem-nsk"$UNAME_RELEASE"-	exit ;;-    NSV-*:NONSTOP_KERNEL:*:*)-	echo nsv-tandem-nsk"$UNAME_RELEASE"-	exit ;;-    NSX-*:NONSTOP_KERNEL:*:*)-	echo nsx-tandem-nsk"$UNAME_RELEASE"-	exit ;;-    *:NonStop-UX:*:*)-	echo mips-compaq-nonstopux-	exit ;;-    BS2000:POSIX*:*:*)-	echo bs2000-siemens-sysv-	exit ;;-    DS/*:UNIX_System_V:*:*)-	echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"-	exit ;;-    *:Plan9:*:*)-	# "uname -m" is not consistent, so use $cputype instead. 386-	# is converted to i386 for consistency with other x86-	# operating systems.-	# shellcheck disable=SC2154-	if test "$cputype" = 386; then-	    UNAME_MACHINE=i386-	else-	    UNAME_MACHINE="$cputype"-	fi-	echo "$UNAME_MACHINE"-unknown-plan9-	exit ;;-    *:TOPS-10:*:*)-	echo pdp10-unknown-tops10-	exit ;;-    *:TENEX:*:*)-	echo pdp10-unknown-tenex-	exit ;;-    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)-	echo pdp10-dec-tops20-	exit ;;-    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)-	echo pdp10-xkl-tops20-	exit ;;-    *:TOPS-20:*:*)-	echo pdp10-unknown-tops20-	exit ;;-    *:ITS:*:*)-	echo pdp10-unknown-its-	exit ;;-    SEI:*:*:SEIUX)-	echo mips-sei-seiux"$UNAME_RELEASE"-	exit ;;-    *:DragonFly:*:*)-	echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"-	exit ;;-    *:*VMS:*:*)-	UNAME_MACHINE=$( (uname -p) 2>/dev/null)-	case "$UNAME_MACHINE" in-	    A*) echo alpha-dec-vms ; exit ;;-	    I*) echo ia64-dec-vms ; exit ;;-	    V*) echo vax-dec-vms ; exit ;;-	esac ;;-    *:XENIX:*:SysV)-	echo i386-pc-xenix-	exit ;;-    i*86:skyos:*:*)-	echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"-	exit ;;-    i*86:rdos:*:*)-	echo "$UNAME_MACHINE"-pc-rdos-	exit ;;-    *:AROS:*:*)-	echo "$UNAME_MACHINE"-unknown-aros-	exit ;;-    x86_64:VMkernel:*:*)-	echo "$UNAME_MACHINE"-unknown-esx-	exit ;;-    amd64:Isilon\ OneFS:*:*)-	echo x86_64-unknown-onefs-	exit ;;-    *:Unleashed:*:*)-	echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE"-	exit ;;-esac--# No uname command or uname output not recognized.-set_cc_for_build-cat > "$dummy.c" <<EOF-#ifdef _SEQUENT_-#include <sys/types.h>-#include <sys/utsname.h>-#endif-#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)-#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)-#include <signal.h>-#if defined(_SIZE_T_) || defined(SIGLOST)-#include <sys/utsname.h>-#endif-#endif-#endif-main ()-{-#if defined (sony)-#if defined (MIPSEB)-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,-     I don't know....  */-  printf ("mips-sony-bsd\n"); exit (0);-#else-#include <sys/param.h>-  printf ("m68k-sony-newsos%s\n",-#ifdef NEWSOS4-  "4"-#else-  ""-#endif-  ); exit (0);-#endif-#endif--#if defined (NeXT)-#if !defined (__ARCHITECTURE__)-#define __ARCHITECTURE__ "m68k"-#endif-  int version;-  version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);-  if (version < 4)-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);-  else-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);-  exit (0);-#endif--#if defined (MULTIMAX) || defined (n16)-#if defined (UMAXV)-  printf ("ns32k-encore-sysv\n"); exit (0);-#else-#if defined (CMU)-  printf ("ns32k-encore-mach\n"); exit (0);-#else-  printf ("ns32k-encore-bsd\n"); exit (0);-#endif-#endif-#endif--#if defined (__386BSD__)-  printf ("i386-pc-bsd\n"); exit (0);-#endif--#if defined (sequent)-#if defined (i386)-  printf ("i386-sequent-dynix\n"); exit (0);-#endif-#if defined (ns32000)-  printf ("ns32k-sequent-dynix\n"); exit (0);-#endif-#endif--#if defined (_SEQUENT_)-  struct utsname un;--  uname(&un);-  if (strncmp(un.version, "V2", 2) == 0) {-    printf ("i386-sequent-ptx2\n"); exit (0);-  }-  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */-    printf ("i386-sequent-ptx1\n"); exit (0);-  }-  printf ("i386-sequent-ptx\n"); exit (0);-#endif--#if defined (vax)-#if !defined (ultrix)-#include <sys/param.h>-#if defined (BSD)-#if BSD == 43-  printf ("vax-dec-bsd4.3\n"); exit (0);-#else-#if BSD == 199006-  printf ("vax-dec-bsd4.3reno\n"); exit (0);-#else-  printf ("vax-dec-bsd\n"); exit (0);-#endif-#endif-#else-  printf ("vax-dec-bsd\n"); exit (0);-#endif-#else-#if defined(_SIZE_T_) || defined(SIGLOST)-  struct utsname un;-  uname (&un);-  printf ("vax-dec-ultrix%s\n", un.release); exit (0);-#else-  printf ("vax-dec-ultrix\n"); exit (0);-#endif-#endif-#endif-#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)-#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)-#if defined(_SIZE_T_) || defined(SIGLOST)-  struct utsname *un;-  uname (&un);-  printf ("mips-dec-ultrix%s\n", un.release); exit (0);-#else-  printf ("mips-dec-ultrix\n"); exit (0);-#endif-#endif-#endif--#if defined (alliant) && defined (i860)-  printf ("i860-alliant-bsd\n"); exit (0);-#endif--  exit (1);-}-EOF--$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&-	{ echo "$SYSTEM_NAME"; exit; }--# Apollos put the system type in the environment.-test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }--echo "$0: unable to guess system type" >&2--case "$UNAME_MACHINE:$UNAME_SYSTEM" in-    mips:Linux | mips64:Linux)-	# If we got here on MIPS GNU/Linux, output extra information.-	cat >&2 <<EOF--NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize-the system type. Please install a C compiler and try again.-EOF-	;;-esac--cat >&2 <<EOF--This script (version $timestamp), has failed to recognize the-operating system you are using. If your script is old, overwrite *all*-copies of config.guess and config.sub with the latest versions from:--  https://git.savannah.gnu.org/cgit/config.git/plain/config.guess-and-  https://git.savannah.gnu.org/cgit/config.git/plain/config.sub-EOF--year=$(echo $timestamp | sed 's,-.*,,')-# shellcheck disable=SC2003-if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then-   cat >&2 <<EOF--If $0 has already been updated, send the following data and any-information you think might be pertinent to config-patches@gnu.org to-provide the necessary information to handle your system.--config.guess timestamp = $timestamp--uname -m = $( (uname -m) 2>/dev/null || echo unknown)-uname -r = $( (uname -r) 2>/dev/null || echo unknown)-uname -s = $( (uname -s) 2>/dev/null || echo unknown)-uname -v = $( (uname -v) 2>/dev/null || echo unknown)--/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)-/bin/uname -X     = $( (/bin/uname -X) 2>/dev/null)--hostinfo               = $( (hostinfo) 2>/dev/null)-/bin/universe          = $( (/bin/universe) 2>/dev/null)-/usr/bin/arch -k       = $( (/usr/bin/arch -k) 2>/dev/null)-/bin/arch              = $( (/bin/arch) 2>/dev/null)-/usr/bin/oslevel       = $( (/usr/bin/oslevel) 2>/dev/null)-/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)--UNAME_MACHINE = "$UNAME_MACHINE"-UNAME_RELEASE = "$UNAME_RELEASE"-UNAME_SYSTEM  = "$UNAME_SYSTEM"-UNAME_VERSION = "$UNAME_VERSION"-EOF-fi--exit 1--# Local variables:-# eval: (add-hook 'before-save-hook 'time-stamp)+#   Copyright 1992-2017 Free Software Foundation, Inc.++timestamp='2017-03-05'++# This file is free software; you can redistribute it and/or modify it+# under the terms of the GNU General Public License as published by+# the Free Software Foundation; either version 3 of the License, or+# (at your option) any later version.+#+# This program is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+# General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program; if not, see <http://www.gnu.org/licenses/>.+#+# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program that contains a+# configuration script generated by Autoconf, you may include it under+# the same distribution terms that you use for the rest of that+# program.  This Exception is an additional permission under section 7+# of the GNU General Public License, version 3 ("GPLv3").+#+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.+#+# You can get the latest version of this script from:+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess+#+# Please send patches to <config-patches@gnu.org>.+++me=`echo "$0" | sed -e 's,.*/,,'`++usage="\+Usage: $0 [OPTION]++Output the configuration name of the system \`$me' is run on.++Operation modes:+  -h, --help         print this help, then exit+  -t, --time-stamp   print date of last modification, then exit+  -v, --version      print version number, then exit++Report bugs and patches to <config-patches@gnu.org>."++version="\+GNU config.guess ($timestamp)++Originally written by Per Bothner.+Copyright 1992-2017 Free Software Foundation, Inc.++This is free software; see the source for copying conditions.  There is NO+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."++help="+Try \`$me --help' for more information."++# Parse command line+while test $# -gt 0 ; do+  case $1 in+    --time-stamp | --time* | -t )+       echo "$timestamp" ; exit ;;+    --version | -v )+       echo "$version" ; exit ;;+    --help | --h* | -h )+       echo "$usage"; exit ;;+    -- )     # Stop option processing+       shift; break ;;+    - )	# Use stdin as input.+       break ;;+    -* )+       echo "$me: invalid option $1$help" >&2+       exit 1 ;;+    * )+       break ;;+  esac+done++if test $# != 0; then+  echo "$me: too many arguments$help" >&2+  exit 1+fi++trap 'exit 1' 1 2 15++# CC_FOR_BUILD -- compiler used by this script. Note that the use of a+# compiler to aid in system detection is discouraged as it requires+# temporary files to be created and, as you can see below, it is a+# headache to deal with in a portable fashion.++# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still+# use `HOST_CC' if defined, but it is deprecated.++# Portable tmp directory creation inspired by the Autoconf team.++set_cc_for_build='+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;+: ${TMPDIR=/tmp} ;+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;+dummy=$tmp/dummy ;+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;+case $CC_FOR_BUILD,$HOST_CC,$CC in+ ,,)    echo "int x;" > $dummy.c ;+	for c in cc gcc c89 c99 ; do+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then+	     CC_FOR_BUILD="$c"; break ;+	  fi ;+	done ;+	if test x"$CC_FOR_BUILD" = x ; then+	  CC_FOR_BUILD=no_compiler_found ;+	fi+	;;+ ,,*)   CC_FOR_BUILD=$CC ;;+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;+esac ; set_cc_for_build= ;'++# This is needed to find uname on a Pyramid OSx when run in the BSD universe.+# (ghazi@noc.rutgers.edu 1994-08-24)+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then+	PATH=$PATH:/.attbin ; export PATH+fi++UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown++case "${UNAME_SYSTEM}" in+Linux|GNU|GNU/*)+	# If the system lacks a compiler, then just pick glibc.+	# We could probably try harder.+	LIBC=gnu++	eval $set_cc_for_build+	cat <<-EOF > $dummy.c+	#include <features.h>+	#if defined(__UCLIBC__)+	LIBC=uclibc+	#elif defined(__dietlibc__)+	LIBC=dietlibc+	#else+	LIBC=gnu+	#endif+	EOF+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`+	;;+esac++# Note: order is significant - the case branches are not exclusive.++case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in+    *:NetBSD:*:*)+	# NetBSD (nbsd) targets should (where applicable) match one or+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently+	# switched to ELF, *-*-netbsd* would select the old+	# object file format.  This provides both forward+	# compatibility and a consistent mechanism for selecting the+	# object file format.+	#+	# Note: NetBSD doesn't particularly care about the vendor+	# portion of the name.  We always set it to "unknown".+	sysctl="sysctl -n hw.machine_arch"+	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \+	    /sbin/$sysctl 2>/dev/null || \+	    /usr/sbin/$sysctl 2>/dev/null || \+	    echo unknown)`+	case "${UNAME_MACHINE_ARCH}" in+	    armeb) machine=armeb-unknown ;;+	    arm*) machine=arm-unknown ;;+	    sh3el) machine=shl-unknown ;;+	    sh3eb) machine=sh-unknown ;;+	    sh5el) machine=sh5le-unknown ;;+	    earmv*)+		arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`+		endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`+		machine=${arch}${endian}-unknown+		;;+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;+	esac+	# The Operating System including object format, if it has switched+	# to ELF recently (or will in the future) and ABI.+	case "${UNAME_MACHINE_ARCH}" in+	    earm*)+		os=netbsdelf+		;;+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)+		eval $set_cc_for_build+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \+			| grep -q __ELF__+		then+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).+		    # Return netbsd for either.  FIX?+		    os=netbsd+		else+		    os=netbsdelf+		fi+		;;+	    *)+		os=netbsd+		;;+	esac+	# Determine ABI tags.+	case "${UNAME_MACHINE_ARCH}" in+	    earm*)+		expr='s/^earmv[0-9]/-eabi/;s/eb$//'+		abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`+		;;+	esac+	# The OS release+	# Debian GNU/NetBSD machines have a different userland, and+	# thus, need a distinct triplet. However, they do not need+	# kernel version information, so it can be replaced with a+	# suitable tag, in the style of linux-gnu.+	case "${UNAME_VERSION}" in+	    Debian*)+		release='-gnu'+		;;+	    *)+		release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`+		;;+	esac+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:+	# contains redundant information, the shorter form:+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.+	echo "${machine}-${os}${release}${abi}"+	exit ;;+    *:Bitrig:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}+	exit ;;+    *:OpenBSD:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}+	exit ;;+    *:LibertyBSD:*:*)+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`+	echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}+	exit ;;+    *:ekkoBSD:*:*)+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}+	exit ;;+    *:SolidBSD:*:*)+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}+	exit ;;+    macppc:MirBSD:*:*)+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}+	exit ;;+    *:MirBSD:*:*)+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}+	exit ;;+    *:Sortix:*:*)+	echo ${UNAME_MACHINE}-unknown-sortix+	exit ;;+    alpha:OSF1:*:*)+	case $UNAME_RELEASE in+	*4.0)+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`+		;;+	*5.*)+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`+		;;+	esac+	# According to Compaq, /usr/sbin/psrinfo has been available on+	# OSF/1 and Tru64 systems produced since 1995.  I hope that+	# covers most systems running today.  This code pipes the CPU+	# types through head -n 1, so we only detect the type of CPU 0.+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`+	case "$ALPHA_CPU_TYPE" in+	    "EV4 (21064)")+		UNAME_MACHINE=alpha ;;+	    "EV4.5 (21064)")+		UNAME_MACHINE=alpha ;;+	    "LCA4 (21066/21068)")+		UNAME_MACHINE=alpha ;;+	    "EV5 (21164)")+		UNAME_MACHINE=alphaev5 ;;+	    "EV5.6 (21164A)")+		UNAME_MACHINE=alphaev56 ;;+	    "EV5.6 (21164PC)")+		UNAME_MACHINE=alphapca56 ;;+	    "EV5.7 (21164PC)")+		UNAME_MACHINE=alphapca57 ;;+	    "EV6 (21264)")+		UNAME_MACHINE=alphaev6 ;;+	    "EV6.7 (21264A)")+		UNAME_MACHINE=alphaev67 ;;+	    "EV6.8CB (21264C)")+		UNAME_MACHINE=alphaev68 ;;+	    "EV6.8AL (21264B)")+		UNAME_MACHINE=alphaev68 ;;+	    "EV6.8CX (21264D)")+		UNAME_MACHINE=alphaev68 ;;+	    "EV6.9A (21264/EV69A)")+		UNAME_MACHINE=alphaev69 ;;+	    "EV7 (21364)")+		UNAME_MACHINE=alphaev7 ;;+	    "EV7.9 (21364A)")+		UNAME_MACHINE=alphaev79 ;;+	esac+	# A Pn.n version is a patched version.+	# A Vn.n version is a released version.+	# A Tn.n version is a released field test version.+	# A Xn.n version is an unreleased experimental baselevel.+	# 1.2 uses "1.2" for uname -r.+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.+	exitcode=$?+	trap '' 0+	exit $exitcode ;;+    Alpha\ *:Windows_NT*:*)+	# How do we know it's Interix rather than the generic POSIX subsystem?+	# Should we change UNAME_MACHINE based on the output of uname instead+	# of the specific Alpha model?+	echo alpha-pc-interix+	exit ;;+    21064:Windows_NT:50:3)+	echo alpha-dec-winnt3.5+	exit ;;+    Amiga*:UNIX_System_V:4.0:*)+	echo m68k-unknown-sysv4+	exit ;;+    *:[Aa]miga[Oo][Ss]:*:*)+	echo ${UNAME_MACHINE}-unknown-amigaos+	exit ;;+    *:[Mm]orph[Oo][Ss]:*:*)+	echo ${UNAME_MACHINE}-unknown-morphos+	exit ;;+    *:OS/390:*:*)+	echo i370-ibm-openedition+	exit ;;+    *:z/VM:*:*)+	echo s390-ibm-zvmoe+	exit ;;+    *:OS400:*:*)+	echo powerpc-ibm-os400+	exit ;;+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)+	echo arm-acorn-riscix${UNAME_RELEASE}+	exit ;;+    arm*:riscos:*:*|arm*:RISCOS:*:*)+	echo arm-unknown-riscos+	exit ;;+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)+	echo hppa1.1-hitachi-hiuxmpp+	exit ;;+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.+	if test "`(/bin/universe) 2>/dev/null`" = att ; then+		echo pyramid-pyramid-sysv3+	else+		echo pyramid-pyramid-bsd+	fi+	exit ;;+    NILE*:*:*:dcosx)+	echo pyramid-pyramid-svr4+	exit ;;+    DRS?6000:unix:4.0:6*)+	echo sparc-icl-nx6+	exit ;;+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)+	case `/usr/bin/uname -p` in+	    sparc) echo sparc-icl-nx7; exit ;;+	esac ;;+    s390x:SunOS:*:*)+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`+	exit ;;+    sun4H:SunOS:5.*:*)+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`+	exit ;;+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`+	exit ;;+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)+	echo i386-pc-auroraux${UNAME_RELEASE}+	exit ;;+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)+	eval $set_cc_for_build+	SUN_ARCH=i386+	# If there is a compiler, see if it is configured for 64-bit objects.+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.+	# This test works for both compilers.+	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \+		grep IS_64BIT_ARCH >/dev/null+	    then+		SUN_ARCH=x86_64+	    fi+	fi+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`+	exit ;;+    sun4*:SunOS:6*:*)+	# According to config.sub, this is the proper way to canonicalize+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but+	# it's likely to be more like Solaris than SunOS4.+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`+	exit ;;+    sun4*:SunOS:*:*)+	case "`/usr/bin/arch -k`" in+	    Series*|S4*)+		UNAME_RELEASE=`uname -v`+		;;+	esac+	# Japanese Language versions have a version number like `4.1.3-JL'.+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`+	exit ;;+    sun3*:SunOS:*:*)+	echo m68k-sun-sunos${UNAME_RELEASE}+	exit ;;+    sun*:*:4.2BSD:*)+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`+	test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3+	case "`/bin/arch`" in+	    sun3)+		echo m68k-sun-sunos${UNAME_RELEASE}+		;;+	    sun4)+		echo sparc-sun-sunos${UNAME_RELEASE}+		;;+	esac+	exit ;;+    aushp:SunOS:*:*)+	echo sparc-auspex-sunos${UNAME_RELEASE}+	exit ;;+    # The situation for MiNT is a little confusing.  The machine name+    # can be virtually everything (everything which is not+    # "atarist" or "atariste" at least should have a processor+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"+    # to the lowercase version "mint" (or "freemint").  Finally+    # the system name "TOS" denotes a system which is actually not+    # MiNT.  But MiNT is downward compatible to TOS, so this should+    # be no problem.+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)+	echo m68k-atari-mint${UNAME_RELEASE}+	exit ;;+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)+	echo m68k-atari-mint${UNAME_RELEASE}+	exit ;;+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)+	echo m68k-atari-mint${UNAME_RELEASE}+	exit ;;+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)+	echo m68k-milan-mint${UNAME_RELEASE}+	exit ;;+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)+	echo m68k-hades-mint${UNAME_RELEASE}+	exit ;;+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)+	echo m68k-unknown-mint${UNAME_RELEASE}+	exit ;;+    m68k:machten:*:*)+	echo m68k-apple-machten${UNAME_RELEASE}+	exit ;;+    powerpc:machten:*:*)+	echo powerpc-apple-machten${UNAME_RELEASE}+	exit ;;+    RISC*:Mach:*:*)+	echo mips-dec-mach_bsd4.3+	exit ;;+    RISC*:ULTRIX:*:*)+	echo mips-dec-ultrix${UNAME_RELEASE}+	exit ;;+    VAX*:ULTRIX*:*:*)+	echo vax-dec-ultrix${UNAME_RELEASE}+	exit ;;+    2020:CLIX:*:* | 2430:CLIX:*:*)+	echo clipper-intergraph-clix${UNAME_RELEASE}+	exit ;;+    mips:*:*:UMIPS | mips:*:*:RISCos)+	eval $set_cc_for_build+	sed 's/^	//' << EOF >$dummy.c+#ifdef __cplusplus+#include <stdio.h>  /* for printf() prototype */+	int main (int argc, char *argv[]) {+#else+	int main (argc, argv) int argc; char *argv[]; {+#endif+	#if defined (host_mips) && defined (MIPSEB)+	#if defined (SYSTYPE_SYSV)+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);+	#endif+	#if defined (SYSTYPE_SVR4)+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);+	#endif+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);+	#endif+	#endif+	  exit (-1);+	}+EOF+	$CC_FOR_BUILD -o $dummy $dummy.c &&+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&+	  SYSTEM_NAME=`$dummy $dummyarg` &&+	    { echo "$SYSTEM_NAME"; exit; }+	echo mips-mips-riscos${UNAME_RELEASE}+	exit ;;+    Motorola:PowerMAX_OS:*:*)+	echo powerpc-motorola-powermax+	exit ;;+    Motorola:*:4.3:PL8-*)+	echo powerpc-harris-powermax+	exit ;;+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)+	echo powerpc-harris-powermax+	exit ;;+    Night_Hawk:Power_UNIX:*:*)+	echo powerpc-harris-powerunix+	exit ;;+    m88k:CX/UX:7*:*)+	echo m88k-harris-cxux7+	exit ;;+    m88k:*:4*:R4*)+	echo m88k-motorola-sysv4+	exit ;;+    m88k:*:3*:R3*)+	echo m88k-motorola-sysv3+	exit ;;+    AViiON:dgux:*:*)+	# DG/UX returns AViiON for all architectures+	UNAME_PROCESSOR=`/usr/bin/uname -p`+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]+	then+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \+	       [ ${TARGET_BINARY_INTERFACE}x = x ]+	    then+		echo m88k-dg-dgux${UNAME_RELEASE}+	    else+		echo m88k-dg-dguxbcs${UNAME_RELEASE}+	    fi+	else+	    echo i586-dg-dgux${UNAME_RELEASE}+	fi+	exit ;;+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)+	echo m88k-dolphin-sysv3+	exit ;;+    M88*:*:R3*:*)+	# Delta 88k system running SVR3+	echo m88k-motorola-sysv3+	exit ;;+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)+	echo m88k-tektronix-sysv3+	exit ;;+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)+	echo m68k-tektronix-bsd+	exit ;;+    *:IRIX*:*:*)+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`+	exit ;;+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '+    i*86:AIX:*:*)+	echo i386-ibm-aix+	exit ;;+    ia64:AIX:*:*)+	if [ -x /usr/bin/oslevel ] ; then+		IBM_REV=`/usr/bin/oslevel`+	else+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}+	fi+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}+	exit ;;+    *:AIX:2:3)+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then+		eval $set_cc_for_build+		sed 's/^		//' << EOF >$dummy.c+		#include <sys/systemcfg.h>++		main()+			{+			if (!__power_pc())+				exit(1);+			puts("powerpc-ibm-aix3.2.5");+			exit(0);+			}+EOF+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`+		then+			echo "$SYSTEM_NAME"+		else+			echo rs6000-ibm-aix3.2.5+		fi+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then+		echo rs6000-ibm-aix3.2.4+	else+		echo rs6000-ibm-aix3.2+	fi+	exit ;;+    *:AIX:*:[4567])+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then+		IBM_ARCH=rs6000+	else+		IBM_ARCH=powerpc+	fi+	if [ -x /usr/bin/lslpp ] ; then+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |+			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`+	else+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}+	fi+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}+	exit ;;+    *:AIX:*:*)+	echo rs6000-ibm-aix+	exit ;;+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)+	echo romp-ibm-bsd4.4+	exit ;;+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to+	exit ;;                             # report: romp-ibm BSD 4.3+    *:BOSX:*:*)+	echo rs6000-bull-bosx+	exit ;;+    DPX/2?00:B.O.S.:*:*)+	echo m68k-bull-sysv3+	exit ;;+    9000/[34]??:4.3bsd:1.*:*)+	echo m68k-hp-bsd+	exit ;;+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)+	echo m68k-hp-bsd4.4+	exit ;;+    9000/[34678]??:HP-UX:*:*)+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`+	case "${UNAME_MACHINE}" in+	    9000/31? )            HP_ARCH=m68000 ;;+	    9000/[34]?? )         HP_ARCH=m68k ;;+	    9000/[678][0-9][0-9])+		if [ -x /usr/bin/getconf ]; then+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`+		    case "${sc_cpu_version}" in+		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0+		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1+		      532)                      # CPU_PA_RISC2_0+			case "${sc_kernel_bits}" in+			  32) HP_ARCH=hppa2.0n ;;+			  64) HP_ARCH=hppa2.0w ;;+			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20+			esac ;;+		    esac+		fi+		if [ "${HP_ARCH}" = "" ]; then+		    eval $set_cc_for_build+		    sed 's/^		//' << EOF >$dummy.c++		#define _HPUX_SOURCE+		#include <stdlib.h>+		#include <unistd.h>++		int main ()+		{+		#if defined(_SC_KERNEL_BITS)+		    long bits = sysconf(_SC_KERNEL_BITS);+		#endif+		    long cpu  = sysconf (_SC_CPU_VERSION);++		    switch (cpu)+			{+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;+			case CPU_PA_RISC2_0:+		#if defined(_SC_KERNEL_BITS)+			    switch (bits)+				{+				case 64: puts ("hppa2.0w"); break;+				case 32: puts ("hppa2.0n"); break;+				default: puts ("hppa2.0"); break;+				} break;+		#else  /* !defined(_SC_KERNEL_BITS) */+			    puts ("hppa2.0"); break;+		#endif+			default: puts ("hppa1.0"); break;+			}+		    exit (0);+		}+EOF+		    (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`+		    test -z "$HP_ARCH" && HP_ARCH=hppa+		fi ;;+	esac+	if [ ${HP_ARCH} = hppa2.0w ]+	then+	    eval $set_cc_for_build++	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler+	    # generating 64-bit code.  GNU and HP use different nomenclature:+	    #+	    # $ CC_FOR_BUILD=cc ./config.guess+	    # => hppa2.0w-hp-hpux11.23+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess+	    # => hppa64-hp-hpux11.23++	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |+		grep -q __LP64__+	    then+		HP_ARCH=hppa2.0w+	    else+		HP_ARCH=hppa64+	    fi+	fi+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}+	exit ;;+    ia64:HP-UX:*:*)+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`+	echo ia64-hp-hpux${HPUX_REV}+	exit ;;+    3050*:HI-UX:*:*)+	eval $set_cc_for_build+	sed 's/^	//' << EOF >$dummy.c+	#include <unistd.h>+	int+	main ()+	{+	  long cpu = sysconf (_SC_CPU_VERSION);+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct+	     results, however.  */+	  if (CPU_IS_PA_RISC (cpu))+	    {+	      switch (cpu)+		{+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;+		  default: puts ("hppa-hitachi-hiuxwe2"); break;+		}+	    }+	  else if (CPU_IS_HP_MC68K (cpu))+	    puts ("m68k-hitachi-hiuxwe2");+	  else puts ("unknown-hitachi-hiuxwe2");+	  exit (0);+	}+EOF+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&+		{ echo "$SYSTEM_NAME"; exit; }+	echo unknown-hitachi-hiuxwe2+	exit ;;+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )+	echo hppa1.1-hp-bsd+	exit ;;+    9000/8??:4.3bsd:*:*)+	echo hppa1.0-hp-bsd+	exit ;;+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)+	echo hppa1.0-hp-mpeix+	exit ;;+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )+	echo hppa1.1-hp-osf+	exit ;;+    hp8??:OSF1:*:*)+	echo hppa1.0-hp-osf+	exit ;;+    i*86:OSF1:*:*)+	if [ -x /usr/sbin/sysversion ] ; then+	    echo ${UNAME_MACHINE}-unknown-osf1mk+	else+	    echo ${UNAME_MACHINE}-unknown-osf1+	fi+	exit ;;+    parisc*:Lites*:*:*)+	echo hppa1.1-hp-lites+	exit ;;+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)+	echo c1-convex-bsd+	exit ;;+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)+	if getsysinfo -f scalar_acc+	then echo c32-convex-bsd+	else echo c2-convex-bsd+	fi+	exit ;;+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)+	echo c34-convex-bsd+	exit ;;+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)+	echo c38-convex-bsd+	exit ;;+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)+	echo c4-convex-bsd+	exit ;;+    CRAY*Y-MP:*:*:*)+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'+	exit ;;+    CRAY*[A-Z]90:*:*:*)+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \+	      -e 's/\.[^.]*$/.X/'+	exit ;;+    CRAY*TS:*:*:*)+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'+	exit ;;+    CRAY*T3E:*:*:*)+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'+	exit ;;+    CRAY*SV1:*:*:*)+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'+	exit ;;+    *:UNICOS/mp:*:*)+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'+	exit ;;+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)+	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"+	exit ;;+    5000:UNIX_System_V:4.*:*)+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"+	exit ;;+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}+	exit ;;+    sparc*:BSD/OS:*:*)+	echo sparc-unknown-bsdi${UNAME_RELEASE}+	exit ;;+    *:BSD/OS:*:*)+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}+	exit ;;+    *:FreeBSD:*:*)+	UNAME_PROCESSOR=`/usr/bin/uname -p`+	case ${UNAME_PROCESSOR} in+	    amd64)+		UNAME_PROCESSOR=x86_64 ;;+	    i386)+		UNAME_PROCESSOR=i586 ;;+	esac+	echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`+	exit ;;+    i*:CYGWIN*:*)+	echo ${UNAME_MACHINE}-pc-cygwin+	exit ;;+    *:MINGW64*:*)+	echo ${UNAME_MACHINE}-pc-mingw64+	exit ;;+    *:MINGW*:*)+	echo ${UNAME_MACHINE}-pc-mingw32+	exit ;;+    *:MSYS*:*)+	echo ${UNAME_MACHINE}-pc-msys+	exit ;;+    i*:windows32*:*)+	# uname -m includes "-pc" on this system.+	echo ${UNAME_MACHINE}-mingw32+	exit ;;+    i*:PW*:*)+	echo ${UNAME_MACHINE}-pc-pw32+	exit ;;+    *:Interix*:*)+	case ${UNAME_MACHINE} in+	    x86)+		echo i586-pc-interix${UNAME_RELEASE}+		exit ;;+	    authenticamd | genuineintel | EM64T)+		echo x86_64-unknown-interix${UNAME_RELEASE}+		exit ;;+	    IA64)+		echo ia64-unknown-interix${UNAME_RELEASE}+		exit ;;+	esac ;;+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)+	echo i${UNAME_MACHINE}-pc-mks+	exit ;;+    8664:Windows_NT:*)+	echo x86_64-pc-mks+	exit ;;+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)+	# How do we know it's Interix rather than the generic POSIX subsystem?+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we+	# UNAME_MACHINE based on the output of uname instead of i386?+	echo i586-pc-interix+	exit ;;+    i*:UWIN*:*)+	echo ${UNAME_MACHINE}-pc-uwin+	exit ;;+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)+	echo x86_64-unknown-cygwin+	exit ;;+    p*:CYGWIN*:*)+	echo powerpcle-unknown-cygwin+	exit ;;+    prep*:SunOS:5.*:*)+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`+	exit ;;+    *:GNU:*:*)+	# the GNU system+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`+	exit ;;+    *:GNU/*:*:*)+	# other systems with GNU libc and userland+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}+	exit ;;+    i*86:Minix:*:*)+	echo ${UNAME_MACHINE}-pc-minix+	exit ;;+    aarch64:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    aarch64_be:Linux:*:*)+	UNAME_MACHINE=aarch64_be+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    alpha:Linux:*:*)+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in+	  EV5)   UNAME_MACHINE=alphaev5 ;;+	  EV56)  UNAME_MACHINE=alphaev56 ;;+	  PCA56) UNAME_MACHINE=alphapca56 ;;+	  PCA57) UNAME_MACHINE=alphapca56 ;;+	  EV6)   UNAME_MACHINE=alphaev6 ;;+	  EV67)  UNAME_MACHINE=alphaev67 ;;+	  EV68*) UNAME_MACHINE=alphaev68 ;;+	esac+	objdump --private-headers /bin/sh | grep -q ld.so.1+	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    arc:Linux:*:* | arceb:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    arm*:Linux:*:*)+	eval $set_cc_for_build+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \+	    | grep -q __ARM_EABI__+	then+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	else+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \+		| grep -q __ARM_PCS_VFP+	    then+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi+	    else+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf+	    fi+	fi+	exit ;;+    avr32*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    cris:Linux:*:*)+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}+	exit ;;+    crisv32:Linux:*:*)+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}+	exit ;;+    e2k:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    frv:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    hexagon:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    i*86:Linux:*:*)+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}+	exit ;;+    ia64:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    k1om:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    m32r*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    m68*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    mips:Linux:*:* | mips64:Linux:*:*)+	eval $set_cc_for_build+	sed 's/^	//' << EOF >$dummy.c+	#undef CPU+	#undef ${UNAME_MACHINE}+	#undef ${UNAME_MACHINE}el+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)+	CPU=${UNAME_MACHINE}el+	#else+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)+	CPU=${UNAME_MACHINE}+	#else+	CPU=+	#endif+	#endif+EOF+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }+	;;+    mips64el:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    openrisc*:Linux:*:*)+	echo or1k-unknown-linux-${LIBC}+	exit ;;+    or32:Linux:*:* | or1k*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    padre:Linux:*:*)+	echo sparc-unknown-linux-${LIBC}+	exit ;;+    parisc64:Linux:*:* | hppa64:Linux:*:*)+	echo hppa64-unknown-linux-${LIBC}+	exit ;;+    parisc:Linux:*:* | hppa:Linux:*:*)+	# Look for CPU level+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;+	  *)    echo hppa-unknown-linux-${LIBC} ;;+	esac+	exit ;;+    ppc64:Linux:*:*)+	echo powerpc64-unknown-linux-${LIBC}+	exit ;;+    ppc:Linux:*:*)+	echo powerpc-unknown-linux-${LIBC}+	exit ;;+    ppc64le:Linux:*:*)+	echo powerpc64le-unknown-linux-${LIBC}+	exit ;;+    ppcle:Linux:*:*)+	echo powerpcle-unknown-linux-${LIBC}+	exit ;;+    riscv32:Linux:*:* | riscv64:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    s390:Linux:*:* | s390x:Linux:*:*)+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}+	exit ;;+    sh64*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    sh*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    sparc:Linux:*:* | sparc64:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    tile*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    vax:Linux:*:*)+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}+	exit ;;+    x86_64:Linux:*:*)+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}+	exit ;;+    xtensa*:Linux:*:*)+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}+	exit ;;+    i*86:DYNIX/ptx:4*:*)+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.+	# earlier versions are messed up and put the nodename in both+	# sysname and nodename.+	echo i386-sequent-sysv4+	exit ;;+    i*86:UNIX_SV:4.2MP:2.*)+	# Unixware is an offshoot of SVR4, but it has its own version+	# number series starting with 2...+	# I am not positive that other SVR4 systems won't match this,+	# I just have to hope.  -- rms.+	# Use sysv4.2uw... so that sysv4* matches it.+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}+	exit ;;+    i*86:OS/2:*:*)+	# If we were able to find `uname', then EMX Unix compatibility+	# is probably installed.+	echo ${UNAME_MACHINE}-pc-os2-emx+	exit ;;+    i*86:XTS-300:*:STOP)+	echo ${UNAME_MACHINE}-unknown-stop+	exit ;;+    i*86:atheos:*:*)+	echo ${UNAME_MACHINE}-unknown-atheos+	exit ;;+    i*86:syllable:*:*)+	echo ${UNAME_MACHINE}-pc-syllable+	exit ;;+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)+	echo i386-unknown-lynxos${UNAME_RELEASE}+	exit ;;+    i*86:*DOS:*:*)+	echo ${UNAME_MACHINE}-pc-msdosdjgpp+	exit ;;+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}+	else+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}+	fi+	exit ;;+    i*86:*:5:[678]*)+	# UnixWare 7.x, OpenUNIX and OpenServer 6.+	case `/bin/uname -X | grep "^Machine"` in+	    *486*)	     UNAME_MACHINE=i486 ;;+	    *Pentium)	     UNAME_MACHINE=i586 ;;+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;+	esac+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}+	exit ;;+    i*86:*:3.2:*)+	if test -f /usr/options/cb.name; then+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL+	elif /bin/uname -X 2>/dev/null >/dev/null ; then+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \+			&& UNAME_MACHINE=i586+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \+			&& UNAME_MACHINE=i686+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \+			&& UNAME_MACHINE=i686+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL+	else+		echo ${UNAME_MACHINE}-pc-sysv32+	fi+	exit ;;+    pc:*:*:*)+	# Left here for compatibility:+	# uname -m prints for DJGPP always 'pc', but it prints nothing about+	# the processor, so we play safe by assuming i586.+	# Note: whatever this is, it MUST be the same as what config.sub+	# prints for the "djgpp" host, or else GDB configure will decide that+	# this is a cross-build.+	echo i586-pc-msdosdjgpp+	exit ;;+    Intel:Mach:3*:*)+	echo i386-pc-mach3+	exit ;;+    paragon:*:*:*)+	echo i860-intel-osf1+	exit ;;+    i860:*:4.*:*) # i860-SVR4+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4+	else # Add other i860-SVR4 vendors below as they are discovered.+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4+	fi+	exit ;;+    mini*:CTIX:SYS*5:*)+	# "miniframe"+	echo m68010-convergent-sysv+	exit ;;+    mc68k:UNIX:SYSTEM5:3.51m)+	echo m68k-convergent-sysv+	exit ;;+    M680?0:D-NIX:5.3:*)+	echo m68k-diab-dnix+	exit ;;+    M68*:*:R3V[5678]*:*)+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)+	OS_REL=''+	test -r /etc/.relid \+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \+	  && { echo i486-ncr-sysv4; exit; } ;;+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)+	OS_REL='.3'+	test -r /etc/.relid \+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)+	echo m68k-unknown-lynxos${UNAME_RELEASE}+	exit ;;+    mc68030:UNIX_System_V:4.*:*)+	echo m68k-atari-sysv4+	exit ;;+    TSUNAMI:LynxOS:2.*:*)+	echo sparc-unknown-lynxos${UNAME_RELEASE}+	exit ;;+    rs6000:LynxOS:2.*:*)+	echo rs6000-unknown-lynxos${UNAME_RELEASE}+	exit ;;+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)+	echo powerpc-unknown-lynxos${UNAME_RELEASE}+	exit ;;+    SM[BE]S:UNIX_SV:*:*)+	echo mips-dde-sysv${UNAME_RELEASE}+	exit ;;+    RM*:ReliantUNIX-*:*:*)+	echo mips-sni-sysv4+	exit ;;+    RM*:SINIX-*:*:*)+	echo mips-sni-sysv4+	exit ;;+    *:SINIX-*:*:*)+	if uname -p 2>/dev/null >/dev/null ; then+		UNAME_MACHINE=`(uname -p) 2>/dev/null`+		echo ${UNAME_MACHINE}-sni-sysv4+	else+		echo ns32k-sni-sysv+	fi+	exit ;;+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort+			# says <Richard.M.Bartel@ccMail.Census.GOV>+	echo i586-unisys-sysv4+	exit ;;+    *:UNIX_System_V:4*:FTX*)+	# From Gerald Hewes <hewes@openmarket.com>.+	# How about differentiating between stratus architectures? -djm+	echo hppa1.1-stratus-sysv4+	exit ;;+    *:*:*:FTX*)+	# From seanf@swdc.stratus.com.+	echo i860-stratus-sysv4+	exit ;;+    i*86:VOS:*:*)+	# From Paul.Green@stratus.com.+	echo ${UNAME_MACHINE}-stratus-vos+	exit ;;+    *:VOS:*:*)+	# From Paul.Green@stratus.com.+	echo hppa1.1-stratus-vos+	exit ;;+    mc68*:A/UX:*:*)+	echo m68k-apple-aux${UNAME_RELEASE}+	exit ;;+    news*:NEWS-OS:6*:*)+	echo mips-sony-newsos6+	exit ;;+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)+	if [ -d /usr/nec ]; then+		echo mips-nec-sysv${UNAME_RELEASE}+	else+		echo mips-unknown-sysv${UNAME_RELEASE}+	fi+	exit ;;+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.+	echo powerpc-be-beos+	exit ;;+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.+	echo powerpc-apple-beos+	exit ;;+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.+	echo i586-pc-beos+	exit ;;+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.+	echo i586-pc-haiku+	exit ;;+    x86_64:Haiku:*:*)+	echo x86_64-unknown-haiku+	exit ;;+    SX-4:SUPER-UX:*:*)+	echo sx4-nec-superux${UNAME_RELEASE}+	exit ;;+    SX-5:SUPER-UX:*:*)+	echo sx5-nec-superux${UNAME_RELEASE}+	exit ;;+    SX-6:SUPER-UX:*:*)+	echo sx6-nec-superux${UNAME_RELEASE}+	exit ;;+    SX-7:SUPER-UX:*:*)+	echo sx7-nec-superux${UNAME_RELEASE}+	exit ;;+    SX-8:SUPER-UX:*:*)+	echo sx8-nec-superux${UNAME_RELEASE}+	exit ;;+    SX-8R:SUPER-UX:*:*)+	echo sx8r-nec-superux${UNAME_RELEASE}+	exit ;;+    SX-ACE:SUPER-UX:*:*)+	echo sxace-nec-superux${UNAME_RELEASE}+	exit ;;+    Power*:Rhapsody:*:*)+	echo powerpc-apple-rhapsody${UNAME_RELEASE}+	exit ;;+    *:Rhapsody:*:*)+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}+	exit ;;+    *:Darwin:*:*)+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown+	eval $set_cc_for_build+	if test "$UNAME_PROCESSOR" = unknown ; then+	    UNAME_PROCESSOR=powerpc+	fi+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then+	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \+		    (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \+		    grep IS_64BIT_ARCH >/dev/null+		then+		    case $UNAME_PROCESSOR in+			i386) UNAME_PROCESSOR=x86_64 ;;+			powerpc) UNAME_PROCESSOR=powerpc64 ;;+		    esac+		fi+	    fi+	elif test "$UNAME_PROCESSOR" = i386 ; then+	    # Avoid executing cc on OS X 10.9, as it ships with a stub+	    # that puts up a graphical alert prompting to install+	    # developer tools.  Any system running Mac OS X 10.7 or+	    # later (Darwin 11 and later) is required to have a 64-bit+	    # processor. This is not true of the ARM version of Darwin+	    # that Apple uses in portable devices.+	    UNAME_PROCESSOR=x86_64+	fi+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}+	exit ;;+    *:procnto*:*:* | *:QNX:[0123456789]*:*)+	UNAME_PROCESSOR=`uname -p`+	if test "$UNAME_PROCESSOR" = x86; then+		UNAME_PROCESSOR=i386+		UNAME_MACHINE=pc+	fi+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}+	exit ;;+    *:QNX:*:4*)+	echo i386-pc-qnx+	exit ;;+    NEO-?:NONSTOP_KERNEL:*:*)+	echo neo-tandem-nsk${UNAME_RELEASE}+	exit ;;+    NSE-*:NONSTOP_KERNEL:*:*)+	echo nse-tandem-nsk${UNAME_RELEASE}+	exit ;;+    NSR-?:NONSTOP_KERNEL:*:*)+	echo nsr-tandem-nsk${UNAME_RELEASE}+	exit ;;+    NSX-?:NONSTOP_KERNEL:*:*)+	echo nsx-tandem-nsk${UNAME_RELEASE}+	exit ;;+    *:NonStop-UX:*:*)+	echo mips-compaq-nonstopux+	exit ;;+    BS2000:POSIX*:*:*)+	echo bs2000-siemens-sysv+	exit ;;+    DS/*:UNIX_System_V:*:*)+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}+	exit ;;+    *:Plan9:*:*)+	# "uname -m" is not consistent, so use $cputype instead. 386+	# is converted to i386 for consistency with other x86+	# operating systems.+	if test "$cputype" = 386; then+	    UNAME_MACHINE=i386+	else+	    UNAME_MACHINE="$cputype"+	fi+	echo ${UNAME_MACHINE}-unknown-plan9+	exit ;;+    *:TOPS-10:*:*)+	echo pdp10-unknown-tops10+	exit ;;+    *:TENEX:*:*)+	echo pdp10-unknown-tenex+	exit ;;+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)+	echo pdp10-dec-tops20+	exit ;;+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)+	echo pdp10-xkl-tops20+	exit ;;+    *:TOPS-20:*:*)+	echo pdp10-unknown-tops20+	exit ;;+    *:ITS:*:*)+	echo pdp10-unknown-its+	exit ;;+    SEI:*:*:SEIUX)+	echo mips-sei-seiux${UNAME_RELEASE}+	exit ;;+    *:DragonFly:*:*)+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`+	exit ;;+    *:*VMS:*:*)+	UNAME_MACHINE=`(uname -p) 2>/dev/null`+	case "${UNAME_MACHINE}" in+	    A*) echo alpha-dec-vms ; exit ;;+	    I*) echo ia64-dec-vms ; exit ;;+	    V*) echo vax-dec-vms ; exit ;;+	esac ;;+    *:XENIX:*:SysV)+	echo i386-pc-xenix+	exit ;;+    i*86:skyos:*:*)+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`+	exit ;;+    i*86:rdos:*:*)+	echo ${UNAME_MACHINE}-pc-rdos+	exit ;;+    i*86:AROS:*:*)+	echo ${UNAME_MACHINE}-pc-aros+	exit ;;+    x86_64:VMkernel:*:*)+	echo ${UNAME_MACHINE}-unknown-esx+	exit ;;+    amd64:Isilon\ OneFS:*:*)+	echo x86_64-unknown-onefs+	exit ;;+esac++cat >&2 <<EOF+$0: unable to guess system type++This script (version $timestamp), has failed to recognize the+operating system you are using. If your script is old, overwrite+config.guess and config.sub with the latest versions from:++  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess+and+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub++If $0 has already been updated, send the following data and any+information you think might be pertinent to config-patches@gnu.org to+provide the necessary information to handle your system.++config.guess timestamp = $timestamp++uname -m = `(uname -m) 2>/dev/null || echo unknown`+uname -r = `(uname -r) 2>/dev/null || echo unknown`+uname -s = `(uname -s) 2>/dev/null || echo unknown`+uname -v = `(uname -v) 2>/dev/null || echo unknown`++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`++hostinfo               = `(hostinfo) 2>/dev/null`+/bin/universe          = `(/bin/universe) 2>/dev/null`+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`+/bin/arch              = `(/bin/arch) 2>/dev/null`+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`++UNAME_MACHINE = ${UNAME_MACHINE}+UNAME_RELEASE = ${UNAME_RELEASE}+UNAME_SYSTEM  = ${UNAME_SYSTEM}+UNAME_VERSION = ${UNAME_VERSION}+EOF++exit 1++# Local variables:+# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'"
config.sub view
@@ -1,1859 +1,1835 @@ #! /bin/sh # Configuration validation subroutine script.-#   Copyright 1992-2021 Free Software Foundation, Inc.--timestamp='2021-01-08'--# This file is free software; you can redistribute it and/or modify it-# under the terms of the GNU General Public License as published by-# the Free Software Foundation; either version 3 of the License, or-# (at your option) any later version.-#-# This program is distributed in the hope that it will be useful, but-# WITHOUT ANY WARRANTY; without even the implied warranty of-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU-# General Public License for more details.-#-# You should have received a copy of the GNU General Public License-# along with this program; if not, see <https://www.gnu.org/licenses/>.-#-# As a special exception to the GNU General Public License, if you-# distribute this file as part of a program that contains a-# configuration script generated by Autoconf, you may include it under-# the same distribution terms that you use for the rest of that-# program.  This Exception is an additional permission under section 7-# of the GNU General Public License, version 3 ("GPLv3").---# Please send patches to <config-patches@gnu.org>.-#-# Configuration subroutine to validate and canonicalize a configuration type.-# Supply the specified configuration type as an argument.-# If it is invalid, we print an error message on stderr and exit with code 1.-# Otherwise, we print the canonical config type on stdout and succeed.--# You can get the latest version of this script from:-# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub--# This file is supposed to be the same for all GNU packages-# and recognize all the CPU types, system types and aliases-# that are meaningful with *any* GNU software.-# Each package is responsible for reporting which valid configurations-# it does not support.  The user should be able to distinguish-# a failure to support a valid configuration from a meaningless-# configuration.--# The goal of this file is to map all the various variations of a given-# machine specification into a single specification in the form:-#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM-# or in some cases, the newer four-part form:-#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM-# It is wrong to echo any other type of specification.--me=$(echo "$0" | sed -e 's,.*/,,')--usage="\-Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS--Canonicalize a configuration name.--Options:-  -h, --help         print this help, then exit-  -t, --time-stamp   print date of last modification, then exit-  -v, --version      print version number, then exit--Report bugs and patches to <config-patches@gnu.org>."--version="\-GNU config.sub ($timestamp)--Copyright 1992-2021 Free Software Foundation, Inc.--This is free software; see the source for copying conditions.  There is NO-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."--help="-Try \`$me --help' for more information."--# Parse command line-while test $# -gt 0 ; do-  case $1 in-    --time-stamp | --time* | -t )-       echo "$timestamp" ; exit ;;-    --version | -v )-       echo "$version" ; exit ;;-    --help | --h* | -h )-       echo "$usage"; exit ;;-    -- )     # Stop option processing-       shift; break ;;-    - )	# Use stdin as input.-       break ;;-    -* )-       echo "$me: invalid option $1$help" >&2-       exit 1 ;;--    *local*)-       # First pass through any local machine types.-       echo "$1"-       exit ;;--    * )-       break ;;-  esac-done--case $# in- 0) echo "$me: missing argument$help" >&2-    exit 1;;- 1) ;;- *) echo "$me: too many arguments$help" >&2-    exit 1;;-esac--# Split fields of configuration type-# shellcheck disable=SC2162-IFS="-" read field1 field2 field3 field4 <<EOF-$1-EOF--# Separate into logical components for further validation-case $1 in-	*-*-*-*-*)-		echo Invalid configuration \`"$1"\': more than four components >&2-		exit 1-		;;-	*-*-*-*)-		basic_machine=$field1-$field2-		basic_os=$field3-$field4-		;;-	*-*-*)-		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two-		# parts-		maybe_os=$field2-$field3-		case $maybe_os in-			nto-qnx* | linux-* | uclinux-uclibc* \-			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \-			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \-			| storm-chaos* | os2-emx* | rtmk-nova*)-				basic_machine=$field1-				basic_os=$maybe_os-				;;-			android-linux)-				basic_machine=$field1-unknown-				basic_os=linux-android-				;;-			*)-				basic_machine=$field1-$field2-				basic_os=$field3-				;;-		esac-		;;-	*-*)-		# A lone config we happen to match not fitting any pattern-		case $field1-$field2 in-			decstation-3100)-				basic_machine=mips-dec-				basic_os=-				;;-			*-*)-				# Second component is usually, but not always the OS-				case $field2 in-					# Prevent following clause from handling this valid os-					sun*os*)-						basic_machine=$field1-						basic_os=$field2-						;;-					# Manufacturers-					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \-					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \-					| unicom* | ibm* | next | hp | isi* | apollo | altos* \-					| convergent* | ncr* | news | 32* | 3600* | 3100* \-					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \-					| ultra | tti* | harris | dolphin | highlevel | gould \-					| cbm | ns | masscomp | apple | axis | knuth | cray \-					| microblaze* | sim | cisco \-					| oki | wec | wrs | winbond)-						basic_machine=$field1-$field2-						basic_os=-						;;-					*)-						basic_machine=$field1-						basic_os=$field2-						;;-				esac-			;;-		esac-		;;-	*)-		# Convert single-component short-hands not valid as part of-		# multi-component configurations.-		case $field1 in-			386bsd)-				basic_machine=i386-pc-				basic_os=bsd-				;;-			a29khif)-				basic_machine=a29k-amd-				basic_os=udi-				;;-			adobe68k)-				basic_machine=m68010-adobe-				basic_os=scout-				;;-			alliant)-				basic_machine=fx80-alliant-				basic_os=-				;;-			altos | altos3068)-				basic_machine=m68k-altos-				basic_os=-				;;-			am29k)-				basic_machine=a29k-none-				basic_os=bsd-				;;-			amdahl)-				basic_machine=580-amdahl-				basic_os=sysv-				;;-			amiga)-				basic_machine=m68k-unknown-				basic_os=-				;;-			amigaos | amigados)-				basic_machine=m68k-unknown-				basic_os=amigaos-				;;-			amigaunix | amix)-				basic_machine=m68k-unknown-				basic_os=sysv4-				;;-			apollo68)-				basic_machine=m68k-apollo-				basic_os=sysv-				;;-			apollo68bsd)-				basic_machine=m68k-apollo-				basic_os=bsd-				;;-			aros)-				basic_machine=i386-pc-				basic_os=aros-				;;-			aux)-				basic_machine=m68k-apple-				basic_os=aux-				;;-			balance)-				basic_machine=ns32k-sequent-				basic_os=dynix-				;;-			blackfin)-				basic_machine=bfin-unknown-				basic_os=linux-				;;-			cegcc)-				basic_machine=arm-unknown-				basic_os=cegcc-				;;-			convex-c1)-				basic_machine=c1-convex-				basic_os=bsd-				;;-			convex-c2)-				basic_machine=c2-convex-				basic_os=bsd-				;;-			convex-c32)-				basic_machine=c32-convex-				basic_os=bsd-				;;-			convex-c34)-				basic_machine=c34-convex-				basic_os=bsd-				;;-			convex-c38)-				basic_machine=c38-convex-				basic_os=bsd-				;;-			cray)-				basic_machine=j90-cray-				basic_os=unicos-				;;-			crds | unos)-				basic_machine=m68k-crds-				basic_os=-				;;-			da30)-				basic_machine=m68k-da30-				basic_os=-				;;-			decstation | pmax | pmin | dec3100 | decstatn)-				basic_machine=mips-dec-				basic_os=-				;;-			delta88)-				basic_machine=m88k-motorola-				basic_os=sysv3-				;;-			dicos)-				basic_machine=i686-pc-				basic_os=dicos-				;;-			djgpp)-				basic_machine=i586-pc-				basic_os=msdosdjgpp-				;;-			ebmon29k)-				basic_machine=a29k-amd-				basic_os=ebmon-				;;-			es1800 | OSE68k | ose68k | ose | OSE)-				basic_machine=m68k-ericsson-				basic_os=ose-				;;-			gmicro)-				basic_machine=tron-gmicro-				basic_os=sysv-				;;-			go32)-				basic_machine=i386-pc-				basic_os=go32-				;;-			h8300hms)-				basic_machine=h8300-hitachi-				basic_os=hms-				;;-			h8300xray)-				basic_machine=h8300-hitachi-				basic_os=xray-				;;-			h8500hms)-				basic_machine=h8500-hitachi-				basic_os=hms-				;;-			harris)-				basic_machine=m88k-harris-				basic_os=sysv3-				;;-			hp300 | hp300hpux)-				basic_machine=m68k-hp-				basic_os=hpux-				;;-			hp300bsd)-				basic_machine=m68k-hp-				basic_os=bsd-				;;-			hppaosf)-				basic_machine=hppa1.1-hp-				basic_os=osf-				;;-			hppro)-				basic_machine=hppa1.1-hp-				basic_os=proelf-				;;-			i386mach)-				basic_machine=i386-mach-				basic_os=mach-				;;-			isi68 | isi)-				basic_machine=m68k-isi-				basic_os=sysv-				;;-			m68knommu)-				basic_machine=m68k-unknown-				basic_os=linux-				;;-			magnum | m3230)-				basic_machine=mips-mips-				basic_os=sysv-				;;-			merlin)-				basic_machine=ns32k-utek-				basic_os=sysv-				;;-			mingw64)-				basic_machine=x86_64-pc-				basic_os=mingw64-				;;-			mingw32)-				basic_machine=i686-pc-				basic_os=mingw32-				;;-			mingw32ce)-				basic_machine=arm-unknown-				basic_os=mingw32ce-				;;-			monitor)-				basic_machine=m68k-rom68k-				basic_os=coff-				;;-			morphos)-				basic_machine=powerpc-unknown-				basic_os=morphos-				;;-			moxiebox)-				basic_machine=moxie-unknown-				basic_os=moxiebox-				;;-			msdos)-				basic_machine=i386-pc-				basic_os=msdos-				;;-			msys)-				basic_machine=i686-pc-				basic_os=msys-				;;-			mvs)-				basic_machine=i370-ibm-				basic_os=mvs-				;;-			nacl)-				basic_machine=le32-unknown-				basic_os=nacl-				;;-			ncr3000)-				basic_machine=i486-ncr-				basic_os=sysv4-				;;-			netbsd386)-				basic_machine=i386-pc-				basic_os=netbsd-				;;-			netwinder)-				basic_machine=armv4l-rebel-				basic_os=linux-				;;-			news | news700 | news800 | news900)-				basic_machine=m68k-sony-				basic_os=newsos-				;;-			news1000)-				basic_machine=m68030-sony-				basic_os=newsos-				;;-			necv70)-				basic_machine=v70-nec-				basic_os=sysv-				;;-			nh3000)-				basic_machine=m68k-harris-				basic_os=cxux-				;;-			nh[45]000)-				basic_machine=m88k-harris-				basic_os=cxux-				;;-			nindy960)-				basic_machine=i960-intel-				basic_os=nindy-				;;-			mon960)-				basic_machine=i960-intel-				basic_os=mon960-				;;-			nonstopux)-				basic_machine=mips-compaq-				basic_os=nonstopux-				;;-			os400)-				basic_machine=powerpc-ibm-				basic_os=os400-				;;-			OSE68000 | ose68000)-				basic_machine=m68000-ericsson-				basic_os=ose-				;;-			os68k)-				basic_machine=m68k-none-				basic_os=os68k-				;;-			paragon)-				basic_machine=i860-intel-				basic_os=osf-				;;-			parisc)-				basic_machine=hppa-unknown-				basic_os=linux-				;;-			psp)-				basic_machine=mipsallegrexel-sony-				basic_os=psp-				;;-			pw32)-				basic_machine=i586-unknown-				basic_os=pw32-				;;-			rdos | rdos64)-				basic_machine=x86_64-pc-				basic_os=rdos-				;;-			rdos32)-				basic_machine=i386-pc-				basic_os=rdos-				;;-			rom68k)-				basic_machine=m68k-rom68k-				basic_os=coff-				;;-			sa29200)-				basic_machine=a29k-amd-				basic_os=udi-				;;-			sei)-				basic_machine=mips-sei-				basic_os=seiux-				;;-			sequent)-				basic_machine=i386-sequent-				basic_os=-				;;-			sps7)-				basic_machine=m68k-bull-				basic_os=sysv2-				;;-			st2000)-				basic_machine=m68k-tandem-				basic_os=-				;;-			stratus)-				basic_machine=i860-stratus-				basic_os=sysv4-				;;-			sun2)-				basic_machine=m68000-sun-				basic_os=-				;;-			sun2os3)-				basic_machine=m68000-sun-				basic_os=sunos3-				;;-			sun2os4)-				basic_machine=m68000-sun-				basic_os=sunos4-				;;-			sun3)-				basic_machine=m68k-sun-				basic_os=-				;;-			sun3os3)-				basic_machine=m68k-sun-				basic_os=sunos3-				;;-			sun3os4)-				basic_machine=m68k-sun-				basic_os=sunos4-				;;-			sun4)-				basic_machine=sparc-sun-				basic_os=-				;;-			sun4os3)-				basic_machine=sparc-sun-				basic_os=sunos3-				;;-			sun4os4)-				basic_machine=sparc-sun-				basic_os=sunos4-				;;-			sun4sol2)-				basic_machine=sparc-sun-				basic_os=solaris2-				;;-			sun386 | sun386i | roadrunner)-				basic_machine=i386-sun-				basic_os=-				;;-			sv1)-				basic_machine=sv1-cray-				basic_os=unicos-				;;-			symmetry)-				basic_machine=i386-sequent-				basic_os=dynix-				;;-			t3e)-				basic_machine=alphaev5-cray-				basic_os=unicos-				;;-			t90)-				basic_machine=t90-cray-				basic_os=unicos-				;;-			toad1)-				basic_machine=pdp10-xkl-				basic_os=tops20-				;;-			tpf)-				basic_machine=s390x-ibm-				basic_os=tpf-				;;-			udi29k)-				basic_machine=a29k-amd-				basic_os=udi-				;;-			ultra3)-				basic_machine=a29k-nyu-				basic_os=sym1-				;;-			v810 | necv810)-				basic_machine=v810-nec-				basic_os=none-				;;-			vaxv)-				basic_machine=vax-dec-				basic_os=sysv-				;;-			vms)-				basic_machine=vax-dec-				basic_os=vms-				;;-			vsta)-				basic_machine=i386-pc-				basic_os=vsta-				;;-			vxworks960)-				basic_machine=i960-wrs-				basic_os=vxworks-				;;-			vxworks68)-				basic_machine=m68k-wrs-				basic_os=vxworks-				;;-			vxworks29k)-				basic_machine=a29k-wrs-				basic_os=vxworks-				;;-			xbox)-				basic_machine=i686-pc-				basic_os=mingw32-				;;-			ymp)-				basic_machine=ymp-cray-				basic_os=unicos-				;;-			*)-				basic_machine=$1-				basic_os=-				;;-		esac-		;;-esac--# Decode 1-component or ad-hoc basic machines-case $basic_machine in-	# Here we handle the default manufacturer of certain CPU types.  It is in-	# some cases the only manufacturer, in others, it is the most popular.-	w89k)-		cpu=hppa1.1-		vendor=winbond-		;;-	op50n)-		cpu=hppa1.1-		vendor=oki-		;;-	op60c)-		cpu=hppa1.1-		vendor=oki-		;;-	ibm*)-		cpu=i370-		vendor=ibm-		;;-	orion105)-		cpu=clipper-		vendor=highlevel-		;;-	mac | mpw | mac-mpw)-		cpu=m68k-		vendor=apple-		;;-	pmac | pmac-mpw)-		cpu=powerpc-		vendor=apple-		;;--	# Recognize the various machine names and aliases which stand-	# for a CPU type and a company and sometimes even an OS.-	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)-		cpu=m68000-		vendor=att-		;;-	3b*)-		cpu=we32k-		vendor=att-		;;-	bluegene*)-		cpu=powerpc-		vendor=ibm-		basic_os=cnk-		;;-	decsystem10* | dec10*)-		cpu=pdp10-		vendor=dec-		basic_os=tops10-		;;-	decsystem20* | dec20*)-		cpu=pdp10-		vendor=dec-		basic_os=tops20-		;;-	delta | 3300 | motorola-3300 | motorola-delta \-	      | 3300-motorola | delta-motorola)-		cpu=m68k-		vendor=motorola-		;;-	dpx2*)-		cpu=m68k-		vendor=bull-		basic_os=sysv3-		;;-	encore | umax | mmax)-		cpu=ns32k-		vendor=encore-		;;-	elxsi)-		cpu=elxsi-		vendor=elxsi-		basic_os=${basic_os:-bsd}-		;;-	fx2800)-		cpu=i860-		vendor=alliant-		;;-	genix)-		cpu=ns32k-		vendor=ns-		;;-	h3050r* | hiux*)-		cpu=hppa1.1-		vendor=hitachi-		basic_os=hiuxwe2-		;;-	hp3k9[0-9][0-9] | hp9[0-9][0-9])-		cpu=hppa1.0-		vendor=hp-		;;-	hp9k2[0-9][0-9] | hp9k31[0-9])-		cpu=m68000-		vendor=hp-		;;-	hp9k3[2-9][0-9])-		cpu=m68k-		vendor=hp-		;;-	hp9k6[0-9][0-9] | hp6[0-9][0-9])-		cpu=hppa1.0-		vendor=hp-		;;-	hp9k7[0-79][0-9] | hp7[0-79][0-9])-		cpu=hppa1.1-		vendor=hp-		;;-	hp9k78[0-9] | hp78[0-9])-		# FIXME: really hppa2.0-hp-		cpu=hppa1.1-		vendor=hp-		;;-	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)-		# FIXME: really hppa2.0-hp-		cpu=hppa1.1-		vendor=hp-		;;-	hp9k8[0-9][13679] | hp8[0-9][13679])-		cpu=hppa1.1-		vendor=hp-		;;-	hp9k8[0-9][0-9] | hp8[0-9][0-9])-		cpu=hppa1.0-		vendor=hp-		;;-	i*86v32)-		cpu=$(echo "$1" | sed -e 's/86.*/86/')-		vendor=pc-		basic_os=sysv32-		;;-	i*86v4*)-		cpu=$(echo "$1" | sed -e 's/86.*/86/')-		vendor=pc-		basic_os=sysv4-		;;-	i*86v)-		cpu=$(echo "$1" | sed -e 's/86.*/86/')-		vendor=pc-		basic_os=sysv-		;;-	i*86sol2)-		cpu=$(echo "$1" | sed -e 's/86.*/86/')-		vendor=pc-		basic_os=solaris2-		;;-	j90 | j90-cray)-		cpu=j90-		vendor=cray-		basic_os=${basic_os:-unicos}-		;;-	iris | iris4d)-		cpu=mips-		vendor=sgi-		case $basic_os in-		    irix*)-			;;-		    *)-			basic_os=irix4-			;;-		esac-		;;-	miniframe)-		cpu=m68000-		vendor=convergent-		;;-	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)-		cpu=m68k-		vendor=atari-		basic_os=mint-		;;-	news-3600 | risc-news)-		cpu=mips-		vendor=sony-		basic_os=newsos-		;;-	next | m*-next)-		cpu=m68k-		vendor=next-		case $basic_os in-		    openstep*)-		        ;;-		    nextstep*)-			;;-		    ns2*)-		      basic_os=nextstep2-			;;-		    *)-		      basic_os=nextstep3-			;;-		esac-		;;-	np1)-		cpu=np1-		vendor=gould-		;;-	op50n-* | op60c-*)-		cpu=hppa1.1-		vendor=oki-		basic_os=proelf-		;;-	pa-hitachi)-		cpu=hppa1.1-		vendor=hitachi-		basic_os=hiuxwe2-		;;-	pbd)-		cpu=sparc-		vendor=tti-		;;-	pbb)-		cpu=m68k-		vendor=tti-		;;-	pc532)-		cpu=ns32k-		vendor=pc532-		;;-	pn)-		cpu=pn-		vendor=gould-		;;-	power)-		cpu=power-		vendor=ibm-		;;-	ps2)-		cpu=i386-		vendor=ibm-		;;-	rm[46]00)-		cpu=mips-		vendor=siemens-		;;-	rtpc | rtpc-*)-		cpu=romp-		vendor=ibm-		;;-	sde)-		cpu=mipsisa32-		vendor=sde-		basic_os=${basic_os:-elf}-		;;-	simso-wrs)-		cpu=sparclite-		vendor=wrs-		basic_os=vxworks-		;;-	tower | tower-32)-		cpu=m68k-		vendor=ncr-		;;-	vpp*|vx|vx-*)-		cpu=f301-		vendor=fujitsu-		;;-	w65)-		cpu=w65-		vendor=wdc-		;;-	w89k-*)-		cpu=hppa1.1-		vendor=winbond-		basic_os=proelf-		;;-	none)-		cpu=none-		vendor=none-		;;-	leon|leon[3-9])-		cpu=sparc-		vendor=$basic_machine-		;;-	leon-*|leon[3-9]-*)-		cpu=sparc-		vendor=$(echo "$basic_machine" | sed 's/-.*//')-		;;--	*-*)-		# shellcheck disable=SC2162-		IFS="-" read cpu vendor <<EOF-$basic_machine-EOF-		;;-	# We use `pc' rather than `unknown'-	# because (1) that's what they normally are, and-	# (2) the word "unknown" tends to confuse beginning users.-	i*86 | x86_64)-		cpu=$basic_machine-		vendor=pc-		;;-	# These rules are duplicated from below for sake of the special case above;-	# i.e. things that normalized to x86 arches should also default to "pc"-	pc98)-		cpu=i386-		vendor=pc-		;;-	x64 | amd64)-		cpu=x86_64-		vendor=pc-		;;-	# Recognize the basic CPU types without company name.-	*)-		cpu=$basic_machine-		vendor=unknown-		;;-esac--unset -v basic_machine--# Decode basic machines in the full and proper CPU-Company form.-case $cpu-$vendor in-	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in-	# some cases the only manufacturer, in others, it is the most popular.-	craynv-unknown)-		vendor=cray-		basic_os=${basic_os:-unicosmp}-		;;-	c90-unknown | c90-cray)-		vendor=cray-		basic_os=${Basic_os:-unicos}-		;;-	fx80-unknown)-		vendor=alliant-		;;-	romp-unknown)-		vendor=ibm-		;;-	mmix-unknown)-		vendor=knuth-		;;-	microblaze-unknown | microblazeel-unknown)-		vendor=xilinx-		;;-	rs6000-unknown)-		vendor=ibm-		;;-	vax-unknown)-		vendor=dec-		;;-	pdp11-unknown)-		vendor=dec-		;;-	we32k-unknown)-		vendor=att-		;;-	cydra-unknown)-		vendor=cydrome-		;;-	i370-ibm*)-		vendor=ibm-		;;-	orion-unknown)-		vendor=highlevel-		;;-	xps-unknown | xps100-unknown)-		cpu=xps100-		vendor=honeywell-		;;--	# Here we normalize CPU types with a missing or matching vendor-	dpx20-unknown | dpx20-bull)-		cpu=rs6000-		vendor=bull-		basic_os=${basic_os:-bosx}-		;;--	# Here we normalize CPU types irrespective of the vendor-	amd64-*)-		cpu=x86_64-		;;-	blackfin-*)-		cpu=bfin-		basic_os=linux-		;;-	c54x-*)-		cpu=tic54x-		;;-	c55x-*)-		cpu=tic55x-		;;-	c6x-*)-		cpu=tic6x-		;;-	e500v[12]-*)-		cpu=powerpc-		basic_os=${basic_os}"spe"-		;;-	mips3*-*)-		cpu=mips64-		;;-	ms1-*)-		cpu=mt-		;;-	m68knommu-*)-		cpu=m68k-		basic_os=linux-		;;-	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)-		cpu=s12z-		;;-	openrisc-*)-		cpu=or32-		;;-	parisc-*)-		cpu=hppa-		basic_os=linux-		;;-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)-		cpu=i586-		;;-	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)-		cpu=i686-		;;-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)-		cpu=i686-		;;-	pentium4-*)-		cpu=i786-		;;-	pc98-*)-		cpu=i386-		;;-	ppc-* | ppcbe-*)-		cpu=powerpc-		;;-	ppcle-* | powerpclittle-*)-		cpu=powerpcle-		;;-	ppc64-*)-		cpu=powerpc64-		;;-	ppc64le-* | powerpc64little-*)-		cpu=powerpc64le-		;;-	sb1-*)-		cpu=mipsisa64sb1-		;;-	sb1el-*)-		cpu=mipsisa64sb1el-		;;-	sh5e[lb]-*)-		cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')-		;;-	spur-*)-		cpu=spur-		;;-	strongarm-* | thumb-*)-		cpu=arm-		;;-	tx39-*)-		cpu=mipstx39-		;;-	tx39el-*)-		cpu=mipstx39el-		;;-	x64-*)-		cpu=x86_64-		;;-	xscale-* | xscalee[bl]-*)-		cpu=$(echo "$cpu" | sed 's/^xscale/arm/')-		;;-	arm64-*)-		cpu=aarch64-		;;--	# Recognize the canonical CPU Types that limit and/or modify the-	# company names they are paired with.-	cr16-*)-		basic_os=${basic_os:-elf}-		;;-	crisv32-* | etraxfs*-*)-		cpu=crisv32-		vendor=axis-		;;-	cris-* | etrax*-*)-		cpu=cris-		vendor=axis-		;;-	crx-*)-		basic_os=${basic_os:-elf}-		;;-	neo-tandem)-		cpu=neo-		vendor=tandem-		;;-	nse-tandem)-		cpu=nse-		vendor=tandem-		;;-	nsr-tandem)-		cpu=nsr-		vendor=tandem-		;;-	nsv-tandem)-		cpu=nsv-		vendor=tandem-		;;-	nsx-tandem)-		cpu=nsx-		vendor=tandem-		;;-	mipsallegrexel-sony)-		cpu=mipsallegrexel-		vendor=sony-		;;-	tile*-*)-		basic_os=${basic_os:-linux-gnu}-		;;--	*)-		# Recognize the canonical CPU types that are allowed with any-		# company name.-		case $cpu in-			1750a | 580 \-			| a29k \-			| aarch64 | aarch64_be \-			| abacus \-			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \-			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \-			| alphapca5[67] | alpha64pca5[67] \-			| am33_2.0 \-			| amdgcn \-			| arc | arceb \-			| arm | arm[lb]e | arme[lb] | armv* \-			| avr | avr32 \-			| asmjs \-			| ba \-			| be32 | be64 \-			| bfin | bpf | bs2000 \-			| c[123]* | c30 | [cjt]90 | c4x \-			| c8051 | clipper | craynv | csky | cydra \-			| d10v | d30v | dlx | dsp16xx \-			| e2k | elxsi | epiphany \-			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \-			| h8300 | h8500 \-			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \-			| hexagon \-			| i370 | i*86 | i860 | i960 | ia16 | ia64 \-			| ip2k | iq2000 \-			| k1om \-			| le32 | le64 \-			| lm32 \-			| loongarch32 | loongarch64 | loongarchx32 \-			| m32c | m32r | m32rle \-			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \-			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \-			| m88110 | m88k | maxq | mb | mcore | mep | metag \-			| microblaze | microblazeel \-			| mips | mipsbe | mipseb | mipsel | mipsle \-			| mips16 \-			| mips64 | mips64eb | mips64el \-			| mips64octeon | mips64octeonel \-			| mips64orion | mips64orionel \-			| mips64r5900 | mips64r5900el \-			| mips64vr | mips64vrel \-			| mips64vr4100 | mips64vr4100el \-			| mips64vr4300 | mips64vr4300el \-			| mips64vr5000 | mips64vr5000el \-			| mips64vr5900 | mips64vr5900el \-			| mipsisa32 | mipsisa32el \-			| mipsisa32r2 | mipsisa32r2el \-			| mipsisa32r6 | mipsisa32r6el \-			| mipsisa64 | mipsisa64el \-			| mipsisa64r2 | mipsisa64r2el \-			| mipsisa64r6 | mipsisa64r6el \-			| mipsisa64sb1 | mipsisa64sb1el \-			| mipsisa64sr71k | mipsisa64sr71kel \-			| mipsr5900 | mipsr5900el \-			| mipstx39 | mipstx39el \-			| mmix \-			| mn10200 | mn10300 \-			| moxie \-			| mt \-			| msp430 \-			| nds32 | nds32le | nds32be \-			| nfp \-			| nios | nios2 | nios2eb | nios2el \-			| none | np1 | ns16k | ns32k | nvptx \-			| open8 \-			| or1k* \-			| or32 \-			| orion \-			| picochip \-			| pdp10 | pdp11 | pj | pjl | pn | power \-			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \-			| pru \-			| pyramid \-			| riscv | riscv32 | riscv32be | riscv64 | riscv64be \-			| rl78 | romp | rs6000 | rx \-			| s390 | s390x \-			| score \-			| sh | shl \-			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \-			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \-			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \-			| sparclite \-			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \-			| spu \-			| tahoe \-			| thumbv7* \-			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \-			| tron \-			| ubicom32 \-			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \-			| vax \-			| visium \-			| w65 \-			| wasm32 | wasm64 \-			| we32k \-			| x86 | x86_64 | xc16x | xgate | xps100 \-			| xstormy16 | xtensa* \-			| ymp \-			| z8k | z80)-				;;--			*)-				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2-				exit 1-				;;-		esac-		;;-esac--# Here we canonicalize certain aliases for manufacturers.-case $vendor in-	digital*)-		vendor=dec-		;;-	commodore*)-		vendor=cbm-		;;-	*)-		;;-esac--# Decode manufacturer-specific aliases for certain operating systems.--if test x$basic_os != x-then--# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just-# set os.-case $basic_os in-	gnu/linux*)-		kernel=linux-		os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')-		;;-	os2-emx)-		kernel=os2-		os=$(echo $basic_os | sed -e 's|os2-emx|emx|')-		;;-	nto-qnx*)-		kernel=nto-		os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')-		;;-	*-*)-		# shellcheck disable=SC2162-		IFS="-" read kernel os <<EOF-$basic_os-EOF-		;;-	# Default OS when just kernel was specified-	nto*)-		kernel=nto-		os=$(echo $basic_os | sed -e 's|nto|qnx|')-		;;-	linux*)-		kernel=linux-		os=$(echo $basic_os | sed -e 's|linux|gnu|')-		;;-	*)-		kernel=-		os=$basic_os-		;;-esac--# Now, normalize the OS (knowing we just have one component, it's not a kernel,-# etc.)-case $os in-	# First match some system type aliases that might get confused-	# with valid system types.-	# solaris* is a basic system type, with this one exception.-	auroraux)-		os=auroraux-		;;-	bluegene*)-		os=cnk-		;;-	solaris1 | solaris1.*)-		os=$(echo $os | sed -e 's|solaris1|sunos4|')-		;;-	solaris)-		os=solaris2-		;;-	unixware*)-		os=sysv4.2uw-		;;-	# es1800 is here to avoid being matched by es* (a different OS)-	es1800*)-		os=ose-		;;-	# Some version numbers need modification-	chorusos*)-		os=chorusos-		;;-	isc)-		os=isc2.2-		;;-	sco6)-		os=sco5v6-		;;-	sco5)-		os=sco3.2v5-		;;-	sco4)-		os=sco3.2v4-		;;-	sco3.2.[4-9]*)-		os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')-		;;-	sco*v* | scout)-		# Don't match below-		;;-	sco*)-		os=sco3.2v2-		;;-	psos*)-		os=psos-		;;-	qnx*)-		os=qnx-		;;-	hiux*)-		os=hiuxwe2-		;;-	lynx*178)-		os=lynxos178-		;;-	lynx*5)-		os=lynxos5-		;;-	lynxos*)-		# don't get caught up in next wildcard-		;;-	lynx*)-		os=lynxos-		;;-	mac[0-9]*)-		os=$(echo "$os" | sed -e 's|mac|macos|')-		;;-	opened*)-		os=openedition-		;;-	os400*)-		os=os400-		;;-	sunos5*)-		os=$(echo "$os" | sed -e 's|sunos5|solaris2|')-		;;-	sunos6*)-		os=$(echo "$os" | sed -e 's|sunos6|solaris3|')-		;;-	wince*)-		os=wince-		;;-	utek*)-		os=bsd-		;;-	dynix*)-		os=bsd-		;;-	acis*)-		os=aos-		;;-	atheos*)-		os=atheos-		;;-	syllable*)-		os=syllable-		;;-	386bsd)-		os=bsd-		;;-	ctix* | uts*)-		os=sysv-		;;-	nova*)-		os=rtmk-nova-		;;-	ns2)-		os=nextstep2-		;;-	# Preserve the version number of sinix5.-	sinix5.*)-		os=$(echo $os | sed -e 's|sinix|sysv|')-		;;-	sinix*)-		os=sysv4-		;;-	tpf*)-		os=tpf-		;;-	triton*)-		os=sysv3-		;;-	oss*)-		os=sysv3-		;;-	svr4*)-		os=sysv4-		;;-	svr3)-		os=sysv3-		;;-	sysvr4)-		os=sysv4-		;;-	ose*)-		os=ose-		;;-	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)-		os=mint-		;;-	dicos*)-		os=dicos-		;;-	pikeos*)-		# Until real need of OS specific support for-		# particular features comes up, bare metal-		# configurations are quite functional.-		case $cpu in-		    arm*)-			os=eabi-			;;-		    *)-			os=elf-			;;-		esac-		;;-	*)-		# No normalization, but not necessarily accepted, that comes below.-		;;-esac--else--# Here we handle the default operating systems that come with various machines.-# The value should be what the vendor currently ships out the door with their-# machine or put another way, the most popular os provided with the machine.--# Note that if you're going to try to match "-MANUFACTURER" here (say,-# "-sun"), then you have to tell the case statement up towards the top-# that MANUFACTURER isn't an operating system.  Otherwise, code above-# will signal an error saying that MANUFACTURER isn't an operating-# system, and we'll never get to this point.--kernel=-case $cpu-$vendor in-	score-*)-		os=elf-		;;-	spu-*)-		os=elf-		;;-	*-acorn)-		os=riscix1.2-		;;-	arm*-rebel)-		kernel=linux-		os=gnu-		;;-	arm*-semi)-		os=aout-		;;-	c4x-* | tic4x-*)-		os=coff-		;;-	c8051-*)-		os=elf-		;;-	clipper-intergraph)-		os=clix-		;;-	hexagon-*)-		os=elf-		;;-	tic54x-*)-		os=coff-		;;-	tic55x-*)-		os=coff-		;;-	tic6x-*)-		os=coff-		;;-	# This must come before the *-dec entry.-	pdp10-*)-		os=tops20-		;;-	pdp11-*)-		os=none-		;;-	*-dec | vax-*)-		os=ultrix4.2-		;;-	m68*-apollo)-		os=domain-		;;-	i386-sun)-		os=sunos4.0.2-		;;-	m68000-sun)-		os=sunos3-		;;-	m68*-cisco)-		os=aout-		;;-	mep-*)-		os=elf-		;;-	mips*-cisco)-		os=elf-		;;-	mips*-*)-		os=elf-		;;-	or32-*)-		os=coff-		;;-	*-tti)	# must be before sparc entry or we get the wrong os.-		os=sysv3-		;;-	sparc-* | *-sun)-		os=sunos4.1.1-		;;-	pru-*)-		os=elf-		;;-	*-be)-		os=beos-		;;-	*-ibm)-		os=aix-		;;-	*-knuth)-		os=mmixware-		;;-	*-wec)-		os=proelf-		;;-	*-winbond)-		os=proelf-		;;-	*-oki)-		os=proelf-		;;-	*-hp)-		os=hpux-		;;-	*-hitachi)-		os=hiux-		;;-	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)-		os=sysv-		;;-	*-cbm)-		os=amigaos-		;;-	*-dg)-		os=dgux-		;;-	*-dolphin)-		os=sysv3-		;;-	m68k-ccur)-		os=rtu-		;;-	m88k-omron*)-		os=luna-		;;-	*-next)-		os=nextstep-		;;-	*-sequent)-		os=ptx-		;;-	*-crds)-		os=unos-		;;-	*-ns)-		os=genix-		;;-	i370-*)-		os=mvs-		;;-	*-gould)-		os=sysv-		;;-	*-highlevel)-		os=bsd-		;;-	*-encore)-		os=bsd-		;;-	*-sgi)-		os=irix-		;;-	*-siemens)-		os=sysv4-		;;-	*-masscomp)-		os=rtu-		;;-	f30[01]-fujitsu | f700-fujitsu)-		os=uxpv-		;;-	*-rom68k)-		os=coff-		;;-	*-*bug)-		os=coff-		;;-	*-apple)-		os=macos-		;;-	*-atari*)-		os=mint-		;;-	*-wrs)-		os=vxworks-		;;-	*)-		os=none-		;;-esac--fi--# Now, validate our (potentially fixed-up) OS.-case $os in-	# Sometimes we do "kernel-libc", so those need to count as OSes.-	musl* | newlib* | uclibc*)-		;;-	# Likewise for "kernel-abi"-	eabi* | gnueabi*)-		;;-	# VxWorks passes extra cpu info in the 4th filed.-	simlinux | simwindows | spe)-		;;-	# Now accept the basic system types.-	# The portable systems comes first.-	# Each alternative MUST end in a * to match a version number.-	gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \-	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \-	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \-	     | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \-	     | hiux* | abug | nacl* | netware* | windows* \-	     | os9* | macos* | osx* | ios* \-	     | mpw* | magic* | mmixware* | mon960* | lnews* \-	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \-	     | aos* | aros* | cloudabi* | sortix* | twizzler* \-	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \-	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \-	     | mirbsd* | netbsd* | dicos* | openedition* | ose* \-	     | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \-	     | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \-	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \-	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \-	     | udi* | lites* | ieee* | go32* | aux* | hcos* \-	     | chorusrdb* | cegcc* | glidix* \-	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \-	     | midipix* | mingw32* | mingw64* | mint* \-	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \-	     | interix* | uwin* | mks* | rhapsody* | darwin* \-	     | openstep* | oskit* | conix* | pw32* | nonstopux* \-	     | storm-chaos* | tops10* | tenex* | tops20* | its* \-	     | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \-	     | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \-	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \-	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \-	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \-	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \-	     | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)-		;;-	# This one is extra strict with allowed versions-	sco3.2v2 | sco3.2v[4-9]* | sco5v6*)-		# Don't forget version if it is 3.2v4 or newer.-		;;-	none)-		;;-	*)-		echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2-		exit 1-		;;-esac--# As a final step for OS-related things, validate the OS-kernel combination-# (given a valid OS), if there is a kernel.-case $kernel-$os in-	linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )-		;;-	uclinux-uclibc* )-		;;-	-dietlibc* | -newlib* | -musl* | -uclibc* )-		# These are just libc implementations, not actual OSes, and thus-		# require a kernel.-		echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2-		exit 1-		;;-	kfreebsd*-gnu* | kopensolaris*-gnu*)-		;;-	vxworks-simlinux | vxworks-simwindows | vxworks-spe)-		;;-	nto-qnx*)-		;;-	os2-emx)-		;;-	*-eabi* | *-gnueabi*)-		;;-	-*)-		# Blank kernel with real OS is always fine.-		;;-	*-*)-		echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2-		exit 1-		;;-esac--# Here we handle the case where we know the os, and the CPU type, but not the-# manufacturer.  We pick the logical manufacturer.-case $vendor in-	unknown)-		case $cpu-$os in-			*-riscix*)-				vendor=acorn-				;;-			*-sunos*)-				vendor=sun-				;;-			*-cnk* | *-aix*)-				vendor=ibm-				;;-			*-beos*)-				vendor=be-				;;-			*-hpux*)-				vendor=hp-				;;-			*-mpeix*)-				vendor=hp-				;;-			*-hiux*)-				vendor=hitachi-				;;-			*-unos*)-				vendor=crds-				;;-			*-dgux*)-				vendor=dg-				;;-			*-luna*)-				vendor=omron-				;;-			*-genix*)-				vendor=ns-				;;-			*-clix*)-				vendor=intergraph-				;;-			*-mvs* | *-opened*)-				vendor=ibm-				;;-			*-os400*)-				vendor=ibm-				;;-			s390-* | s390x-*)-				vendor=ibm-				;;-			*-ptx*)-				vendor=sequent-				;;-			*-tpf*)-				vendor=ibm-				;;-			*-vxsim* | *-vxworks* | *-windiss*)-				vendor=wrs-				;;-			*-aux*)-				vendor=apple-				;;-			*-hms*)-				vendor=hitachi-				;;-			*-mpw* | *-macos*)-				vendor=apple-				;;-			*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)-				vendor=atari-				;;-			*-vos*)-				vendor=stratus-				;;-		esac-		;;-esac--echo "$cpu-$vendor-${kernel:+$kernel-}$os"-exit--# Local variables:-# eval: (add-hook 'before-save-hook 'time-stamp)+#   Copyright 1992-2017 Free Software Foundation, Inc.++timestamp='2017-04-02'++# This file is free software; you can redistribute it and/or modify it+# under the terms of the GNU General Public License as published by+# the Free Software Foundation; either version 3 of the License, or+# (at your option) any later version.+#+# This program is distributed in the hope that it will be useful, but+# WITHOUT ANY WARRANTY; without even the implied warranty of+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+# General Public License for more details.+#+# You should have received a copy of the GNU General Public License+# along with this program; if not, see <http://www.gnu.org/licenses/>.+#+# As a special exception to the GNU General Public License, if you+# distribute this file as part of a program that contains a+# configuration script generated by Autoconf, you may include it under+# the same distribution terms that you use for the rest of that+# program.  This Exception is an additional permission under section 7+# of the GNU General Public License, version 3 ("GPLv3").+++# Please send patches to <config-patches@gnu.org>.+#+# Configuration subroutine to validate and canonicalize a configuration type.+# Supply the specified configuration type as an argument.+# If it is invalid, we print an error message on stderr and exit with code 1.+# Otherwise, we print the canonical config type on stdout and succeed.++# You can get the latest version of this script from:+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub++# This file is supposed to be the same for all GNU packages+# and recognize all the CPU types, system types and aliases+# that are meaningful with *any* GNU software.+# Each package is responsible for reporting which valid configurations+# it does not support.  The user should be able to distinguish+# a failure to support a valid configuration from a meaningless+# configuration.++# The goal of this file is to map all the various variations of a given+# machine specification into a single specification in the form:+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM+# or in some cases, the newer four-part form:+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM+# It is wrong to echo any other type of specification.++me=`echo "$0" | sed -e 's,.*/,,'`++usage="\+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS++Canonicalize a configuration name.++Operation modes:+  -h, --help         print this help, then exit+  -t, --time-stamp   print date of last modification, then exit+  -v, --version      print version number, then exit++Report bugs and patches to <config-patches@gnu.org>."++version="\+GNU config.sub ($timestamp)++Copyright 1992-2017 Free Software Foundation, Inc.++This is free software; see the source for copying conditions.  There is NO+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."++help="+Try \`$me --help' for more information."++# Parse command line+while test $# -gt 0 ; do+  case $1 in+    --time-stamp | --time* | -t )+       echo "$timestamp" ; exit ;;+    --version | -v )+       echo "$version" ; exit ;;+    --help | --h* | -h )+       echo "$usage"; exit ;;+    -- )     # Stop option processing+       shift; break ;;+    - )	# Use stdin as input.+       break ;;+    -* )+       echo "$me: invalid option $1$help"+       exit 1 ;;++    *local*)+       # First pass through any local machine types.+       echo $1+       exit ;;++    * )+       break ;;+  esac+done++case $# in+ 0) echo "$me: missing argument$help" >&2+    exit 1;;+ 1) ;;+ *) echo "$me: too many arguments$help" >&2+    exit 1;;+esac++# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).+# Here we must recognize all the valid KERNEL-OS combinations.+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`+case $maybe_os in+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \+  kopensolaris*-gnu* | cloudabi*-eabi* | \+  storm-chaos* | os2-emx* | rtmk-nova*)+    os=-$maybe_os+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`+    ;;+  android-linux)+    os=-linux-android+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown+    ;;+  *)+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`+    if [ $basic_machine != $1 ]+    then os=`echo $1 | sed 's/.*-/-/'`+    else os=; fi+    ;;+esac++### Let's recognize common machines as not being operating systems so+### that things like config.sub decstation-3100 work.  We also+### recognize some manufacturers as not being operating systems, so we+### can provide default operating systems below.+case $os in+	-sun*os*)+		# Prevent following clause from handling this invalid input.+		;;+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \+	-apple | -axis | -knuth | -cray | -microblaze*)+		os=+		basic_machine=$1+		;;+	-bluegene*)+		os=-cnk+		;;+	-sim | -cisco | -oki | -wec | -winbond)+		os=+		basic_machine=$1+		;;+	-scout)+		;;+	-wrs)+		os=-vxworks+		basic_machine=$1+		;;+	-chorusos*)+		os=-chorusos+		basic_machine=$1+		;;+	-chorusrdb)+		os=-chorusrdb+		basic_machine=$1+		;;+	-hiux*)+		os=-hiuxwe2+		;;+	-sco6)+		os=-sco5v6+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-sco5)+		os=-sco3.2v5+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-sco4)+		os=-sco3.2v4+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-sco3.2.[4-9]*)+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-sco3.2v[4-9]*)+		# Don't forget version if it is 3.2v4 or newer.+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-sco5v6*)+		# Don't forget version if it is 3.2v4 or newer.+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-sco*)+		os=-sco3.2v2+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-udk*)+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-isc)+		os=-isc2.2+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-clix*)+		basic_machine=clipper-intergraph+		;;+	-isc*)+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`+		;;+	-lynx*178)+		os=-lynxos178+		;;+	-lynx*5)+		os=-lynxos5+		;;+	-lynx*)+		os=-lynxos+		;;+	-ptx*)+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`+		;;+	-windowsnt*)+		os=`echo $os | sed -e 's/windowsnt/winnt/'`+		;;+	-psos*)+		os=-psos+		;;+	-mint | -mint[0-9]*)+		basic_machine=m68k-atari+		os=-mint+		;;+esac++# Decode aliases for certain CPU-COMPANY combinations.+case $basic_machine in+	# Recognize the basic CPU types without company name.+	# Some are omitted here because they have special meanings below.+	1750a | 580 \+	| a29k \+	| aarch64 | aarch64_be \+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \+	| am33_2.0 \+	| arc | arceb \+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \+	| avr | avr32 \+	| ba \+	| be32 | be64 \+	| bfin \+	| c4x | c8051 | clipper \+	| d10v | d30v | dlx | dsp16xx \+	| e2k | epiphany \+	| fido | fr30 | frv | ft32 \+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \+	| hexagon \+	| i370 | i860 | i960 | ia16 | ia64 \+	| ip2k | iq2000 \+	| k1om \+	| le32 | le64 \+	| lm32 \+	| m32c | m32r | m32rle | m68000 | m68k | m88k \+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \+	| mips | mipsbe | mipseb | mipsel | mipsle \+	| mips16 \+	| mips64 | mips64el \+	| mips64octeon | mips64octeonel \+	| mips64orion | mips64orionel \+	| mips64r5900 | mips64r5900el \+	| mips64vr | mips64vrel \+	| mips64vr4100 | mips64vr4100el \+	| mips64vr4300 | mips64vr4300el \+	| mips64vr5000 | mips64vr5000el \+	| mips64vr5900 | mips64vr5900el \+	| mipsisa32 | mipsisa32el \+	| mipsisa32r2 | mipsisa32r2el \+	| mipsisa32r6 | mipsisa32r6el \+	| mipsisa64 | mipsisa64el \+	| mipsisa64r2 | mipsisa64r2el \+	| mipsisa64r6 | mipsisa64r6el \+	| mipsisa64sb1 | mipsisa64sb1el \+	| mipsisa64sr71k | mipsisa64sr71kel \+	| mipsr5900 | mipsr5900el \+	| mipstx39 | mipstx39el \+	| mn10200 | mn10300 \+	| moxie \+	| mt \+	| msp430 \+	| nds32 | nds32le | nds32be \+	| nios | nios2 | nios2eb | nios2el \+	| ns16k | ns32k \+	| open8 | or1k | or1knd | or32 \+	| pdp10 | pdp11 | pj | pjl \+	| powerpc | powerpc64 | powerpc64le | powerpcle \+	| pru \+	| pyramid \+	| riscv32 | riscv64 \+	| rl78 | rx \+	| score \+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \+	| sh64 | sh64le \+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \+	| spu \+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \+	| ubicom32 \+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \+	| visium \+	| wasm32 \+	| we32k \+	| x86 | xc16x | xstormy16 | xtensa \+	| z8k | z80)+		basic_machine=$basic_machine-unknown+		;;+	c54x)+		basic_machine=tic54x-unknown+		;;+	c55x)+		basic_machine=tic55x-unknown+		;;+	c6x)+		basic_machine=tic6x-unknown+		;;+	leon|leon[3-9])+		basic_machine=sparc-$basic_machine+		;;+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)+		basic_machine=$basic_machine-unknown+		os=-none+		;;+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)+		;;+	ms1)+		basic_machine=mt-unknown+		;;++	strongarm | thumb | xscale)+		basic_machine=arm-unknown+		;;+	xgate)+		basic_machine=$basic_machine-unknown+		os=-none+		;;+	xscaleeb)+		basic_machine=armeb-unknown+		;;++	xscaleel)+		basic_machine=armel-unknown+		;;++	# We use `pc' rather than `unknown'+	# because (1) that's what they normally are, and+	# (2) the word "unknown" tends to confuse beginning users.+	i*86 | x86_64)+	  basic_machine=$basic_machine-pc+	  ;;+	# Object if more than one company name word.+	*-*-*)+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2+		exit 1+		;;+	# Recognize the basic CPU types with company name.+	580-* \+	| a29k-* \+	| aarch64-* | aarch64_be-* \+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \+	| avr-* | avr32-* \+	| ba-* \+	| be32-* | be64-* \+	| bfin-* | bs2000-* \+	| c[123]* | c30-* | [cjt]90-* | c4x-* \+	| c8051-* | clipper-* | craynv-* | cydra-* \+	| d10v-* | d30v-* | dlx-* \+	| e2k-* | elxsi-* \+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \+	| h8300-* | h8500-* \+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \+	| hexagon-* \+	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \+	| ip2k-* | iq2000-* \+	| k1om-* \+	| le32-* | le64-* \+	| lm32-* \+	| m32c-* | m32r-* | m32rle-* \+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \+	| microblaze-* | microblazeel-* \+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \+	| mips16-* \+	| mips64-* | mips64el-* \+	| mips64octeon-* | mips64octeonel-* \+	| mips64orion-* | mips64orionel-* \+	| mips64r5900-* | mips64r5900el-* \+	| mips64vr-* | mips64vrel-* \+	| mips64vr4100-* | mips64vr4100el-* \+	| mips64vr4300-* | mips64vr4300el-* \+	| mips64vr5000-* | mips64vr5000el-* \+	| mips64vr5900-* | mips64vr5900el-* \+	| mipsisa32-* | mipsisa32el-* \+	| mipsisa32r2-* | mipsisa32r2el-* \+	| mipsisa32r6-* | mipsisa32r6el-* \+	| mipsisa64-* | mipsisa64el-* \+	| mipsisa64r2-* | mipsisa64r2el-* \+	| mipsisa64r6-* | mipsisa64r6el-* \+	| mipsisa64sb1-* | mipsisa64sb1el-* \+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \+	| mipsr5900-* | mipsr5900el-* \+	| mipstx39-* | mipstx39el-* \+	| mmix-* \+	| mt-* \+	| msp430-* \+	| nds32-* | nds32le-* | nds32be-* \+	| nios-* | nios2-* | nios2eb-* | nios2el-* \+	| none-* | np1-* | ns16k-* | ns32k-* \+	| open8-* \+	| or1k*-* \+	| orion-* \+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \+	| pru-* \+	| pyramid-* \+	| riscv32-* | riscv64-* \+	| rl78-* | romp-* | rs6000-* | rx-* \+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \+	| sparclite-* \+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \+	| tahoe-* \+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \+	| tile*-* \+	| tron-* \+	| ubicom32-* \+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \+	| vax-* \+	| visium-* \+	| wasm32-* \+	| we32k-* \+	| x86-* | x86_64-* | xc16x-* | xps100-* \+	| xstormy16-* | xtensa*-* \+	| ymp-* \+	| z8k-* | z80-*)+		;;+	# Recognize the basic CPU types without company name, with glob match.+	xtensa*)+		basic_machine=$basic_machine-unknown+		;;+	# Recognize the various machine names and aliases which stand+	# for a CPU type and a company and sometimes even an OS.+	386bsd)+		basic_machine=i386-unknown+		os=-bsd+		;;+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)+		basic_machine=m68000-att+		;;+	3b*)+		basic_machine=we32k-att+		;;+	a29khif)+		basic_machine=a29k-amd+		os=-udi+		;;+	abacus)+		basic_machine=abacus-unknown+		;;+	adobe68k)+		basic_machine=m68010-adobe+		os=-scout+		;;+	alliant | fx80)+		basic_machine=fx80-alliant+		;;+	altos | altos3068)+		basic_machine=m68k-altos+		;;+	am29k)+		basic_machine=a29k-none+		os=-bsd+		;;+	amd64)+		basic_machine=x86_64-pc+		;;+	amd64-*)+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	amdahl)+		basic_machine=580-amdahl+		os=-sysv+		;;+	amiga | amiga-*)+		basic_machine=m68k-unknown+		;;+	amigaos | amigados)+		basic_machine=m68k-unknown+		os=-amigaos+		;;+	amigaunix | amix)+		basic_machine=m68k-unknown+		os=-sysv4+		;;+	apollo68)+		basic_machine=m68k-apollo+		os=-sysv+		;;+	apollo68bsd)+		basic_machine=m68k-apollo+		os=-bsd+		;;+	aros)+		basic_machine=i386-pc+		os=-aros+		;;+	asmjs)+		basic_machine=asmjs-unknown+		;;+	aux)+		basic_machine=m68k-apple+		os=-aux+		;;+	balance)+		basic_machine=ns32k-sequent+		os=-dynix+		;;+	blackfin)+		basic_machine=bfin-unknown+		os=-linux+		;;+	blackfin-*)+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`+		os=-linux+		;;+	bluegene*)+		basic_machine=powerpc-ibm+		os=-cnk+		;;+	c54x-*)+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	c55x-*)+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	c6x-*)+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	c90)+		basic_machine=c90-cray+		os=-unicos+		;;+	cegcc)+		basic_machine=arm-unknown+		os=-cegcc+		;;+	convex-c1)+		basic_machine=c1-convex+		os=-bsd+		;;+	convex-c2)+		basic_machine=c2-convex+		os=-bsd+		;;+	convex-c32)+		basic_machine=c32-convex+		os=-bsd+		;;+	convex-c34)+		basic_machine=c34-convex+		os=-bsd+		;;+	convex-c38)+		basic_machine=c38-convex+		os=-bsd+		;;+	cray | j90)+		basic_machine=j90-cray+		os=-unicos+		;;+	craynv)+		basic_machine=craynv-cray+		os=-unicosmp+		;;+	cr16 | cr16-*)+		basic_machine=cr16-unknown+		os=-elf+		;;+	crds | unos)+		basic_machine=m68k-crds+		;;+	crisv32 | crisv32-* | etraxfs*)+		basic_machine=crisv32-axis+		;;+	cris | cris-* | etrax*)+		basic_machine=cris-axis+		;;+	crx)+		basic_machine=crx-unknown+		os=-elf+		;;+	da30 | da30-*)+		basic_machine=m68k-da30+		;;+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)+		basic_machine=mips-dec+		;;+	decsystem10* | dec10*)+		basic_machine=pdp10-dec+		os=-tops10+		;;+	decsystem20* | dec20*)+		basic_machine=pdp10-dec+		os=-tops20+		;;+	delta | 3300 | motorola-3300 | motorola-delta \+	      | 3300-motorola | delta-motorola)+		basic_machine=m68k-motorola+		;;+	delta88)+		basic_machine=m88k-motorola+		os=-sysv3+		;;+	dicos)+		basic_machine=i686-pc+		os=-dicos+		;;+	djgpp)+		basic_machine=i586-pc+		os=-msdosdjgpp+		;;+	dpx20 | dpx20-*)+		basic_machine=rs6000-bull+		os=-bosx+		;;+	dpx2* | dpx2*-bull)+		basic_machine=m68k-bull+		os=-sysv3+		;;+	e500v[12])+		basic_machine=powerpc-unknown+		os=$os"spe"+		;;+	e500v[12]-*)+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`+		os=$os"spe"+		;;+	ebmon29k)+		basic_machine=a29k-amd+		os=-ebmon+		;;+	elxsi)+		basic_machine=elxsi-elxsi+		os=-bsd+		;;+	encore | umax | mmax)+		basic_machine=ns32k-encore+		;;+	es1800 | OSE68k | ose68k | ose | OSE)+		basic_machine=m68k-ericsson+		os=-ose+		;;+	fx2800)+		basic_machine=i860-alliant+		;;+	genix)+		basic_machine=ns32k-ns+		;;+	gmicro)+		basic_machine=tron-gmicro+		os=-sysv+		;;+	go32)+		basic_machine=i386-pc+		os=-go32+		;;+	h3050r* | hiux*)+		basic_machine=hppa1.1-hitachi+		os=-hiuxwe2+		;;+	h8300hms)+		basic_machine=h8300-hitachi+		os=-hms+		;;+	h8300xray)+		basic_machine=h8300-hitachi+		os=-xray+		;;+	h8500hms)+		basic_machine=h8500-hitachi+		os=-hms+		;;+	harris)+		basic_machine=m88k-harris+		os=-sysv3+		;;+	hp300-*)+		basic_machine=m68k-hp+		;;+	hp300bsd)+		basic_machine=m68k-hp+		os=-bsd+		;;+	hp300hpux)+		basic_machine=m68k-hp+		os=-hpux+		;;+	hp3k9[0-9][0-9] | hp9[0-9][0-9])+		basic_machine=hppa1.0-hp+		;;+	hp9k2[0-9][0-9] | hp9k31[0-9])+		basic_machine=m68000-hp+		;;+	hp9k3[2-9][0-9])+		basic_machine=m68k-hp+		;;+	hp9k6[0-9][0-9] | hp6[0-9][0-9])+		basic_machine=hppa1.0-hp+		;;+	hp9k7[0-79][0-9] | hp7[0-79][0-9])+		basic_machine=hppa1.1-hp+		;;+	hp9k78[0-9] | hp78[0-9])+		# FIXME: really hppa2.0-hp+		basic_machine=hppa1.1-hp+		;;+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)+		# FIXME: really hppa2.0-hp+		basic_machine=hppa1.1-hp+		;;+	hp9k8[0-9][13679] | hp8[0-9][13679])+		basic_machine=hppa1.1-hp+		;;+	hp9k8[0-9][0-9] | hp8[0-9][0-9])+		basic_machine=hppa1.0-hp+		;;+	hppa-next)+		os=-nextstep3+		;;+	hppaosf)+		basic_machine=hppa1.1-hp+		os=-osf+		;;+	hppro)+		basic_machine=hppa1.1-hp+		os=-proelf+		;;+	i370-ibm* | ibm*)+		basic_machine=i370-ibm+		;;+	i*86v32)+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`+		os=-sysv32+		;;+	i*86v4*)+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`+		os=-sysv4+		;;+	i*86v)+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`+		os=-sysv+		;;+	i*86sol2)+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`+		os=-solaris2+		;;+	i386mach)+		basic_machine=i386-mach+		os=-mach+		;;+	i386-vsta | vsta)+		basic_machine=i386-unknown+		os=-vsta+		;;+	iris | iris4d)+		basic_machine=mips-sgi+		case $os in+		    -irix*)+			;;+		    *)+			os=-irix4+			;;+		esac+		;;+	isi68 | isi)+		basic_machine=m68k-isi+		os=-sysv+		;;+	leon-*|leon[3-9]-*)+		basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`+		;;+	m68knommu)+		basic_machine=m68k-unknown+		os=-linux+		;;+	m68knommu-*)+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`+		os=-linux+		;;+	m88k-omron*)+		basic_machine=m88k-omron+		;;+	magnum | m3230)+		basic_machine=mips-mips+		os=-sysv+		;;+	merlin)+		basic_machine=ns32k-utek+		os=-sysv+		;;+	microblaze*)+		basic_machine=microblaze-xilinx+		;;+	mingw64)+		basic_machine=x86_64-pc+		os=-mingw64+		;;+	mingw32)+		basic_machine=i686-pc+		os=-mingw32+		;;+	mingw32ce)+		basic_machine=arm-unknown+		os=-mingw32ce+		;;+	miniframe)+		basic_machine=m68000-convergent+		;;+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)+		basic_machine=m68k-atari+		os=-mint+		;;+	mips3*-*)+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`+		;;+	mips3*)+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown+		;;+	monitor)+		basic_machine=m68k-rom68k+		os=-coff+		;;+	morphos)+		basic_machine=powerpc-unknown+		os=-morphos+		;;+	moxiebox)+		basic_machine=moxie-unknown+		os=-moxiebox+		;;+	msdos)+		basic_machine=i386-pc+		os=-msdos+		;;+	ms1-*)+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`+		;;+	msys)+		basic_machine=i686-pc+		os=-msys+		;;+	mvs)+		basic_machine=i370-ibm+		os=-mvs+		;;+	nacl)+		basic_machine=le32-unknown+		os=-nacl+		;;+	ncr3000)+		basic_machine=i486-ncr+		os=-sysv4+		;;+	netbsd386)+		basic_machine=i386-unknown+		os=-netbsd+		;;+	netwinder)+		basic_machine=armv4l-rebel+		os=-linux+		;;+	news | news700 | news800 | news900)+		basic_machine=m68k-sony+		os=-newsos+		;;+	news1000)+		basic_machine=m68030-sony+		os=-newsos+		;;+	news-3600 | risc-news)+		basic_machine=mips-sony+		os=-newsos+		;;+	necv70)+		basic_machine=v70-nec+		os=-sysv+		;;+	next | m*-next )+		basic_machine=m68k-next+		case $os in+		    -nextstep* )+			;;+		    -ns2*)+		      os=-nextstep2+			;;+		    *)+		      os=-nextstep3+			;;+		esac+		;;+	nh3000)+		basic_machine=m68k-harris+		os=-cxux+		;;+	nh[45]000)+		basic_machine=m88k-harris+		os=-cxux+		;;+	nindy960)+		basic_machine=i960-intel+		os=-nindy+		;;+	mon960)+		basic_machine=i960-intel+		os=-mon960+		;;+	nonstopux)+		basic_machine=mips-compaq+		os=-nonstopux+		;;+	np1)+		basic_machine=np1-gould+		;;+	neo-tandem)+		basic_machine=neo-tandem+		;;+	nse-tandem)+		basic_machine=nse-tandem+		;;+	nsr-tandem)+		basic_machine=nsr-tandem+		;;+	nsx-tandem)+		basic_machine=nsx-tandem+		;;+	op50n-* | op60c-*)+		basic_machine=hppa1.1-oki+		os=-proelf+		;;+	openrisc | openrisc-*)+		basic_machine=or32-unknown+		;;+	os400)+		basic_machine=powerpc-ibm+		os=-os400+		;;+	OSE68000 | ose68000)+		basic_machine=m68000-ericsson+		os=-ose+		;;+	os68k)+		basic_machine=m68k-none+		os=-os68k+		;;+	pa-hitachi)+		basic_machine=hppa1.1-hitachi+		os=-hiuxwe2+		;;+	paragon)+		basic_machine=i860-intel+		os=-osf+		;;+	parisc)+		basic_machine=hppa-unknown+		os=-linux+		;;+	parisc-*)+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`+		os=-linux+		;;+	pbd)+		basic_machine=sparc-tti+		;;+	pbb)+		basic_machine=m68k-tti+		;;+	pc532 | pc532-*)+		basic_machine=ns32k-pc532+		;;+	pc98)+		basic_machine=i386-pc+		;;+	pc98-*)+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	pentium | p5 | k5 | k6 | nexgen | viac3)+		basic_machine=i586-pc+		;;+	pentiumpro | p6 | 6x86 | athlon | athlon_*)+		basic_machine=i686-pc+		;;+	pentiumii | pentium2 | pentiumiii | pentium3)+		basic_machine=i686-pc+		;;+	pentium4)+		basic_machine=i786-pc+		;;+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	pentiumpro-* | p6-* | 6x86-* | athlon-*)+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	pentium4-*)+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	pn)+		basic_machine=pn-gould+		;;+	power)	basic_machine=power-ibm+		;;+	ppc | ppcbe)	basic_machine=powerpc-unknown+		;;+	ppc-* | ppcbe-*)+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	ppcle | powerpclittle)+		basic_machine=powerpcle-unknown+		;;+	ppcle-* | powerpclittle-*)+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	ppc64)	basic_machine=powerpc64-unknown+		;;+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	ppc64le | powerpc64little)+		basic_machine=powerpc64le-unknown+		;;+	ppc64le-* | powerpc64little-*)+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	ps2)+		basic_machine=i386-ibm+		;;+	pw32)+		basic_machine=i586-unknown+		os=-pw32+		;;+	rdos | rdos64)+		basic_machine=x86_64-pc+		os=-rdos+		;;+	rdos32)+		basic_machine=i386-pc+		os=-rdos+		;;+	rom68k)+		basic_machine=m68k-rom68k+		os=-coff+		;;+	rm[46]00)+		basic_machine=mips-siemens+		;;+	rtpc | rtpc-*)+		basic_machine=romp-ibm+		;;+	s390 | s390-*)+		basic_machine=s390-ibm+		;;+	s390x | s390x-*)+		basic_machine=s390x-ibm+		;;+	sa29200)+		basic_machine=a29k-amd+		os=-udi+		;;+	sb1)+		basic_machine=mipsisa64sb1-unknown+		;;+	sb1el)+		basic_machine=mipsisa64sb1el-unknown+		;;+	sde)+		basic_machine=mipsisa32-sde+		os=-elf+		;;+	sei)+		basic_machine=mips-sei+		os=-seiux+		;;+	sequent)+		basic_machine=i386-sequent+		;;+	sh)+		basic_machine=sh-hitachi+		os=-hms+		;;+	sh5el)+		basic_machine=sh5le-unknown+		;;+	sh64)+		basic_machine=sh64-unknown+		;;+	sparclite-wrs | simso-wrs)+		basic_machine=sparclite-wrs+		os=-vxworks+		;;+	sps7)+		basic_machine=m68k-bull+		os=-sysv2+		;;+	spur)+		basic_machine=spur-unknown+		;;+	st2000)+		basic_machine=m68k-tandem+		;;+	stratus)+		basic_machine=i860-stratus+		os=-sysv4+		;;+	strongarm-* | thumb-*)+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`+		;;+	sun2)+		basic_machine=m68000-sun+		;;+	sun2os3)+		basic_machine=m68000-sun+		os=-sunos3+		;;+	sun2os4)+		basic_machine=m68000-sun+		os=-sunos4+		;;+	sun3os3)+		basic_machine=m68k-sun+		os=-sunos3+		;;+	sun3os4)+		basic_machine=m68k-sun+		os=-sunos4+		;;+	sun4os3)+		basic_machine=sparc-sun+		os=-sunos3+		;;+	sun4os4)+		basic_machine=sparc-sun+		os=-sunos4+		;;+	sun4sol2)+		basic_machine=sparc-sun+		os=-solaris2+		;;+	sun3 | sun3-*)+		basic_machine=m68k-sun+		;;+	sun4)+		basic_machine=sparc-sun+		;;+	sun386 | sun386i | roadrunner)+		basic_machine=i386-sun+		;;+	sv1)+		basic_machine=sv1-cray+		os=-unicos+		;;+	symmetry)+		basic_machine=i386-sequent+		os=-dynix+		;;+	t3e)+		basic_machine=alphaev5-cray+		os=-unicos+		;;+	t90)+		basic_machine=t90-cray+		os=-unicos+		;;+	tile*)+		basic_machine=$basic_machine-unknown+		os=-linux-gnu+		;;+	tx39)+		basic_machine=mipstx39-unknown+		;;+	tx39el)+		basic_machine=mipstx39el-unknown+		;;+	toad1)+		basic_machine=pdp10-xkl+		os=-tops20+		;;+	tower | tower-32)+		basic_machine=m68k-ncr+		;;+	tpf)+		basic_machine=s390x-ibm+		os=-tpf+		;;+	udi29k)+		basic_machine=a29k-amd+		os=-udi+		;;+	ultra3)+		basic_machine=a29k-nyu+		os=-sym1+		;;+	v810 | necv810)+		basic_machine=v810-nec+		os=-none+		;;+	vaxv)+		basic_machine=vax-dec+		os=-sysv+		;;+	vms)+		basic_machine=vax-dec+		os=-vms+		;;+	vpp*|vx|vx-*)+		basic_machine=f301-fujitsu+		;;+	vxworks960)+		basic_machine=i960-wrs+		os=-vxworks+		;;+	vxworks68)+		basic_machine=m68k-wrs+		os=-vxworks+		;;+	vxworks29k)+		basic_machine=a29k-wrs+		os=-vxworks+		;;+	wasm32)+		basic_machine=wasm32-unknown+		;;+	w65*)+		basic_machine=w65-wdc+		os=-none+		;;+	w89k-*)+		basic_machine=hppa1.1-winbond+		os=-proelf+		;;+	xbox)+		basic_machine=i686-pc+		os=-mingw32+		;;+	xps | xps100)+		basic_machine=xps100-honeywell+		;;+	xscale-* | xscalee[bl]-*)+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`+		;;+	ymp)+		basic_machine=ymp-cray+		os=-unicos+		;;+	z8k-*-coff)+		basic_machine=z8k-unknown+		os=-sim+		;;+	z80-*-coff)+		basic_machine=z80-unknown+		os=-sim+		;;+	none)+		basic_machine=none-none+		os=-none+		;;++# Here we handle the default manufacturer of certain CPU types.  It is in+# some cases the only manufacturer, in others, it is the most popular.+	w89k)+		basic_machine=hppa1.1-winbond+		;;+	op50n)+		basic_machine=hppa1.1-oki+		;;+	op60c)+		basic_machine=hppa1.1-oki+		;;+	romp)+		basic_machine=romp-ibm+		;;+	mmix)+		basic_machine=mmix-knuth+		;;+	rs6000)+		basic_machine=rs6000-ibm+		;;+	vax)+		basic_machine=vax-dec+		;;+	pdp10)+		# there are many clones, so DEC is not a safe bet+		basic_machine=pdp10-unknown+		;;+	pdp11)+		basic_machine=pdp11-dec+		;;+	we32k)+		basic_machine=we32k-att+		;;+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)+		basic_machine=sh-unknown+		;;+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)+		basic_machine=sparc-sun+		;;+	cydra)+		basic_machine=cydra-cydrome+		;;+	orion)+		basic_machine=orion-highlevel+		;;+	orion105)+		basic_machine=clipper-highlevel+		;;+	mac | mpw | mac-mpw)+		basic_machine=m68k-apple+		;;+	pmac | pmac-mpw)+		basic_machine=powerpc-apple+		;;+	*-unknown)+		# Make sure to match an already-canonicalized machine name.+		;;+	*)+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2+		exit 1+		;;+esac++# Here we canonicalize certain aliases for manufacturers.+case $basic_machine in+	*-digital*)+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`+		;;+	*-commodore*)+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`+		;;+	*)+		;;+esac++# Decode manufacturer-specific aliases for certain operating systems.++if [ x"$os" != x"" ]+then+case $os in+	# First match some system type aliases+	# that might get confused with valid system types.+	# -solaris* is a basic system type, with this one exception.+	-auroraux)+		os=-auroraux+		;;+	-solaris1 | -solaris1.*)+		os=`echo $os | sed -e 's|solaris1|sunos4|'`+		;;+	-solaris)+		os=-solaris2+		;;+	-svr4*)+		os=-sysv4+		;;+	-unixware*)+		os=-sysv4.2uw+		;;+	-gnu/linux*)+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`+		;;+	# First accept the basic system types.+	# The portable systems comes first.+	# Each alternative MUST END IN A *, to match a version number.+	# -sysv* is not here because it comes later, after sysvr4.+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \+	      | -sym* | -kopensolaris* | -plan9* \+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \+	      | -aos* | -aros* | -cloudabi* | -sortix* \+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \+	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \+	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \+	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \+	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \+	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)+	# Remember, each alternative MUST END IN *, to match a version number.+		;;+	-qnx*)+		case $basic_machine in+		    x86-* | i*86-*)+			;;+		    *)+			os=-nto$os+			;;+		esac+		;;+	-nto-qnx*)+		;;+	-nto*)+		os=`echo $os | sed -e 's|nto|nto-qnx|'`+		;;+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)+		;;+	-mac*)+		os=`echo $os | sed -e 's|mac|macos|'`+		;;+	-linux-dietlibc)+		os=-linux-dietlibc+		;;+	-linux*)+		os=`echo $os | sed -e 's|linux|linux-gnu|'`+		;;+	-sunos5*)+		os=`echo $os | sed -e 's|sunos5|solaris2|'`+		;;+	-sunos6*)+		os=`echo $os | sed -e 's|sunos6|solaris3|'`+		;;+	-opened*)+		os=-openedition+		;;+	-os400*)+		os=-os400+		;;+	-wince*)+		os=-wince+		;;+	-osfrose*)+		os=-osfrose+		;;+	-osf*)+		os=-osf+		;;+	-utek*)+		os=-bsd+		;;+	-dynix*)+		os=-bsd+		;;+	-acis*)+		os=-aos+		;;+	-atheos*)+		os=-atheos+		;;+	-syllable*)+		os=-syllable+		;;+	-386bsd)+		os=-bsd+		;;+	-ctix* | -uts*)+		os=-sysv+		;;+	-nova*)+		os=-rtmk-nova+		;;+	-ns2 )+		os=-nextstep2+		;;+	-nsk*)+		os=-nsk+		;;+	# Preserve the version number of sinix5.+	-sinix5.*)+		os=`echo $os | sed -e 's|sinix|sysv|'`+		;;+	-sinix*)+		os=-sysv4+		;;+	-tpf*)+		os=-tpf+		;;+	-triton*)+		os=-sysv3+		;;+	-oss*)+		os=-sysv3+		;;+	-svr4)+		os=-sysv4+		;;+	-svr3)+		os=-sysv3+		;;+	-sysvr4)+		os=-sysv4+		;;+	# This must come after -sysvr4.+	-sysv*)+		;;+	-ose*)+		os=-ose+		;;+	-es1800*)+		os=-ose+		;;+	-xenix)+		os=-xenix+		;;+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)+		os=-mint+		;;+	-aros*)+		os=-aros+		;;+	-zvmoe)+		os=-zvmoe+		;;+	-dicos*)+		os=-dicos+		;;+	-nacl*)+		;;+	-ios)+		;;+	-none)+		;;+	*)+		# Get rid of the `-' at the beginning of $os.+		os=`echo $os | sed 's/[^-]*-//'`+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2+		exit 1+		;;+esac+else++# Here we handle the default operating systems that come with various machines.+# The value should be what the vendor currently ships out the door with their+# machine or put another way, the most popular os provided with the machine.++# Note that if you're going to try to match "-MANUFACTURER" here (say,+# "-sun"), then you have to tell the case statement up towards the top+# that MANUFACTURER isn't an operating system.  Otherwise, code above+# will signal an error saying that MANUFACTURER isn't an operating+# system, and we'll never get to this point.++case $basic_machine in+	score-*)+		os=-elf+		;;+	spu-*)+		os=-elf+		;;+	*-acorn)+		os=-riscix1.2+		;;+	arm*-rebel)+		os=-linux+		;;+	arm*-semi)+		os=-aout+		;;+	c4x-* | tic4x-*)+		os=-coff+		;;+	c8051-*)+		os=-elf+		;;+	hexagon-*)+		os=-elf+		;;+	tic54x-*)+		os=-coff+		;;+	tic55x-*)+		os=-coff+		;;+	tic6x-*)+		os=-coff+		;;+	# This must come before the *-dec entry.+	pdp10-*)+		os=-tops20+		;;+	pdp11-*)+		os=-none+		;;+	*-dec | vax-*)+		os=-ultrix4.2+		;;+	m68*-apollo)+		os=-domain+		;;+	i386-sun)+		os=-sunos4.0.2+		;;+	m68000-sun)+		os=-sunos3+		;;+	m68*-cisco)+		os=-aout+		;;+	mep-*)+		os=-elf+		;;+	mips*-cisco)+		os=-elf+		;;+	mips*-*)+		os=-elf+		;;+	or32-*)+		os=-coff+		;;+	*-tti)	# must be before sparc entry or we get the wrong os.+		os=-sysv3+		;;+	sparc-* | *-sun)+		os=-sunos4.1.1+		;;+	pru-*)+		os=-elf+		;;+	*-be)+		os=-beos+		;;+	*-haiku)+		os=-haiku+		;;+	*-ibm)+		os=-aix+		;;+	*-knuth)+		os=-mmixware+		;;+	*-wec)+		os=-proelf+		;;+	*-winbond)+		os=-proelf+		;;+	*-oki)+		os=-proelf+		;;+	*-hp)+		os=-hpux+		;;+	*-hitachi)+		os=-hiux+		;;+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)+		os=-sysv+		;;+	*-cbm)+		os=-amigaos+		;;+	*-dg)+		os=-dgux+		;;+	*-dolphin)+		os=-sysv3+		;;+	m68k-ccur)+		os=-rtu+		;;+	m88k-omron*)+		os=-luna+		;;+	*-next )+		os=-nextstep+		;;+	*-sequent)+		os=-ptx+		;;+	*-crds)+		os=-unos+		;;+	*-ns)+		os=-genix+		;;+	i370-*)+		os=-mvs+		;;+	*-next)+		os=-nextstep3+		;;+	*-gould)+		os=-sysv+		;;+	*-highlevel)+		os=-bsd+		;;+	*-encore)+		os=-bsd+		;;+	*-sgi)+		os=-irix+		;;+	*-siemens)+		os=-sysv4+		;;+	*-masscomp)+		os=-rtu+		;;+	f30[01]-fujitsu | f700-fujitsu)+		os=-uxpv+		;;+	*-rom68k)+		os=-coff+		;;+	*-*bug)+		os=-coff+		;;+	*-apple)+		os=-macos+		;;+	*-atari*)+		os=-mint+		;;+	*)+		os=-none+		;;+esac+fi++# Here we handle the case where we know the os, and the CPU type, but not the+# manufacturer.  We pick the logical manufacturer.+vendor=unknown+case $basic_machine in+	*-unknown)+		case $os in+			-riscix*)+				vendor=acorn+				;;+			-sunos*)+				vendor=sun+				;;+			-cnk*|-aix*)+				vendor=ibm+				;;+			-beos*)+				vendor=be+				;;+			-hpux*)+				vendor=hp+				;;+			-mpeix*)+				vendor=hp+				;;+			-hiux*)+				vendor=hitachi+				;;+			-unos*)+				vendor=crds+				;;+			-dgux*)+				vendor=dg+				;;+			-luna*)+				vendor=omron+				;;+			-genix*)+				vendor=ns+				;;+			-mvs* | -opened*)+				vendor=ibm+				;;+			-os400*)+				vendor=ibm+				;;+			-ptx*)+				vendor=sequent+				;;+			-tpf*)+				vendor=ibm+				;;+			-vxsim* | -vxworks* | -windiss*)+				vendor=wrs+				;;+			-aux*)+				vendor=apple+				;;+			-hms*)+				vendor=hitachi+				;;+			-mpw* | -macos*)+				vendor=apple+				;;+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)+				vendor=atari+				;;+			-vos*)+				vendor=stratus+				;;+		esac+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`+		;;+esac++echo $basic_machine$os+exit++# Local variables:+# eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'"
configure view
@@ -637,7 +637,6 @@ build_vendor build_cpu build-BUILD_PACKAGE_BOOL EGREP GREP CPP@@ -1770,6 +1769,60 @@  } # ac_fn_c_check_func +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES+# -------------------------------------------+# Tests whether TYPE exists after having included INCLUDES, setting cache+# variable VAR accordingly.+ac_fn_c_check_type ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5+$as_echo_n "checking for $2... " >&6; }+if eval \${$3+:} false; then :+  $as_echo_n "(cached) " >&6+else+  eval "$3=no"+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main ()+{+if (sizeof ($2))+	 return 0;+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+$4+int+main ()+{+if (sizeof (($2)))+	    return 0;+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :++else+  eval "$3=yes"+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi+eval ac_res=\$$3+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno++} # ac_fn_c_check_type+ # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR@@ -3664,17 +3717,6 @@ ac_config_headers="$ac_config_headers include/HsUnixConfig.h"  -# Is this a Unix system?-ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"-if test "x$ac_cv_header_dlfcn_h" = xyes; then :-  BUILD_PACKAGE_BOOL=True-else-  BUILD_PACKAGE_BOOL=False-fi---- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then :@@ -4105,6 +4147,133 @@ done  +for ac_func in alarm+do :+  ac_fn_c_check_func "$LINENO" "alarm" "ac_cv_func_alarm"+if test "x$ac_cv_func_alarm" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_ALARM 1+_ACEOF++fi+done++for ac_func in dup+do :+  ac_fn_c_check_func "$LINENO" "dup" "ac_cv_func_dup"+if test "x$ac_cv_func_dup" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_DUP 1+_ACEOF++fi+done++for ac_func in execv+do :+  ac_fn_c_check_func "$LINENO" "execv" "ac_cv_func_execv"+if test "x$ac_cv_func_execv" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_EXECV 1+_ACEOF++fi+done++for ac_func in getpid+do :+  ac_fn_c_check_func "$LINENO" "getpid" "ac_cv_func_getpid"+if test "x$ac_cv_func_getpid" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_GETPID 1+_ACEOF++fi+done++for ac_func in mknod+do :+  ac_fn_c_check_func "$LINENO" "mknod" "ac_cv_func_mknod"+if test "x$ac_cv_func_mknod" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_MKNOD 1+_ACEOF++fi+done++for ac_func in mkstemp+do :+  ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"+if test "x$ac_cv_func_mkstemp" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_MKSTEMP 1+_ACEOF++fi+done++for ac_func in pipe+do :+  ac_fn_c_check_func "$LINENO" "pipe" "ac_cv_func_pipe"+if test "x$ac_cv_func_pipe" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_PIPE 1+_ACEOF++fi+done++for ac_func in times+do :+  ac_fn_c_check_func "$LINENO" "times" "ac_cv_func_times"+if test "x$ac_cv_func_times" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_TIMES 1+_ACEOF++fi+done+++ac_fn_c_check_type "$LINENO" "struct rlimit" "ac_cv_type_struct_rlimit" "#include <sys/resource.h>+"+if test "x$ac_cv_type_struct_rlimit" = xyes; then :++$as_echo "#define HAVE_STRUCT_RLIMIT 1" >>confdefs.h++fi+++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for F_GETLK from fcntl.h" >&5+$as_echo_n "checking for F_GETLK from fcntl.h... " >&6; }+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++ #include <fcntl.h>+ #ifdef F_GETLK+        yes+ #endif++_ACEOF+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |+  $EGREP "yes" >/dev/null 2>&1; then :++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5+$as_echo "yes" >&6; }++$as_echo "#define HAVE_F_GETLK 1" >>confdefs.h+++else++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }++fi+rm -f conftest*++ ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do   if test -f "$ac_dir/install-sh"; then@@ -4297,6 +4466,28 @@ done  +ac_fn_c_check_decl "$LINENO" "CLOCKS_PER_SEC" "ac_cv_have_decl_CLOCKS_PER_SEC" "$ac_includes_default+#ifdef HAVE_TIME_H+#include <time.h>+#endif++"+if test "x$ac_cv_have_decl_CLOCKS_PER_SEC" = xyes; then :+  ac_have_decl=1+else+  ac_have_decl=0+fi++cat >>confdefs.h <<_ACEOF+#define HAVE_DECL_CLOCKS_PER_SEC $ac_have_decl+_ACEOF+if test $ac_have_decl = 1; then :++$as_echo "#define HAVE_CLOCKS_PER_SEC 1" >>confdefs.h++fi++ ac_fn_c_check_member "$LINENO" "struct stat" "st_atim" "ac_cv_member_struct_stat_st_atim" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_atim" = xyes; then : @@ -4448,6 +4639,27 @@ fi  +ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default"+if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then :++cat >>confdefs.h <<_ACEOF+#define HAVE_STRUCT_STAT_ST_BLOCKS 1+_ACEOF+++fi++ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"+if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :++cat >>confdefs.h <<_ACEOF+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1+_ACEOF+++fi++ ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" "#include <pwd.h> " if test "x$ac_cv_member_struct_passwd_pw_gecos" = xyes; then :@@ -4486,7 +4698,7 @@   # Additional temp functions-# We explicilty check for android, as the check AC_CHECK_FUNCS performs returns "yes" for mkstemps+# We explicitly check for android, as the check AC_CHECK_FUNCS performs returns "yes" for mkstemps # when targetting android. See similar conditionals for seekdir and telldir. case $target_os in #(   *-android*) :@@ -4708,7 +4920,6 @@   fp_check_const_result='-1' fi - eval "$as_fp_Cache=\$fp_check_const_result" fi eval ac_res=\$$as_fp_Cache@@ -5136,6 +5347,26 @@ else   { $as_echo "$as_me:${as_lineno-$LINENO}: Not found" >&5 $as_echo "$as_me: Not found" >&6;}+fi+++ac_fn_c_check_decl "$LINENO" "sem_getvalue" "ac_cv_have_decl_sem_getvalue" "$ac_includes_default+#include <semaphore.h>++"+if test "x$ac_cv_have_decl_sem_getvalue" = xyes; then :+  ac_have_decl=1+else+  ac_have_decl=0+fi++cat >>confdefs.h <<_ACEOF+#define HAVE_DECL_SEM_GETVALUE $ac_have_decl+_ACEOF+if test $ac_have_decl = 1; then :++$as_echo "#define HAVE_SEM_GETVALUE 1" >>confdefs.h+ fi  
configure.ac view
@@ -1,5 +1,5 @@-AC_PREREQ([2.60])-AC_INIT([Haskell unix package], [2.0], [libraries@haskell.org], [unix])+AC_PREREQ([2.69])+AC_INIT([Haskell unix package],[2.0],[libraries@haskell.org],[unix])  # Safety check: Ensure that we are in the correct source directory. AC_CONFIG_SRCDIR([include/HsUnix.h])@@ -11,10 +11,6 @@  AC_CONFIG_HEADERS([include/HsUnixConfig.h]) -# Is this a Unix system?-AC_CHECK_HEADER([dlfcn.h], [BUILD_PACKAGE_BOOL=True], [BUILD_PACKAGE_BOOL=False])-AC_SUBST([BUILD_PACKAGE_BOOL])- AC_C_CONST  dnl ** Enable large file support.  NB. do this before testing the type of@@ -38,6 +34,31 @@ AC_CHECK_FUNCS([setitimer]) AC_CHECK_FUNCS([readdir_r]) +AC_CHECK_FUNCS([alarm])+AC_CHECK_FUNCS([dup])+AC_CHECK_FUNCS([execv])+AC_CHECK_FUNCS([getpid])+AC_CHECK_FUNCS([mknod])+AC_CHECK_FUNCS([mkstemp])+AC_CHECK_FUNCS([pipe])+AC_CHECK_FUNCS([times])++AC_CHECK_TYPE([struct rlimit],[AC_DEFINE([HAVE_STRUCT_RLIMIT],[1],[HAVE_STRUCT_RLIMIT])],[],[#include <sys/resource.h>])++AC_MSG_CHECKING(for F_GETLK from fcntl.h)+AC_EGREP_CPP(yes,+[+ #include <fcntl.h>+ #ifdef F_GETLK+        yes+ #endif+], [+  AC_MSG_RESULT(yes)+  AC_DEFINE([HAVE_F_GETLK], [1], [Define to 1 if F_GETLK is available.])+], [+  AC_MSG_RESULT(no)+  ])+ dnl not available on android so check for it AC_CANONICAL_TARGET AS_CASE([$target_os],[*-android*],[],[AC_CHECK_FUNCS([telldir seekdir])])@@ -50,6 +71,12 @@ AC_CHECK_DECLS([execvpe]) AC_CHECK_FUNCS([execvpe]) +AC_CHECK_DECLS([CLOCKS_PER_SEC], [AC_DEFINE([HAVE_CLOCKS_PER_SEC],[1],[Define to 1 if you have the CLOCKS_PER_SEC macro.])], [], [AC_INCLUDES_DEFAULT+#ifdef HAVE_TIME_H+#include <time.h>+#endif+])+ AC_CHECK_MEMBERS([struct stat.st_atim]) AC_CHECK_MEMBERS([struct stat.st_mtim]) AC_CHECK_MEMBERS([struct stat.st_ctim])@@ -66,6 +93,9 @@ AC_CHECK_MEMBERS([struct stat.st_umtime]) AC_CHECK_MEMBERS([struct stat.st_uctime]) +AC_CHECK_MEMBERS([struct stat.st_blocks])+AC_CHECK_MEMBERS([struct stat.st_blksize])+ AC_CHECK_MEMBER([struct passwd.pw_gecos], [], [AC_DEFINE([HAVE_NO_PASSWD_PW_GECOS],[],[Ignore the pw_gecos member of passwd where it does not exist])], [[#include <pwd.h>]])  # Functions for changing file timestamps@@ -74,7 +104,7 @@  # Additional temp functions dnl androids bionic doesn't have mkstemps-# We explicilty check for android, as the check AC_CHECK_FUNCS performs returns "yes" for mkstemps+# We explicitly check for android, as the check AC_CHECK_FUNCS performs returns "yes" for mkstemps # when targetting android. See similar conditionals for seekdir and telldir. AS_CASE([$target_os],[*-android*],[AC_CHECK_FUNCS([mkdtemp])],[AC_CHECK_FUNCS([mkstemps mkdtemp])]) @@ -181,7 +211,7 @@   AC_DEFINE([HAVE_RTLDNEXT], [1], [Define to 1 if we can see RTLD_NEXT in dlfcn.h.]) ], [   AC_MSG_RESULT(no)-  ])    +  ])  AC_MSG_CHECKING(for RTLD_DEFAULT from dlfcn.h) AC_EGREP_CPP(yes,@@ -195,7 +225,7 @@   AC_DEFINE([HAVE_RTLDDEFAULT], [1], [Define to 1 if RTLD_DEFAULT is available.]) ], [   AC_MSG_RESULT(no)-  ])    +  ])  AC_CHECK_FUNCS(openpty,,    AC_CHECK_LIB(util,openpty,@@ -233,6 +263,10 @@ AC_SEARCH_LIBS(sem_close, pthread,     [EXTRA_LIBS="$EXTRA_LIBS $ac_lib"],     [AC_MSG_NOTICE([Not found])])++AC_CHECK_DECLS([sem_getvalue],[AC_DEFINE([HAVE_SEM_GETVALUE],[1],[Define to 1 if you have the `sem_getvalue' function.])],[],[AC_INCLUDES_DEFAULT+#include <semaphore.h>+])  AC_SUBST([EXTRA_LIBS]) AC_CONFIG_FILES([unix.buildinfo])
include/HsUnix.h view
@@ -83,7 +83,9 @@ #include <utmp.h> #endif +#if defined(HAVE_DLFCN_H) #include <dlfcn.h>+#endif  #ifdef HAVE_SIGNAL_H #include <signal.h>@@ -116,5 +118,9 @@  // push a SVR4 STREAMS module; do nothing if STREAMS not available int __hsunix_push_module(int fd, const char *module);++#ifdef HAVE_CLOCKS_PER_SEC+clock_t __hsunix_clocks_per_second (void);+#endif  #endif
include/HsUnixConfig.h.in view
@@ -99,15 +99,25 @@ /* The value of SIG_UNBLOCK. */ #undef CONST_SIG_UNBLOCK +/* Define to 1 if you have the `alarm' function. */+#undef HAVE_ALARM+ /* Define to 1 if you have the <bsd/libutil.h> header file. */ #undef HAVE_BSD_LIBUTIL_H  /* Define to 1 if you have the `clearenv' function. */ #undef HAVE_CLEARENV +/* Define to 1 if you have the CLOCKS_PER_SEC macro. */+#undef HAVE_CLOCKS_PER_SEC+ /* Define to 1 if you have the `ctermid' function. */ #undef HAVE_CTERMID +/* Define to 1 if you have the declaration of `CLOCKS_PER_SEC', and to 0 if+   you don't. */+#undef HAVE_DECL_CLOCKS_PER_SEC+ /* Define to 1 if you have the declaration of `ctermid', and to 0 if you    don't. */ #undef HAVE_DECL_CTERMID@@ -120,6 +130,10 @@    don't. */ #undef HAVE_DECL_FDATASYNC +/* Define to 1 if you have the declaration of `sem_getvalue', and to 0 if you+   don't. */+#undef HAVE_DECL_SEM_GETVALUE+ /* Define to 1 if you have the declaration of `tcdrain', and to 0 if you    don't. */ #undef HAVE_DECL_TCDRAIN@@ -133,6 +147,12 @@ /* Define to 1 if you have the <dirent.h> header file. */ #undef HAVE_DIRENT_H +/* Define to 1 if you have the `dup' function. */+#undef HAVE_DUP++/* Define to 1 if you have the `execv' function. */+#undef HAVE_EXECV+ /* Define to 1 if you have the `execvpe' function. */ #undef HAVE_EXECVPE @@ -151,6 +171,9 @@ /* Define to 1 if you have the `futimes' function. */ #undef HAVE_FUTIMES +/* Define to 1 if F_GETLK is available. */+#undef HAVE_F_GETLK+ /* Define to 1 if you have the `getgrent' function. */ #undef HAVE_GETGRENT @@ -160,6 +183,9 @@ /* Define to 1 if you have the `getgrnam_r' function. */ #undef HAVE_GETGRNAM_R +/* Define to 1 if you have the `getpid' function. */+#undef HAVE_GETPID+ /* Define to 1 if you have the `getpwent' function. */ #undef HAVE_GETPWENT @@ -199,6 +225,12 @@ /* Define to 1 if you have the `mkdtemp' function. */ #undef HAVE_MKDTEMP +/* Define to 1 if you have the `mknod' function. */+#undef HAVE_MKNOD++/* Define to 1 if you have the `mkstemp' function. */+#undef HAVE_MKSTEMP+ /* Define to 1 if you have the `mkstemps' function. */ #undef HAVE_MKSTEMPS @@ -211,6 +243,9 @@ /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY +/* Define to 1 if you have the `pipe' function. */+#undef HAVE_PIPE+ /* Define to 1 if you have the `posix_fadvise' function. */ #undef HAVE_POSIX_FADVISE @@ -244,6 +279,9 @@ /* Define to 1 if you have the `seekdir' function. */ #undef HAVE_SEEKDIR +/* Define to 1 if you have the `sem_getvalue' function. */+#undef HAVE_SEM_GETVALUE+ /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV @@ -271,6 +309,9 @@ /* Define to 1 if you have the <string.h> header file. */ #undef HAVE_STRING_H +/* HAVE_STRUCT_RLIMIT */+#undef HAVE_STRUCT_RLIMIT+ /* Define to 1 if `st_atim' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_ATIM @@ -283,6 +324,12 @@ /* Define to 1 if `st_atime_n' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_ATIME_N +/* Define to 1 if `st_blksize' is a member of `struct stat'. */+#undef HAVE_STRUCT_STAT_ST_BLKSIZE++/* Define to 1 if `st_blocks' is a member of `struct stat'. */+#undef HAVE_STRUCT_STAT_ST_BLOCKS+ /* Define to 1 if `st_ctim' is a member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_CTIM @@ -348,6 +395,9 @@  /* Define to 1 if you have the <termios.h> header file. */ #undef HAVE_TERMIOS_H++/* Define to 1 if you have the `times' function. */+#undef HAVE_TIMES  /* Define to 1 if you have the <time.h> header file. */ #undef HAVE_TIME_H
include/execvpe.h view
@@ -10,16 +10,4 @@ extern int __hsunix_execvpe(const char *name, char *const argv[], char *const envp[]); -// this hack is needed for `process`; to be removed in unix-2.8-#ifndef HSUNIX_EXECVPE_H_NO_COMPAT-#include "HsUnixConfig.h"-#if HAVE_EXECVPE-# include <unistd.h>-extern int-execvpe(const char *name, char *const argv[], char *const envp[]);-#else-# define execvpe(name,argv,envp) __hsunix_execvpe(name,argv,envp)-#endif-#endif- #endif
tests/FileStatus.hs view
@@ -95,7 +95,7 @@   fs  <- getFileStatus f   ls  <- getSymbolicLinkStatus f -  fd  <- openFd f ReadOnly Nothing defaultFileFlags+  fd  <- openFd f ReadOnly defaultFileFlags   fs' <- getFdStatus fd    when (statusElements fs /= statusElements fs') $
tests/FileStatusByteString.hs view
@@ -93,7 +93,7 @@   fs  <- getFileStatus f   ls  <- getSymbolicLinkStatus f -  fd  <- openFd f ReadOnly Nothing defaultFileFlags+  fd  <- openFd f ReadOnly defaultFileFlags   fs' <- getFdStatus fd    when (statusElements fs /= statusElements fs') $
unix.buildinfo.in view
@@ -1,3 +1,2 @@-buildable: @BUILD_PACKAGE_BOOL@ extra-libraries: @EXTRA_LIBS@ install-includes: HsUnixConfig.h
unix.cabal view
@@ -1,16 +1,23 @@+cabal-version:  1.12 name:           unix-version:        2.7.3+version:        2.8.0.0 -- NOTE: Don't forget to update ./changelog.md+ license:        BSD3 license-file:   LICENSE-maintainer:     libraries@haskell.org+maintainer:     Julian Ospald <hasufell@posteo.de>, Viktor Dukhovni <ietf-dane@dukhovni.org>, Andrew Lelechenko <andrew.lelechenko@gmail.com> homepage:       https://github.com/haskell/unix bug-reports:    https://github.com/haskell/unix/issues synopsis:       POSIX functionality category:       System build-type:     Configure-cabal-version:  >= 1.10-tested-with:    GHC>=7.4.1+tested-with:    GHC==9.2.4,+                GHC==9.0.2,+                GHC==8.10.7,+                GHC==8.8.4,+                GHC==8.6.5,+                GHC==8.4.4,+                GHC==8.2.2 description:     This package gives you access to the set of operating system     services standardised by@@ -64,26 +71,34 @@     build-depends:         base        >= 4.10    && < 4.18,         bytestring  >= 0.9.2   && < 0.12,+        filepath    >= 1.4.100.0 && < 1.5,         time        >= 1.2     && < 1.13      exposed-modules:         System.Posix         System.Posix.ByteString+        System.Posix.PosixString          System.Posix.Error         System.Posix.Resource         System.Posix.Time         System.Posix.Unistd-        System.Posix.User         System.Posix.Signals         System.Posix.Signals.Exts         System.Posix.Semaphore         System.Posix.SharedMem +        System.Posix.User+        System.Posix.User.ByteString+         System.Posix.ByteString.FilePath+        System.Posix.PosixPath.FilePath          System.Posix.Directory+        System.Posix.Directory.Internals+        System.Posix.Directory.Fd         System.Posix.Directory.ByteString+        System.Posix.Directory.PosixPath          System.Posix.DynamicLinker.Module         System.Posix.DynamicLinker.Module.ByteString@@ -93,24 +108,30 @@          System.Posix.Files         System.Posix.Files.ByteString+        System.Posix.Files.PosixString          System.Posix.IO         System.Posix.IO.ByteString+        System.Posix.IO.PosixString          System.Posix.Env         System.Posix.Env.ByteString+        System.Posix.Env.PosixString          System.Posix.Fcntl          System.Posix.Process         System.Posix.Process.Internals         System.Posix.Process.ByteString+        System.Posix.Process.PosixString          System.Posix.Temp         System.Posix.Temp.ByteString+        System.Posix.Temp.PosixString          System.Posix.Terminal         System.Posix.Terminal.ByteString+        System.Posix.Terminal.PosixString      other-modules:         System.Posix.Directory.Common@@ -119,6 +140,7 @@         System.Posix.IO.Common         System.Posix.Process.Common         System.Posix.Terminal.Common+        System.Posix.User.Common      ghc-options: -Wall