[Haskell-cafe] named pipes interface
Serge D. Mechveliani
mechvel at botik.ru
Fri Jan 13 19:43:26 CET 2012
I thank people for the notes.
People write that the example without unsafePerformIO is desirable.
So I present the improved question and improved, "pure" code.
----------------------------------------------------------------------
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 the first string in the loop,
and then it ends with an error.
Main.hs is given below. Can you, please, fix the code?
Please, copy the response to mechvel at botik.ru
Thanks,
------
Sergei
mechvel at botik.ru
------------------------------------------------------------------------
import System.IO (IOMode(..), IO(..), Handle, openFile, hPutStr,
hGetLine, hFlush)
dir = showString "/home/mechvel/ghc/axiomInterface/byLowerLevel/"
toA_IO = openFile (dir "toA") WriteMode :: IO Handle
-- used as global values
fromA_IO = openFile (dir "fromA") ReadMode --
axiomIO :: String -> IO String
axiomIO str = do
toA <- toA_IO
fromA <- fromA_IO
hPutStr toA str
hFlush toA
hGetLine fromA
---------------------------------------------- Example of usage --
main = do
putStr "str1 --> "
str1' <- axiomIO str1
putStr (str1' ++ "\n")
putStr "str2 --> "
str2' <- axiomIO str2
putStr (str2' ++ "\n")
where
n = 9
str0 = "ABC"
strings = [str0 ++ (show i) | i <- [1 .. n]]
str1: str2: _ = 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.
And it processes only the first string:
terminal-1:
m> ./Main
str1 --> abc1
str2 --> Main: /home/mechvel/m/toA:
openFile: does not exist (No such device or address)
More information about the Haskell-Cafe
mailing list