[Haskell-cafe] Intercept stdin in Haskell

adam vogt vogt.adam at gmail.com
Mon Jan 6 01:20:19 UTC 2014


Hello,

That last version was still off. I think we are going with John's
idea, which is slightly more concretely in: http://lpaste.net/98017

I expect there are still issues concerning how much input to request,
so that getLine, getChar and getContents all behave as they do in the
console.

--
Adam

On Sun, Jan 5, 2014 at 7:45 PM, Andrew Gibiansky
<andrew.gibiansky at gmail.com> wrote:
> You are a saviour!
>
> 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!
>
> Working program below:
>
> import Control.Concurrent
> import Control.Monad
> import GHC.IO.Handle
> import GHC.IO.Handle.Types
> import System.IO
> import System.Posix.IO
>
> main = do
>   -- Create a pipe using System.Posix and turn it into handles.
>   (readEnd, writeEnd) <- createPipe
>   newStdin <- fdToHandle readEnd
>   stdinInput <- fdToHandle writeEnd
>
>   -- Store old stdin and swap in new stdin.
>   oldStdin <- hDuplicate stdin
>   hDuplicateTo newStdin stdin
>
>   -- In a separate thread, wait for the read.
>   forkIO $ forever $ do
>     let FileHandle _ mvar = stdin
>     threadDelay $ 200 * 1000
>     empty <- isEmptyMVar mvar
>     when empty $ do
>       putStrLn "Empty!"
>       hPutStrLn stdinInput "foo"
>       hFlush stdinInput
>
>
>
>   putStrLn "Waiting."
>   threadDelay $ 3 * 1000 * 1000
>   putStrLn "Reading."
>   getChar >>= print
>
>
>
> On Sun, Jan 5, 2014 at 7:11 PM, John Lato <jwlato at gmail.com> wrote:
>>
>> Here's a stupid idea:
>>
>> 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.
>>
>> Horrible, unsound hack, I'm sure, but it's all I've got...
>>
>>
>> On Sun, Jan 5, 2014 at 3:14 PM, Andrew Gibiansky
>> <andrew.gibiansky at gmail.com> wrote:
>>>
>>> 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.
>>>
>>>
>>> On Sun, Jan 5, 2014 at 5:19 PM, Andrew Gibiansky
>>> <andrew.gibiansky at gmail.com> wrote:
>>>>
>>>> I think we found a way! (With a *ton* of help from @aavogt - might
>>>> actually be more correct to say he found the way :) )
>>>>
>>>> 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.
>>>>
>>>> Results pending.
>>>>
>>>> -- Andrew
>>>>
>>>>
>>>> On Sun, Jan 5, 2014 at 4:14 PM, Donn Cave <donn at avvanta.com> wrote:
>>>>>
>>>>> I bet a quarter you can't do it.  You'd need access to the process
>>>>> state -
>>>>> whether it's blocking for I/O and whether one of the units in the input
>>>>> set
>>>>> is 0 ("stdin".)  Even if you could get that? you'd have to poll for it,
>>>>> which
>>>>> would be hideous.
>>>>>
>>>>> That's the UNIX I/O model.  I've always found it a little annoying,
>>>>> because
>>>>> I could do this with the VMS `mailbox' device, analogous to UNIX pipes
>>>>> -
>>>>> in various ways a more sophisticated interprocess communication system
>>>>> than
>>>>> UNIX's.
>>>>>
>>>>>         Donn
>>>>> _______________________________________________
>>>>> Haskell-Cafe mailing list
>>>>> Haskell-Cafe at haskell.org
>>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>>
>>>>
>>>
>>>
>>> _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>
>>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list