named pipes
Serge D. Mechveliani
mechvel at botik.ru
Thu Jan 19 20:16:30 CET 2012
To my
>> Dear GHC team,
>> I am testing the IO operations of GHC with the Unix named pipes
>> [..]
Albert Y. C. Lai writes on 19 Jan 2012
> Main.hs does not open fromA at all. (fromA_IO is dead code.) This causes
> fifo2.c to be hung whenever it opens fromA. From the man page of mkfifo(3)
> on Linux:
> "Opening a FIFO for reading normally blocks until some other process opens
> the same FIFO for writing, and vice versa. See fifo(7) for nonblocking
> handling of FIFO special files."
I see now. Thank you.
The intitial example was with a real usage of toA and fromA, and it did
not work as expected. Then, I simplified it, but just missed the point
that ./Main does not really open fromA.
Now, I provide below the initial example.
Can people explain, please, why it performs so?
> In the sister thread in haskell-cafe, the addition of unsafePerformIO
> throws further disorder into these highly order-sensitive operations.
By the way, can you respond (if not to `glasgow' then to mechvel at botik.ru)
to my last simple and concrete question to cafe on the subject of
unsafePerformIO ?
Anyway, the below example is free of unsafePerformIO.
And I need to delay the remaining questions on unsafePerformIO
(for myself and maybe, for `cafe') until the current example is fixed.
Regards,
------
Sergei
mechvel at botik.ru
********************************************************************
I am testing the IO operations of GHC with the Unix named pipes --
(in ghc-7.01 under Debian Linux).
In the below example,
the pipe pair are created by > mkfifo toA
> mkfifo fromA,
`main' in Main.hs opens toA for writing,
opens fromA for reading,
outputs "A1" to toA,
inputs the respond string str' from fromA,
prints str' to the screen.
The C program fifo2
opens toA for reading,
opens fromA for writing,
inputs a string str from toA,
converts str to the lower case, obtaining str'
outputs str' to fromA.
Main.hs is built by ghc --make Main,
The C program is built by gcc -o fifo2 fifo2.c
First, ./fifo2 is run on terminal-2,
then ./Main is run on terminal-1.
The effect is that fifo2 (on terminal-2) hangs silent, and
Main.hs (on terminal-1) reports only
"str1 --> hFlush done", and then hangs.
This contradicts to that ./Main must print str' to the screen.
The modules are as follows.
-- Main.hs ---------------------------------------------------------
import System.IO (IOMode(..), IO(..), Handle, openFile, hPutStr,
hFlush, hGetLine)
dir = showString "/home/mechvel/ghc/notes/npipe/"
toA_IO = openFile (dir "toA") WriteMode :: IO Handle
fromA_IO = openFile (dir "fromA") ReadMode
axiomIO :: Handle -> Handle -> String -> IO String
axiomIO h1 h2 str =
do
hPutStr h1 str
hFlush h1
putStr "hFlush done\n"
str' <- hGetLine h2
putStr (concat ["hGetLine -> ", str', "\n"])
return str'
main = do
h1 <- toA_IO
h2 <- fromA_IO
putStr "str1 --> "
str1' <- axiomIO h1 h2 "A1"
putStr (str1' ++ "\n")
----------------------- fifo2.c -------------------------------------
#include <stdio.h>
#include <string.h>
#define BOUND 64
static char str[BOUND];
main()
{
int l, i; FILE *toA, *fromA;
toA = fopen("/home/mechvel/ghc/notes/npipe/toA", "r");
if (toA == NULL) {perror("fopen(toA, r) failed: "); return;};
fromA = fopen("/home/mechvel/ghc/notes/npipe/fromA", "w");
if (fromA == NULL) {perror("fopen(fromA, w) failed: "); return;};
if (fgets(str, BOUND, toA) == NULL) {
perror("fgets(str, bound, toA) failed: "); return;
};
printf("input = %s\n", str);
l = strlen(str) - 1;
i = 0; // convert the string to the lower case
while (i < l) {str[i] = tolower(str[i]); i++;}
printf("output = %s\n", str);
fputs(str, fromA);
fflush(fromA);
printf("output to fromA done\n");
return;
}
---------------------------------------------------------------------
Comparison with C - C
---------------------
If both programs are in C, then the whole loop of the string exchange
(with fifo2.c rewritten into a loop) works as needed, both for the
variants with fgets and with `read'.
More information about the Glasgow-haskell-users
mailing list