mirror of https://github.com/sbt/sbt.git
Handle ctrl+d in canonical mode
In canonical mode, System.in will return -1 for ctrl+d on an empty line. The result of this behavior was that if a user entered ctrl+d during run in a task that was reading from System.in, sbt would end up exiting whenever the task exited. This happened because the WriteableInputStream would close itself when it read -1 from the input stream, which it assumed meant that the underlying input stream itself had been closed. When the jline reader tried to read from the closed WriteableInputStream, it would throw an exception and if the line reader was for the console channel, it would be interpreted as the user had inputted ctrl+d in the sbt shell which is supposed to exit sbt. This change fixes that behavior so that sbt can continue reading input after the run task exits.
This commit is contained in:
parent
9f7985a2d9
commit
82d6a050de
|
|
@ -450,12 +450,16 @@ object Terminal {
|
|||
private[sbt] class WriteableInputStream(in: InputStream, name: String)
|
||||
extends SimpleInputStream
|
||||
with AutoCloseable {
|
||||
private[this] val isRaw = new AtomicBoolean(false)
|
||||
final def write(bytes: Int*): Unit = readThread.synchronized {
|
||||
bytes.foreach(b => buffer.put(b))
|
||||
}
|
||||
def setRawMode(toggle: Boolean): Unit = in match {
|
||||
case win: WindowsInputStream => win.setRawMode(toggle)
|
||||
case _ =>
|
||||
def setRawMode(toggle: Boolean): Unit = {
|
||||
isRaw.set(toggle)
|
||||
in match {
|
||||
case win: WindowsInputStream => win.setRawMode(toggle)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
private[this] val executor =
|
||||
Executors.newSingleThreadExecutor(r => new Thread(r, s"sbt-$name-input-reader"))
|
||||
|
|
@ -479,8 +483,8 @@ object Terminal {
|
|||
val _ = readQueue.take
|
||||
val b = in.read
|
||||
buffer.put(b)
|
||||
if (b != -1 && !Thread.interrupted()) impl()
|
||||
else closed.set(true)
|
||||
if (Thread.interrupted() || (b != -1 && !isRaw.get)) closed.set(true)
|
||||
else impl()
|
||||
}
|
||||
try impl()
|
||||
catch { case _: InterruptedException => closed.set(true) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue