Packages

The Phi Programming Language

Current section

Files

Jump to
phi lib Control Distributed Port.hm
Raw

lib/Control/Distributed/Port.hm

-----------------------------------------------------------------------------
-- |
-- Module : Control.Distributed.Port
-- Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd.
-- License : BSD-style (see the LICENSE file)
--
-- Maintainer : Feng Lee, feng@emqx.io
-- Yang M, yangm@emqx.io
-- Stability : experimental
-- Portability : portable
--
-- The Erlang Port module.
-----------------------------------------------------------------------------
module Control.Distributed.Port
( Command
, Port
, PortInfo
, PortSettings
, settings
, allPorts
, call
, command
, connect
, control
, close
, info
, nodeOf
, open
, openDriver
, openExe
, openFd
, linkPort
, unlinkPort
) where
import Control.Distributed.Node (Node)
import Control.Monad (IO)
import Data.Maybe (Maybe)
import Data.Pid (Pid)
import Data.Show (class Show)
import Data.Unit (Unit)
import Foreign (ffi1, ffiIO0, ffiIO1, ffiIO3)
import System.IO (FilePath)
import Data.Eq (class Eq)
-- | Erlang Port
foreign import data Port :: Type
type Command = String
type PortSettings =
{ packet :: Integer
, stream :: Boolean
, line :: Integer
, cd :: String
, env :: [(String, String)]
, args :: [String]
, arg0 :: String
, exitStatus :: Boolean
, useStdio :: Boolean
, stderrToOut :: Boolean
, overlappedIO :: Boolean
, direction :: Atom -- :in :out :both
, hide :: Boolean
, busyLimitsPort :: (Integer, Integer)
, busyLimitsMsgQ :: (Integer, Integer)
}
type PortInfo =
{ id :: Integer
, name :: String
, connected :: Pid
, links :: [Pid]
, input :: Integer
, output :: Integer
, osPid :: Maybe Integer
}
settings :: PortSettings
settings =
{ packet = 0
, stream = false
, line = 0
, cd = ""
, env = []
, args = []
, arg0 = ""
, exitStatus = false
, useStdio = true
, stderrToOut = false
, overlappedIO = false
, direction = :none
, hide = true
, busyLimitsPort = (0, 0)
, busyLimitsMsgQ = (0, 0)
}
allPorts :: IO [Port]
allPorts = ffiIO0 :erlang :ports
call :: Port -> Integer -> Binary -> IO Binary --TODO: check later
call = ffiIO3 :erlang :port_call
foreign import command :: Port -> Binary -> IO ()
foreign import connect :: Port -> Pid -> IO ()
control :: Port -> Integer -> Binary -> IO Binary
control = ffiIO3 :erlang :port_control
close :: Port -> IO ()
close = ffiIO1 :erlang :port_close
foreign import info :: Port -> IO (Maybe PortInfo)
nodeOf :: Port -> IO Node
nodeOf = ffiIO1 :erlang :node
foreign import open :: Command -> PortSettings -> IO Port
foreign import openDriver :: Command -> PortSettings -> IO Port
foreign import openExe :: FilePath -> PortSettings -> IO Port
foreign import openFd :: Integer -> Integer -> PortSettings -> IO Port
foreign import linkPort :: Port -> IO ()
foreign import unlinkPort :: Port -> IO ()
instance Show Port where
show = showPortImpl
showPortImpl :: Port -> String
showPortImpl = ffi1 :erlang :port_to_list
instance Eq Port where
eq = eqPortImpl
foreign import eqPortImpl :: Port -> Port -> Boolean
-- https://erlang.org/doc/reference_manual/ports.html
-- port_command(Port, Data, OptionList) -> boolean()