<div dir="ltr">You are a saviour!<div><br></div><div>We'd actually already tried going down this path with takeMVars and putMVars, but somehow it didn't quite work. Let's see if this works in practice in IHaskell!</div>

<div><br></div><div>Working program below:</div><div><font face="courier new, monospace"><br></font></div><div><div><font face="courier new, monospace">import Control.Concurrent</font></div><div><font face="courier new, monospace">import Control.Monad</font></div>

<div><font face="courier new, monospace">import GHC.IO.Handle</font></div><div><font face="courier new, monospace">import GHC.IO.Handle.Types</font></div><div><font face="courier new, monospace">import System.IO</font></div>

<div><font face="courier new, monospace">import <a href="http://System.Posix.IO">System.Posix.IO</a></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">main = do</font></div>

<div><font face="courier new, monospace">  -- Create a pipe using System.Posix and turn it into handles.</font></div><div><font face="courier new, monospace">  (readEnd, writeEnd) <- createPipe</font></div><div><font face="courier new, monospace">  newStdin <- fdToHandle readEnd</font></div>

<div><font face="courier new, monospace">  stdinInput <- fdToHandle writeEnd</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  -- Store old stdin and swap in new stdin.</font></div>

<div><font face="courier new, monospace">  oldStdin <- hDuplicate stdin</font></div><div><font face="courier new, monospace">  hDuplicateTo newStdin stdin</font></div><div><font face="courier new, monospace"><br></font></div>

<div><font face="courier new, monospace">  -- In a separate thread, wait for the read.</font></div><div><font face="courier new, monospace">  forkIO $ forever $ do</font></div><div><font face="courier new, monospace">    let FileHandle _ mvar = stdin</font></div>

<div><font face="courier new, monospace">    threadDelay $ 200 * 1000</font></div><div><font face="courier new, monospace">    empty <- isEmptyMVar mvar</font></div><div><font face="courier new, monospace">    when empty $ do</font></div>

<div><font face="courier new, monospace">      putStrLn "Empty!"</font></div><div><font face="courier new, monospace">      hPutStrLn stdinInput "foo"</font></div><div><font face="courier new, monospace">      hFlush stdinInput</font></div>

<div><font face="courier new, monospace">  </font></div><div><font face="courier new, monospace">  </font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">  putStrLn "Waiting."</font></div>

<div><font face="courier new, monospace">  threadDelay $ 3 * 1000 * 1000</font></div><div><font face="courier new, monospace">  putStrLn "Reading."</font></div><div><font face="courier new, monospace">  getChar >>= print</font></div>

</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 5, 2014 at 7:11 PM, John Lato <span dir="ltr"><<a href="mailto:jwlato@gmail.com" target="_blank">jwlato@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Here's a stupid idea:<div><br></div><div>A Handle contains an MVar Handle__, and when a thread calls hGetLine stdin, it will take that MVar, attempt to read from the buffered device, and then block until there's data available to be read from the device.  You could check if the MVar is empty, and if so, assume that something is trying to read from stdin and write your input into the device.</div>


<div><br></div><div>Horrible, unsound hack, I'm sure, but it's all I've got...</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 5, 2014 at 3:14 PM, Andrew Gibiansky <span dir="ltr"><<a href="mailto:andrew.gibiansky@gmail.com" target="_blank">andrew.gibiansky@gmail.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Looks like the excitement was a bit premature. The types work, and in Haskell that often means the program works... but looks like hDupTo relies on the `dup2` of the IODevice class, and attempts to cast one IODevice to another IODevice. Since I'm trying to replace stdin (with IODevice type Fd) with my own IODevice, the cast fails and raises an exception. Practically ClassCastException.... yeesh.</div>


<div><div>

<div class="gmail_extra"><br><br><div class="gmail_quote">On Sun, Jan 5, 2014 at 5:19 PM, Andrew Gibiansky <span dir="ltr"><<a href="mailto:andrew.gibiansky@gmail.com" target="_blank">andrew.gibiansky@gmail.com</a>></span> wrote:<br>




<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I think we found a way! (With a *ton* of help from @aavogt - might actually be more correct to say he found the way :) )<div>




<br></div><div>You can use `hDupTo` to change what a Handle points to. You can use `mkFileHandle` in GHC.IO.Internal to create a new file handle. You can implement your own IODevice and BufferedIO datatype to give to `mkFileHandle` instead of using `Fd`. Then, when your "device" is being read from, you just implement `newBuffer` and `readBuffer` to do whatever you need them to.</div>





<div><br></div><div>Results pending.</div><span><font color="#888888"><div><br></div><div>-- Andrew</div></font></span></div><div><div><div class="gmail_extra"><br><br><div class="gmail_quote">

On Sun, Jan 5, 2014 at 4:14 PM, Donn Cave <span dir="ltr"><<a href="mailto:donn@avvanta.com" target="_blank">donn@avvanta.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I bet a quarter you can't do it.  You'd need access to the process state -<br>
whether it's blocking for I/O and whether one of the units in the input set<br>
is 0 ("stdin".)  Even if you could get that? you'd have to poll for it, which<br>
would be hideous.<br>
<br>
That's the UNIX I/O model.  I've always found it a little annoying, because<br>
I could do this with the VMS `mailbox' device, analogous to UNIX pipes -<br>
in various ways a more sophisticated interprocess communication system than<br>
UNIX's.<br>
<span><font color="#888888"><br>
        Donn<br>
</font></span><div><div>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div>