Opened 7 years ago

Closed 7 years ago

#4460 closed bug (fixed)

Input is not echoed when GHCi is suspended and subsequently brought to foreground.

Reported by: manzyuk Owned by: simonmar
Priority: normal Milestone: 7.0.2
Component: GHCi Version: 6.12.1
Keywords: suspend Cc:
Operating System: Linux Architecture: x86_64 (amd64)
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


How to reproduce:

  1. Start ghci.
  1. Press Ctrl-Z to suspend it.
  1. Type fg to bring ghci back to foreground.
  1. Hit RET to get the prompt.
  1. Type anything. The input is not echoed until you hit RET.

Also, if I press Ctrl-D to end the GHCi session (after it was suspended and brought back to foreground), I get

<stdin>: hWaitForInput: end of file

I am using ghc6 package from Debian Squeeze:

$ apt-cache show ghc6
Package: ghc6
Priority: optional
Section: haskell
Installed-Size: 378408
Maintainer: Kari Pahula <>
Architecture: amd64
Version: 6.12.1-13
Replaces: ghc6-doc (= 6.12.1-8), haddock
Provides: ghc, haddock, haskell-compiler, libghc6-array-dev, libghc6-array-dev-, libghc6-base-dev, libghc6-base-dev-, libghc6-base-dev-, libghc6-bin-package-db-dev, libghc6-bin-package-db-dev-, libghc6-bytestring-dev, libghc6-bytestring-dev-, libghc6-cabal-dev, libghc6-cabal-dev-, libghc6-containers-dev, libghc6-containers-dev-, libghc6-directory-dev, libghc6-directory-dev-, libghc6-dph-base-dev, libghc6-dph-base-dev-0.4.0-385a3, libghc6-dph-par-dev, libghc6-dph-par-dev-0.4.0-b4f33, libghc6-dph-prim-interface-dev, libghc6-dph-prim-interface-dev-0.4.0-9c8ab, libghc6-dph-prim-par-dev, libghc6-dph-prim-par-dev-0.4.0-4eccc, libghc6-dph-prim-seq-dev, libghc6-dph-prim-seq-dev-0.4.0-a2769, libghc6-dph-seq-dev, libghc6-dph-seq-dev-0.4.0-52cfd, libghc6-extensible-exceptions-dev, libghc6-extensible-exceptions-dev-, libghc6-filepath-dev, libghc6-filepath-dev-, libghc6-ghc-binary-dev, libghc6-ghc-binary-dev-, libghc6-ghc-dev-6.12.1-3a757, libghc6-ghc-prim-dev, libghc6-ghc-prim-dev-, libghc6-haskell98-dev, libghc6-haskell98-dev-, libghc6-hpc-dev, libghc6-hpc-dev-, libghc6-integer-gmp-dev, libghc6-integer-gmp-dev-, libghc6-old-locale-dev, libghc6-old-locale-dev-, libghc6-old-time-dev, libghc6-old-time-dev-, libghc6-pretty-dev, libghc6-pretty-dev-, libghc6-process-dev, libghc6-process-dev-, libghc6-random-dev, libghc6-random-dev-, libghc6-rts-dev, libghc6-syb-dev, libghc6-syb-dev-, libghc6-template-haskell-dev, libghc6-template-haskell-dev-, libghc6-time-dev, libghc6-time-dev-1.1.4-1ced4, libghc6-unix-dev, libghc6-unix-dev-, libghc6-utf8-string-dev, libghc6-utf8-string-dev-0.3.4-75a94
Depends: perl | perl5, gcc (>= 4:4.2), libgmp3-dev, libffi-dev, libbsd-dev, libc6-dev, libc6 (>= 2.3.4), libffi5 (>= 3.0.4), libgmp3c2, libncurses5 (>= 5.7+20100313)
Suggests: ghc6-prof, ghc6-doc, haskell-doc
Conflicts: ghc4 (<= 4.08.1-4), haddock
Breaks: cabal-install (<< 0.8.0), ghc6-doc (<= 6.12.1-8), haskell-devscripts (<< 0.6.19)
Filename: pool/main/g/ghc6/ghc6_6.12.1-13_amd64.deb
Size: 68875186
MD5sum: 84e247fb7f40f06a2fcd724d735c75e8
SHA1: 25e8d8f9ad9c8a484bd6a86494397ca44431208e
SHA256: 27096990dc41dfae6965ef16fa2bf12a3c2c3b7a8c9c77ead4f9b45cd422e9fe
Description: GHC - the Glasgow Haskell Compilation system
 Version 6 of the Glorious Glasgow Haskell Compilation system (GHC).  GHC is
 a compiler for Haskell98.
 Haskell is "the" standard lazy functional programming language. Haskell98
 is the current version of the language. The language definition and
 additional documentation can be found in the `haskell-doc' package.
 Alternatively, there is an online version at
Tag: devel::{compiler,interpreter,lang:haskell}, implemented-in::c, implemented-in::haskell, interface::commandline, interface::text-mode, role::program, scope::utility, uitoolkit::ncurses, works-with::software:source

Attachments (1)

Main.hs (731 bytes) - added by igloo 7 years ago.

Download all attachments as: .zip

Change History (8)

comment:1 Changed 7 years ago by judahj

Interestingly, Haskeline (ghci's line-reading backend) by itself does not have this problem. For example, the above steps work fine for the test program at:

So this issue may be caused by something specific to ghci.

Changed 7 years ago by igloo

Attachment: Main.hs added

comment:2 Changed 7 years ago by igloo

The attached Main.hs has the same problem.

comment:3 Changed 7 years ago by igloo

Milestone: 7.0.2

comment:4 Changed 7 years ago by igloo

The hSetBuffering stdin NoBuffering in particular is the problem. After suspending and resuming the program, icanon has been turned back on. We presumably need to set it to what we think it should be when we get a SIGCONT.

module Main (main) where

import Control.Monad.Trans
import System.Console.Haskeline
import System.Cmd
import System.IO

main :: IO ()
main = do gb 1
          hSetBuffering stdin NoBuffering
          gb 2
          runInputT defaultSettings runCommands
          putStrLn "Leaving."

runCommands :: InputT IO ()
runCommands = do liftIO $ gb 3
                 m <- getInputLine "Prompt: "
                 case m of
                     Nothing -> return ()
                     Just x -> do liftIO $ print x

gb :: Int -> IO ()
gb n = do putStrLn "----------------------------"
          b <- hGetBuffering stdin
          putStrLn ("b " ++ show n ++ " " ++ show b)
          rawSystem "stty" ["-a"]
          return ()

comment:5 Changed 7 years ago by simonmar

Owner: set to simonmar

I'm on this.

comment:6 Changed 7 years ago by simonmar

Status: newmerge


Fri Jan  7 12:40:42 GMT 2011  Simon Marlow <>
  * catch SIGTSTP and save/restore terminal settings (#4460)
  As far as I can tell, it is the responsibility of the program to save
  and restore its own terminal settings across a suspend/foreground, the
  shell doesn't do it (which seems odd).  So I've added a signal handler
  for SIGTSTP to the RTS which will save and restore the terminal
  settings iff we modified them with hSetBuffering or hSetEcho (we
  already restore them at exit time in these cases).

comment:7 Changed 7 years ago by igloo

Resolution: fixed
Status: mergeclosed


Note: See TracTickets for help on using tickets.