module IdeSession.RPC.Sockets (
portToString
, makeSocket
, connectToPort
, stringToPort
, acceptHandle
, ReadChannel(..)
, WriteChannel(..)
) where
import System.IO (Handle)
import GHC.Generics (Generic)
import Data.Typeable (Typeable)
import Data.Binary
import Network
import Data.ByteString.Lazy.Char8
import qualified Data.ByteString.Base64.Lazy as Base64
import Network.Socket hiding (close, sClose, accept, socketPort)
#ifdef VERSION_unix
import System.IO.Temp (createTempDirectory)
import System.FilePath ((</>))
import System.Directory (getTemporaryDirectory)
#endif
newtype ReadChannel = ReadChannel PortID deriving (Generic, Typeable)
newtype WriteChannel = WriteChannel PortID deriving (Generic, Typeable)
instance Binary ReadChannel
instance Binary WriteChannel
makeSocket :: IO Socket
#ifdef VERSION_unix
makeSocket = do
tmpDir <- getTemporaryDirectory
rpcDir <- createTempDirectory tmpDir "ide-backend-rpc."
let rpcFile = rpcDir </> "rpc"
s <- listenOn $ UnixSocket rpcFile
p <- socketPort s
return s
#else
makeSocket = listenOn $ PortNumber aNY_PORT
#endif
connectToPort :: PortID -> IO Handle
connectToPort = connectTo "localhost"
acceptHandle :: Socket -> IO Handle
acceptHandle s = do
(h, _, _) <- accept s
return h
portToString :: PortID -> String
portToString = unpack . Base64.encode . encode
stringToPort :: String -> PortID
stringToPort = decode . Base64.decodeLenient . pack
deriving instance Generic PortID
deriving instance Generic PortNumber
instance Binary PortID
instance Binary PortNumber