People, can anybody explain what incorrect may happen with the following program which uses exchange through two Unix pipes and unsafePerformIO ?
The pipes are created by the Unix commands mkfifo toA; mkfifo fromA gcc iface.c compiles the C program to a.out. ghc --make Main compiles the Haskell program by GHC to ./Main Run on the second terminal > ./iface Run on the first terminal > ./Main It prints the result to the screen. In Main.hs, the function iface :: String -> String is defined via hPutStr, hGetLine, hFlush, unsafePerformIO. It outputs str :: String to the pipe toA; the process iface (programmed in C) waits for delay and returns the respond string through the pipe fromA; iface inputs this respond string. So far, I put the respond string to be the same string, I think, this is not essential, but another map can be considered. Assume that the parallel computation is not allowed. In the below `main', I tried f ss where ss = [iface $ shows i "\n" | i <- [1 .. 4]], f [s1, s2, s3, s4] = [s3++s1, s3++s2, s1++s2], and it works correct. The question is: what a simple definition is possible for f which will evaluate incorrect? Is this true that unsafePerformIO is _safe_ for all f in this context? The `delay' constant can be edited in fifo.c. See both sources below. Please, copy the respond to mech...@botik.ru Thanks, ------ Sergei mech...@botik.ru ------------------------------------------------------------------------ import System.IO (IOMode(..), IO(..), Handle, openFile, hPutStr, hGetLine, hFlush) import System.IO.Unsafe (unsafePerformIO) dir = showString "/home/mechvel/haxiom/unsafeTest/" -- openFile :: FilePath -> IOMode -> IO Handle -- hPutStr :: Handle -> String -> IO () -- hGetLine :: Handle -> IO String toA_IO = openFile (dir "toA") WriteMode :: IO Handle fromA_IO = openFile (dir "fromA") ReadMode toA = unsafePerformIO toA_IO fromA = unsafePerformIO fromA_IO initIO :: IO (Handle, Handle) initIO = do to <- toA_IO from <- fromA_IO return (to, from) ifaceIO :: (Handle, Handle) -> String -> IO String ifaceIO (h1, h2) str = do hPutStr h1 str hFlush h1 str' <- hGetLine h2 return str' iface :: String -> String iface str = unsafePerformIO $ ifaceIO (toA, fromA) str main = putStr $ shows [s3++s1, s3++s2, s1++s2] "\n" where ss@[s1, s2, s3, s4] = [iface $ shows i "\n" | i <- [1 .. 4]] -- The C program fifo.c --------------------------------------------- #include <stdio.h> #include <string.h> #define BOUND 64 static char str[BOUND]; main() { int l, i; long j; FILE *toA, *fromA; toA = fopen("/home/mechvel/haxiom/unsafeTest/toA", "r"); if (toA == NULL) {perror("fopen(toA, r) failed: "); return;}; fromA = fopen("/home/mechvel/haxiom/unsafeTest/fromA", "w"); if (fromA == NULL) {perror("fopen(fromA, w) failed: "); return;}; for (;;) { if (fgets(str, BOUND, toA) == NULL) { perror("fgets(str, bound, toA) failed: "); return; }; j = 20000000; // delay. edit it while (j > 0) {j = j-1;}; fputs(str, fromA); fflush(fromA); }; return; } _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe