From 34c7bf896f19b182cf6fa104e057f1df9df1254a Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Fri, 11 Nov 2011 16:18:48 +0000 Subject: Provide a raw ByteString version of FilePath and environment APIs The new module System.Posix.ByteString provides exactly the same API as System.Posix, except that: - There is a new type: RawFilePath = ByteString - All functions mentioning FilePath in the System.Posix API use RawFilePath in the System.Posix.ByteString API - RawFilePaths are not subject to Unicode locale encoding and decoding, unlike FilePaths. They are the exact bytes passed to and returned from the underlying POSIX API. - Similarly for functions that deal in environment strings (System.Posix.Env): these use untranslated ByteStrings in System.Posix.Environment - There is a new function System.Posix.ByteString.getArgs :: [ByteString] returning the raw untranslated arguments as passed to exec() when the program was started. --- System/Posix/Terminal/ByteString.hsc | 132 +++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 System/Posix/Terminal/ByteString.hsc (limited to 'System/Posix/Terminal/ByteString.hsc') diff --git a/System/Posix/Terminal/ByteString.hsc b/System/Posix/Terminal/ByteString.hsc new file mode 100644 index 0000000..b3ca9a9 --- /dev/null +++ b/System/Posix/Terminal/ByteString.hsc @@ -0,0 +1,132 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +{-# OPTIONS_GHC -fno-warn-unused-imports #-} +#if __GLASGOW_HASKELL__ >= 701 +{-# LANGUAGE Trustworthy #-} +#endif +----------------------------------------------------------------------------- +-- | +-- Module : System.Posix.Terminal.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 Terminal support +-- +----------------------------------------------------------------------------- + +module System.Posix.Terminal.ByteString ( + -- * 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 + +import Foreign.C hiding ( + throwErrnoPath, + throwErrnoPathIf, + throwErrnoPathIf_, + throwErrnoPathIfNull, + throwErrnoPathIfMinus1, + throwErrnoPathIfMinus1_ ) + +import System.Posix.ByteString.FilePath + + +-- | @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 RawFilePath +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. +getControllingTerminalName :: IO RawFilePath +getControllingTerminalName = do + s <- throwErrnoIfNull "getControllingTerminalName" (c_ctermid nullPtr) + peekFilePath s + +foreign import ccall unsafe "ctermid" + c_ctermid :: CString -> IO CString + +-- | @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 RawFilePath + +#ifdef HAVE_PTSNAME +getSlaveTerminalName (Fd fd) = do + s <- throwErrnoIfNull "getSlaveTerminalName" (c_ptsname fd) + peekFilePath s + +foreign import ccall unsafe "__hsunix_ptsname" + c_ptsname :: CInt -> IO CString +#else +getSlaveTerminalName _ = + ioError (errnoToIOError "getSlaveTerminalName" eNOSYS Nothing Nothing) +#endif + -- cgit v1.2.3