Named Pipes Et Cetera

Hello, all. Three questions: 1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF 2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate) 3> Is this sort of question generally regarded as too unixy or not haskelly enough to be appropriate for this mailing list? Thanks. --BEGIN PROGRAM-- module Main () where import Control.Monad import System.IO import System.Posix.Files pipeString = "/tmp/dld.fifo" main :: IO () main = do createNamedPipe pipeString $ unionFileModes ownerReadMode ownerWriteMode pipe <- openFile pipeString ReadMode forever (hGetLine pipe >>= putStrLn) -- mac

Matthew,
Does it return immediately when you start it or only when you try to
write to the pipe with some client?
Here's what I get on my Linux box:
$ rm /tmp/dld.fifo && ./pipe &
[1] 8603
$ echo -e "1\n2\n3" > /tmp/dld.fifo
1
2
3
pipe: /tmp/dld.fifo: hGetLine: end of file
Patrick
On Tue, Nov 23, 2010 at 7:55 AM, matthew coolbeth
Hello, all.
Three questions:
1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF
2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate)
3> Is this sort of question generally regarded as too unixy or not haskelly enough to be appropriate for this mailing list?
Thanks.
--BEGIN PROGRAM-- module Main () where
import Control.Monad import System.IO import System.Posix.Files
pipeString = "/tmp/dld.fifo"
main :: IO () main = do createNamedPipe pipeString $ unionFileModes ownerReadMode ownerWriteMode pipe <- openFile pipeString ReadMode forever (hGetLine pipe >>= putStrLn)
-- mac _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

That's interesting. This was using my source code?
On mine (also a Linux box), it exited immediately, giving me no
opportunity to write to the pipe.
On 2010-11-23, Patrick LeBoutillier
Matthew,
Does it return immediately when you start it or only when you try to write to the pipe with some client?
Here's what I get on my Linux box:
$ rm /tmp/dld.fifo && ./pipe & [1] 8603 $ echo -e "1\n2\n3" > /tmp/dld.fifo 1 2 3 pipe: /tmp/dld.fifo: hGetLine: end of file
Patrick
On Tue, Nov 23, 2010 at 7:55 AM, matthew coolbeth
wrote: Hello, all.
Three questions:
1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF
2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate)
3> Is this sort of question generally regarded as too unixy or not haskelly enough to be appropriate for this mailing list?
Thanks.
--BEGIN PROGRAM-- module Main () where
import Control.Monad import System.IO import System.Posix.Files
pipeString = "/tmp/dld.fifo"
main :: IO () main = do createNamedPipe pipeString $ unionFileModes ownerReadMode ownerWriteMode pipe <- openFile pipeString ReadMode forever (hGetLine pipe >>= putStrLn)
-- mac _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada
-- mac

On Tue, Nov 23, 2010 at 9:13 AM, matthew coolbeth
That's interesting. This was using my source code?
Yes, as is. I compiled it with "ghc --make pipe.hs". I'm running Fedora 10 x64 with: $ ghc --version The Glorious Glasgow Haskell Compilation System, version 6.10.1 Patrick
On mine (also a Linux box), it exited immediately, giving me no opportunity to write to the pipe.
On 2010-11-23, Patrick LeBoutillier
wrote: Matthew,
Does it return immediately when you start it or only when you try to write to the pipe with some client?
Here's what I get on my Linux box:
$ rm /tmp/dld.fifo && ./pipe & [1] 8603 $ echo -e "1\n2\n3" > /tmp/dld.fifo 1 2 3 pipe: /tmp/dld.fifo: hGetLine: end of file
Patrick
On Tue, Nov 23, 2010 at 7:55 AM, matthew coolbeth
wrote: Hello, all.
Three questions:
1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF
2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate)
3> Is this sort of question generally regarded as too unixy or not haskelly enough to be appropriate for this mailing list?
Thanks.
--BEGIN PROGRAM-- module Main () where
import Control.Monad import System.IO import System.Posix.Files
pipeString = "/tmp/dld.fifo"
main :: IO () main = do createNamedPipe pipeString $ unionFileModes ownerReadMode ownerWriteMode pipe <- openFile pipeString ReadMode forever (hGetLine pipe >>= putStrLn)
-- mac _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada
-- mac
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

Here's the uname -a output:
$ uname -a
Linux pc207 2.6.30.10-105.2.23.fc11.x86_64 #1 SMP Thu Feb 11 07:06:34
UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
Patrick
On Tue, Nov 23, 2010 at 10:36 AM, Patrick LeBoutillier
On Tue, Nov 23, 2010 at 9:13 AM, matthew coolbeth
wrote: That's interesting. This was using my source code?
Yes, as is. I compiled it with "ghc --make pipe.hs".
I'm running Fedora 10 x64 with: $ ghc --version The Glorious Glasgow Haskell Compilation System, version 6.10.1
Patrick
On mine (also a Linux box), it exited immediately, giving me no opportunity to write to the pipe.
On 2010-11-23, Patrick LeBoutillier
wrote: Matthew,
Does it return immediately when you start it or only when you try to write to the pipe with some client?
Here's what I get on my Linux box:
$ rm /tmp/dld.fifo && ./pipe & [1] 8603 $ echo -e "1\n2\n3" > /tmp/dld.fifo 1 2 3 pipe: /tmp/dld.fifo: hGetLine: end of file
Patrick
On Tue, Nov 23, 2010 at 7:55 AM, matthew coolbeth
wrote: Hello, all.
Three questions:
1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF
2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate)
3> Is this sort of question generally regarded as too unixy or not haskelly enough to be appropriate for this mailing list?
Thanks.
--BEGIN PROGRAM-- module Main () where
import Control.Monad import System.IO import System.Posix.Files
pipeString = "/tmp/dld.fifo"
main :: IO () main = do createNamedPipe pipeString $ unionFileModes ownerReadMode ownerWriteMode pipe <- openFile pipeString ReadMode forever (hGetLine pipe >>= putStrLn)
-- mac _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada
-- mac
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada
-- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 11/23/10 10:36 , Patrick LeBoutillier wrote:
The Glorious Glasgow Haskell Compilation System, version 6.10.1
IIRC this was in fact broken in 6.10.1; upgrade at least to 6.10.3. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkz5THAACgkQIn7hlCsL25VOEQCgp/fPxHTsFb6vAeaO1GGonZDc dh8AmgIy4l0khXTHliySwRSnz804tu0Z =m7l1 -----END PGP SIGNATURE-----

As Mr Therning suggested, I switched over from System.IO.openFile to
openFd in System.Posix.
This gives the blocking behavior that I want. The only downside was
having to provide my own readLine.
Just so everyone knows.
thanks,
mac
On 2010-12-03, Brandon S Allbery KF8NH
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/23/10 10:36 , Patrick LeBoutillier wrote:
The Glorious Glasgow Haskell Compilation System, version 6.10.1
IIRC this was in fact broken in 6.10.1; upgrade at least to 6.10.3.
- -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkz5THAACgkQIn7hlCsL25VOEQCgp/fPxHTsFb6vAeaO1GGonZDc dh8AmgIy4l0khXTHliySwRSnz804tu0Z =m7l1 -----END PGP SIGNATURE-----
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
-- mac

On Tue, Nov 23, 2010 at 14:09, Patrick LeBoutillier
Matthew,
Does it return immediately when you start it or only when you try to write to the pipe with some client?
Here's what I get on my Linux box:
$ rm /tmp/dld.fifo && ./pipe & [1] 8603 $ echo -e "1\n2\n3" > /tmp/dld.fifo 1 2 3 pipe: /tmp/dld.fifo: hGetLine: end of file
Would you run 'uname -a' and 'ghc --version'? I don't see that behaviour here % uname -a Linux bryma 2.6.35-ARCH #1 SMP PREEMPT Sat Oct 30 21:22:26 CEST 2010 x86_64 Intel(R) Core(TM)2 Quad CPU Q9450 @ 2.66GHz GenuineIntel GNU/Linux % ghc --version The Glorious Glasgow Haskell Compilation System, version 6.12.3 % rm /tmp/dld.fifo && ./pipe& [1] 30762 % pipe: /tmp/dld.fifo: hGetLine: end of file [1] + exit 1 ./pipe /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus

On Tuesday 23 November 2010 15:16:59, Magnus Therning wrote:
On Tue, Nov 23, 2010 at 14:09, Patrick LeBoutillier
wrote: Matthew,
Does it return immediately when you start it or only when you try to write to the pipe with some client?
Here's what I get on my Linux box:
$ rm /tmp/dld.fifo && ./pipe & [1] 8603 $ echo -e "1\n2\n3" > /tmp/dld.fifo 1 2 3 pipe: /tmp/dld.fifo: hGetLine: end of file
Would you run 'uname -a' and 'ghc --version'?
I don't see that behaviour here
% uname -a Linux bryma 2.6.35-ARCH #1 SMP PREEMPT Sat Oct 30 21:22:26 CEST 2010 x86_64 Intel(R) Core(TM)2 Quad CPU Q9450 @ 2.66GHz GenuineIntel GNU/Linux % ghc --version The Glorious Glasgow Haskell Compilation System, version 6.12.3
% rm /tmp/dld.fifo && ./pipe& [1] 30762 % pipe: /tmp/dld.fifo: hGetLine: end of file
[1] + exit 1 ./pipe
I get the same with 6.12.3 and 7.0.1. $ uname -a Linux linux-mkk1 2.6.27.54-0.1-pae #1 SMP 2010-10-19 18:40:07 +0200 i686 i686 i386 GNU/Linux
/M

On Tue, Nov 23, 2010 at 12:55, matthew coolbeth
Hello, all.
Three questions:
1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF
2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate)
3> Is this sort of question generally regarded as too unixy or not haskelly enough to be appropriate for this mailing list?
The behaviour is as expected from reading the documentation on hGetLine (http://hackage.haskell.org/packages/archive/haskell98/latest/doc/html/IO.htm...). The same seems to be true for all functions in IO, so I suspect you'll have to go down to a lower level where you have more control over this behaviour, e.g. by using th fd* functions in System.Posix.IO. /M -- Magnus Therning OpenPGP: 0xAB4DFBA4 email: magnus@therning.org jabber: magnus@therning.org twitter: magthe http://therning.org/magnus

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 11/23/10 07:55 , matthew coolbeth wrote:
Hello, all.
Three questions:
1> What, if anything, can I do in a Haskell program to do blocking reads from a Linux FIFO? For the curious, there is a small program below that doesn't block, but immediately terminates because of an EOF
2> How could I have found the answer to this question on my own? (The documentation that Google found for me was not completely adequate)
This isn't specific to Haskell, but rather to Unix/POSIX FIFOs. In general, they often don't do what you want. :) The short version is: the "server" end should open read-write, because the last close by a writer will send an EOF and tear down the connection so that it can't be reused without closing and reopening. This does mean you can't actually receive EOFs if you intend to block on the FIFO, so design whatever protocol you plan to use with this in mind. That said, it sounds like GHC's I/O manager is handling this incorrectly; what you wrote should in fact block waiting for a writer, output everything it reads, then exit when the writer goes away. If it's GHC7, then likely someone broke FIFO handling (again... very few people seem to understand the care and feeding of FIFOs) in the new I/O manager. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkz5TBkACgkQIn7hlCsL25URDQCdGisbjpa65EeE83CZcyXRLuru Py4AoIB17qhlagBd3JxggakvjV23+6pC =mphl -----END PGP SIGNATURE-----
participants (5)
-
Brandon S Allbery KF8NH
-
Daniel Fischer
-
Magnus Therning
-
matthew coolbeth
-
Patrick LeBoutillier