Буферизация по умолчанию в Haskell
Вчера я написал небольшое упражнение xinetd для моих учеников: создай программу обратного эха.
Чтобы узнать что-то новое, я попытался реализовать решение на Haskell. Тривиальныйmain = forever $ interact reverse
не работает. я прошел сквозьэтот вопрос и сделал исправленную версию:
import Control.Monad
import System.IO
main = forever $ interact revLines
revLines = unlines . map (reverse) . lines
Но эта исправленная версия также нет работа. Я прочиталбуферная документация и играл с различными настройками. Если я установлюNoBuffering
или жеLineBuffering
Моя программа работает правильно. Наконец я распечатал режимы буферизации по умолчанию для stdin и stdoutI '
import System.IO
main = do
hGetBuffering stdin >>= print
hGetBuffering stdout >>= print
у нас естьBlockBuffering Nothing
если я запускаю свою программу из xinetd (echo "test" | nc localhost 7
) но из кли яу нас естьLineBuffering
Редактировать: Спасибо всем за полезные ответы.
Я принимаю ответ, который дал Blaze, он намекнул на isatty (3). Я снова просмотрел документацию по System.IO и нашелhIsTerminalDevice функция, с которой я могу проверить соединение ручки.
Для справки, вот моя последняя программа:
{-# OPTIONS_GHC -W #-}
import System.IO
main = do
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering
interact revLines
revLines = unlines . map (reverse) . lines