Opened 11 years ago

Closed 11 years ago

Last modified 10 years ago

#2228 closed merge (fixed)

runghc screws up terminal buffering mode and doesn't reset it

Reported by: guest Owned by: igloo
Priority: normal Milestone: 6.8.3
Component: GHCi Version: 6.8.2
Keywords: Cc:
Operating System: Linux Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

If I use runghc to run a Haskell script that reads from stdin, my terminal gets put into a strange buffering mode. This makes the script essentially unusable: characters are echoed twice, and Backspace and EOF don't work. The state is not even reset afterwards, so future non-Haskell programs act strangely as well.

$ cat cat.hs
main = putStr =<< getContents
$ stty
speed 38400 baud; line = 0;
eol = M-^?; eol2 = M-^?; swtch = M-^?;
iutf8
$ runghc cat.hs
hheelllloo

^D^?^D^D^C
cat.hs: exception :: GhcException

$ stty
speed 38400 baud; line = 0;
eol = M-^?; eol2 = M-^?; swtch = M-^?; min = 1; time = 0;
iutf8
-icanon

There is no problem if the script is compiled with ghc instead of interpreted with runghc.

I'm using ghc 6.8.2-2ubuntu1 on hardy amd64.

Change History (10)

comment:1 Changed 11 years ago by igloo

difficulty: Unknown
Milestone: 6.8.3

I can't reproduce this. Both before and after I get

$ stty -a      
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

(amd64/Linux, with Debian's 6.8.2-4).

comment:2 Changed 11 years ago by andersk

Architecture: x86_64 (amd64)Multiple

[I'm the original reporter.]

Are you sure they're the same? I've reproduced this on hardy's 6.8.2-2ubuntu1, sid's 6.8.2-4, and a hand-compiled 6.8.2 on etch and RHEL4, on amd64 and i386, from both gnome-terminal and the Linux console, and I've had friends reproduce it as well. After stopping runghc cat.hs with C, the difference I see in the stty -a output is that icanon changes to -icanon (which might be easy to miss visually?).

With 6.6.1, I see the same double echo, raw controls behavior while runghc cat.hs is running, but everything is correctly reset when it is stopped.

comment:3 Changed 11 years ago by igloo

Here's complete output from a gnome-terminal:

$ cat cat.hs
main = putStr =<< getContents
$ stty -a
speed 38400 baud; rows 56; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
$ runghc cat.hs
hheelllloo

^D^?^D^D
cat.hs: exception :: GhcException

$ stty -a
speed 38400 baud; rows 56; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?;
swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
$ 

Incidentally, I have to press another key after control-C for it to actually terminate.

comment:4 Changed 11 years ago by andersk

Is it possible that your shell is resetting icanon between the runghc and stty commands? My shell is bash, but I just tried with zsh instead and got the same result you did.

Try this instead:

stty -a
sh -c "trap 'stty -a' INT; runghc cat.hs"

comment:5 Changed 11 years ago by igloo

Owner: set to igloo

Aha, yes, thanks, I can reproduce it with bash.

comment:6 Changed 11 years ago by simonmar

Yes, zsh saves the terminal settings and restores them after every program; use ttyctl -u to stop it doing that.

There are a couple of problems here.

  • GHCi is setting stdin/stdout to NoBuffering in runghc, and it shouldn't be. I think this is because runghc is executing multiple commands, and GHCi is resetting the buffering between the commands.
  • GHCi is exiting via topHandlerFastExit which omits all of the shutdown cleanup that the RTS normally does, in particular the restoring of the terminal state (RtsStartup.c:hs_exit_()).

igloo: I can probably fix this, but I'm not completely sure about the second issue - I think it was you that introduced the topHandlerFastExit thing. It doesn't look quite right to me.

comment:7 Changed 11 years ago by igloo

Owner: changed from igloo to simonmar

Perhaps it should just be topHandler. As long as ghc-e004 and ghc-e005 still pass it's probably fine.

comment:8 Changed 11 years ago by simonmar

Owner: changed from simonmar to igloo
Type: bugmerge

To merge:

Tue Apr 29 23:24:09 BST 2008  Simon Marlow <simonmar@microsoft.com>
  * don't turn off stdin/stdout buffering after loading a module with ghc -e (#2228)

Tue Apr 29 23:24:42 BST 2008  Simon Marlow <simonmar@microsoft.com>
  * change topHandlerFastExit to topHandler, so the terminal state gets restored (#2228)

comment:9 Changed 11 years ago by igloo

Resolution: fixed
Status: newclosed

Both merged

comment:10 Changed 10 years ago by simonmar

Architecture: MultipleUnknown/Multiple
Note: See TracTickets for help on using tickets.