[Haskell-cafe] named pipe interface
Serge D. Mechveliani
mechvel at botik.ru
Thu Jan 12 19:53:48 CET 2012
People,
(I wonder: is this for beginners at haskell.org ?)
I need to organize a string interface for a Haskell function
Main.axiom and a C program
fifoFromA.c
via a pair of named pipes (in Linux, UNIX).
The pipes are created before running, by the commands > mkfifo toA
> mkfifo fromA
Main.axiom outputs a string to toA and inputs the respond string
from fromA as the result.
fifoFromA inputs a string from toA,
converts it to the string resStr, outputs resStr to fromA.
Main.axiom must be able to be applied in a loop,
and there must be avoided repeated opening of a file/channel in a loop.
As an example, the string conversion in fifoFromA.c is put the
conversion of each character to the lower case:
-------------------------- fifoFromA.c ------------------------------
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#define BOUND 64
int main()
{
int toA, fromA, i, numread;
char buf[BOUND];
toA = open("toA", O_RDONLY); fromA = open("fromA", O_WRONLY);
for (;;)
{
numread = read(toA, buf, BOUND);
buf[numread] = '\0';
// printf("A: Read from toA: %s\n", buf);
i = 0; // convert the string to the lower case
while (i < numread) {buf[i] = tolower(buf[i]); i++;}
write(fromA, buf, strlen(buf));
}
}
-----------------------------------------------------------------------
For the "to-A" part writen in C (instead of Haskell), this interface
loop works all right.
With Haskell, I manage to process only a single string in the loop,
and then it ends with an error.
Main.hs is given below.
I never dealt with such an IO in Haskell.
Can you, please, fix the code or give comments?
Please, copy the response to mechvel at botik.ru
(I am not in the list).
Thank you in advance for your notes,
------
Sergei
mechvel at botik.ru
-------------------------------------------------------------------
import System.IO (IOMode(..), IO(..), Handle, openFile, hPutStr,
hGetLine, hFlush)
import System.IO.Unsafe (unsafePerformIO)
dir = showString "/home/mechvel/ghc/axiomInterface/byLowerLevel/"
toA_IO = openFile (dir "toA") WriteMode :: IO Handle
fromA_IO = openFile (dir "fromA") ReadMode
-- used as global values
toA = unsafePerformIO toA_IO --
fromA = unsafePerformIO fromA_IO --
axiomIO :: String -> IO String
axiomIO str = do
hPutStr toA str
hFlush toA
hGetLine fromA
axiom :: String -> String -> String
axiom str = showString (unsafePerformIO $ axiomIO str)
-- Examples of usage --------------------------------------------
--
main = putStr (axiom "ABC1" "\n") -- I
-- putStr (axiom "ABC1" $ showChar '\n' $ axiom "ABC2" "\n") -- II
{- III:
putStr (shows resPairs "\n")
where
n = 9000
str0 = "ABC"
strings = [str0 ++ (show i) | i <- [1 .. n]]
resPairs = [(str, axiom str "") | str <- strings]
-}
-----------------------------------------------------------------
I use Glasgow Haskell ghc-7.01.
Build: > gcc -o fifoFromA fifoFromA.c
> ghc --make Main
Running: first, command > ./fifoFromA
on terminal-2,
then command > ./Main
on terminal-1.
Now, the example (I) works
-- in the sense that terminal-1 shows the result "abc1"
after the program on terminal-2 is interrupted.
II and III do not work. And the aim is the examples like III.
More information about the Haskell-Cafe
mailing list