1module Pager where 2 3import System.IO 4import System.Posix.IO 5import System.Posix.Terminal 6import Control.Applicative 7import Prelude 8 9-- If stdin is not connected to a tty, we're being used as a pager with 10-- output piped in. The content of stdin is sucked in and returned for 11-- paging, and stdin is re-opened from the terminal device. 12stdinPager :: IO (Maybe String) 13stdinPager = go =<< queryTerminal stdInput 14 where 15 go True = return Nothing 16 go False = do 17 stdoutisterm <- queryTerminal stdOutput 18 if stdoutisterm 19 then do 20 term <- getTerminalName stdOutput 21 oldstdin <- dup stdInput 22 closeFd stdInput 23 newstdin <- openFd term ReadOnly Nothing defaultFileFlags 24 _ <- dupTo newstdin stdInput 25 Just <$> (hGetContents =<< fdToHandle oldstdin) 26 else error "stdout is not a terminal" 27