[Haskell-cafe] ptys and hGetContent problem

Mathijs Kwik bluescreen303 at gmail.com
Mon Mar 8 18:49:09 EST 2010

And to reply to myself again...

  ta <- getTerminalAttributes fd
  setTerminalAttributes fd (withoutMode ta EnableEcho) Immediately
  -- and to find the right EOF character:
  let Just eofChar = controlChar ta EndOfFile

On Tue, Mar 9, 2010 at 12:23 AM, Mathijs Kwik <bluescreen303 at gmail.com> wrote:
> Ok, cool
> I got a bit further now.
> I'm not using handles anymore (they seem to break indeed for ptys).
> Just using executePseudoTerminalFd now (from the original blogpost)
> and fdRead/fdWrite.
> Now I can communicate with the process and all goes well.
> If I really want lazy-like behaviour, I can just forkIo and talk
> through a Chan, but for now this is enough.
> Also sending "\^C" and "\^D" work as expected, although I just saw the
> reply mentioning I should ask stty for the current EOF character.
> The only thing I'm still looking for is a way to stop echoing input.
> Right now, fdRead gives me back the output of the process, mixed with
> the input I supplied.
> I'm pretty sure this can be turned off.
> Any suggestions?
> On Mon, Mar 8, 2010 at 11:11 PM, Nick Bowler <nbowler at elliptictech.com> wrote:
>> On 20:38 Mon 08 Mar     , Mathijs Kwik wrote:
>>> Hi all,
>>> I found this blogpost from Bryan O'Sullivan
>>> http://www.serpentine.com/blog/2008/09/30/unix-hacking-in-haskell-better-pseudoterminal-support/
>>> and I wanted to try it out.
>>> Before moving to an interactive command (which needs pty), I just did
>>> a small test for "ls -l /" to see if it worked.
>>> I got it to compile, but when running, it throws an exception when
>>> reaching the end of the output (in this case because I evaluate the
>>> length to force reading all).
>>> Main: /dev/ptmx: hGetContents: hardware fault (Input/output error)
>> You have just stumbled into the wonderful world of pseudo-terminals,
>> where their behaviour is subtly different on every bloody platform.  It
>> appears that on your platform, after the last user closes the slave port
>> (i.e. after your child process terminates), subsequent reads from the
>> master port return EIO.
>> One would normally detect this condition with the poll system call, by
>> looking for POLLHUP on the master port.
>> On some platforms (but evidently not yours), the last close of the slave
>> port causes the behaviour you seem to have expected, where a subsequent
>> read returns 0.
>>> What's wrong? :)
>> Presumably the problem is that handle-based I/O is not suitable for
>> pseudo-terminal masters.  Definitely not lazy I/O.
>>> And further...
>>> If I do want to use an interactive program which needs input, how do I
>>> send ctrl-d or ctrl-c?
>>> tail -f needs ctrl-c (or I need to kill the process)
>> These so-called "control characters" are normally configured by termios.
>> If suitably configured, the appropriate action will be performed when
>> the control characters are written to the master port.
>> --
>> Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

More information about the Haskell-Cafe mailing list