2013-10-22 10 views
11

昨日私は生徒のために少しxinetdのエクササイズを書いた:逆エコープログラムを作る。Haskellのデフォルトioバッファリング

新しいことを学ぶために、私はHaskellソリューションを実装しようとしました。簡単なmain = forever $ interact reverseは機能しません。私はthis questionを経て、修正版作っ:

import Control.Monad 
import System.IO 

main = forever $ interact revLines 

revLines = unlines . map (reverse) . lines 

をしかし、この修正版も動作しません。私はbuffering documentationを読んで、さまざまな設定で遊んだ。 NoBufferingまたはLineBufferingと設定すると、プログラムが正常に動作します。最後に、私はxinetdの(echo "test" | nc localhost 7)から私のプログラムを実行する場合、私はBlockBuffering Nothingを持って

import System.IO 

main = do 
    hGetBuffering stdin >>= print 
    hGetBuffering stdout >>= print 

標準入出力のデフォルトのバッファリングモードをプリントアウトしますが、CLIから、私は

  • 何ですかLineBufferingを持っていますxinetd tcpサービスとcliプログラムとの違いは、バッファリングに関するものですか?
  • 両方の実行方法で動作中のプログラムを書きたい場合、手動でバッファリングを設定する必要がありますか?

編集:は役に立ち解答ありがとうございました。

私は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 
+2

ここでは「永遠」は必要ありません。怠惰のために、 '対話'は入力を待っていて、 'stdin'からの完全な行ごとに、その逆が即座に出力されます。 – tempestadept

+0

私はそれがOS特有だと思っていますが、一般的には、あなたがライン指向のプログラムを持っていれば、おそらく 'LineBuffering'から最良の動作を得るでしょう。 –

+5

私は悪い質問について多くの不平を言うので、私はちょうどあなたを称賛したいと思います。これは大きな問題です。最小限のコード、問題を再現するための明確な指示、独自の進歩を示した明確な証拠、進歩のために知る必要があることの明確な説明。楽しい。 –

答えて

10

それは(例えば、標準Cライブラリは、同じことを)ハスケルに固有ではありません。レコードの

は、ここで私の最終的なプログラムです。 従来、ファイルディスクリプタが端末に対応する場合、バッファリングはラインモードに設定され、それ以外の場合はモードをブロックします。ファイルディスクリプタのタイプはisatty(3)関数で確認できます。System.IOにエクスポートされているかどうかはわかりません。

はい、依存する場合は、手動でバッファリングモードを設定する必要があります。

ちなみに、システムを攻略し、プログラムをcat | ./prog | catとして実行すると、コマンドラインでブロックバッファリングを強制することができます。

5

GHCランタイムシステムは、デフォルトのバッファリングを選択すると巧妙になります。 stdinとstdoutが端末に直接接続されているように見える場合、それらはラインバッファリングされます。それらが他のものに接続されているように見える場合は、ブロックバッファリングされます。これは、端末から直接入力されない行単位の入力を伴うプログラムを実行する場合に問題になることがあります。たとえば、cat | your-programはちょうどyour-programとは異なる動作をすると思います。

両方の実行方法で動作するプログラムを作成するには、手動でバッファリングを設定する必要がありますか。

はい。

関連する問題