#ifdef USE_EDITLINE
is_tty <- hIsTerminalDevice stdin
- when is_tty $ do
+ when is_tty $ withReadline $ do
Readline.initialize
withGhcAppData
io yield
saveSession -- for use by completion
prompt <- mkPrompt
- l <- io (readline prompt `finally` setNonBlockingFD 0)
- -- readline sometimes puts stdin into blocking mode,
- -- so we need to put it back for the IO library
+ l <- io $ withReadline (readline prompt)
splatSavedSession
case l of
Nothing -> return Nothing
io (addHistory l)
str <- io $ consoleInputToUnicode True l
return (Just str)
+
+withReadline :: IO a -> IO a
+withReadline = bracket_ stopTimer (do startTimer; setNonBlockingFD 0)
+ -- Two problems are being worked around here:
+ -- 1. readline sometimes puts stdin into blocking mode,
+ -- so we need to put it back for the IO library
+ -- 2. editline doesn't handle some of its system calls returning
+ -- EINTR, so our timer signal confuses it, hence we turn off
+ -- the timer signal when making calls to editline. (#2277)
+ -- If editline is ever fixed, we can remove this.
+
+-- These come from the RTS
+foreign import ccall unsafe startTimer :: IO ()
+foreign import ccall unsafe stopTimer :: IO ()
#endif
queryQueue :: GHCi (Maybe String)
#include "Schedule.h"
#include "Sparks.h"
#include "RtsTypeable.h"
+#include "Timer.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
SymX(stackOverflow) \
SymX(stg_CAF_BLACKHOLE_info) \
SymX(awakenBlockedQueue) \
+ SymX(startTimer) \
SymX(stg_CHARLIKE_closure) \
SymX(stg_MVAR_CLEAN_info) \
SymX(stg_MVAR_DIRTY_info) \