packages feed

netw-0.1.0.0: test/unix-scm-rights/Main.hs

{-# LANGUAGE OverloadedLists #-}
module Main (main) where
import System.Posix.IO

import System.Posix.Process

import Netw.Socket
import Netw.SockAddr
import Netw.Ancillary

import Control.Monad

import Data.Bits
import Data.List
import Data.Primitive

import System.Posix
import System.Exit

serverMain :: FilePath -> IO ()
serverMain sunPath = do
  server <- socket PF_UNIX SOCK_STREAM DefaultProtocol
  bind server addr
  listen server 1
  
  client <- accept_ server
  buffer <- newByteArray 8
  
  (_, _, ancil) <- recvmsg_ client [(buffer, 0, 8)] 64 zeroBits
  let x :: Maybe ScmRights = (\ a -> ancillaryData a) . fst =<< uncons ancil
      y = case x of
            Nothing ->
              putStrLn "Failed to recv ancillary data"
            Just (ScmRights fds) -> do
              putStrLn "Received ancillary data"
              print fds
  y

  closeSocket client
  removeLink sunPath
  closeSocket server
  where addr = SockAddrUn sunPath
        

clientMain :: FilePath -> IO ()
clientMain sunPath = do
  server <- socket PF_UNIX SOCK_STREAM DefaultProtocol
  connect server addr
  fd <- openFd "/dev/null" WriteOnly Nothing defaultFileFlags
  void (sendmsg server SockAddrNull [([0], 0, 1)] [mkAncillaryData (ScmRights [fd])] zeroBits)
  closeSocket server
  where addr = SockAddrUn sunPath

main :: IO ()
main = do
  s <- forkProcess (serverMain sunPath)
  c <- forkProcess (clientMain sunPath)

  serverExit <- maybe (fail "Server failure") return =<< getProcessStatus True True s
  clientExit <- maybe (fail "Client failure") return =<< getProcessStatus True True c

  case (serverExit, clientExit) of
    (Exited ExitSuccess, Exited ExitSuccess) -> exitSuccess
    _otherwise -> exitFailure

  where sunPath = "/run/user/1000/test"