diff --git a/util/collection/Signal.scala b/util/collection/Signal.scala index 3152d4d49..8bad472cd 100644 --- a/util/collection/Signal.scala +++ b/util/collection/Signal.scala @@ -2,7 +2,9 @@ package sbt object Signals { - def withHandler[T](handler: () => Unit, signal: String = "INT")(action: () => T): T = + val CONT = "CONT" + val INT = "INT" + def withHandler[T](handler: () => Unit, signal: String = INT)(action: () => T): T = { val result = try @@ -17,6 +19,13 @@ object Signals case Right(v) => v } } + def supported(signal: String): Boolean = + try + { + val signals = new Signals0 + signals.supported(signal) + } + catch { case e: LinkageError => false } } // Must only be referenced using a @@ -24,6 +33,13 @@ object Signals // block to private final class Signals0 { + def supported(signal: String): Boolean = + { + import sun.misc.Signal + try { new Signal(signal); true } + catch { case e: IllegalArgumentException => false } + } + // returns a LinkageError in `action` as Left(t) in order to avoid it being // incorrectly swallowed as missing Signal/SignalHandler def withHandler[T](signal: String, handler: () => Unit, action: () => T): Either[Throwable, T] = diff --git a/util/complete/LineReader.scala b/util/complete/LineReader.scala index 1cb90b55b..a48e4c141 100644 --- a/util/complete/LineReader.scala +++ b/util/complete/LineReader.scala @@ -35,7 +35,7 @@ abstract class JLine extends LineReader private[this] def readLineDirect(prompt: String, mask: Option[Char]): String = if(handleCONT) - Signals.withHandler(() => resume(), signal = "CONT")( () => readLineDirectRaw(prompt, mask) ) + Signals.withHandler(() => resume(), signal = Signals.CONT)( () => readLineDirectRaw(prompt, mask) ) else readLineDirectRaw(prompt, mask) private[this] def readLineDirectRaw(prompt: String, mask: Option[Char]): String = @@ -90,7 +90,7 @@ private object JLine def simple(historyPath: Option[File], handleCONT: Boolean = HandleCONT): SimpleReader = new SimpleReader(historyPath, handleCONT) val MaxHistorySize = 500 - val HandleCONT = !java.lang.Boolean.getBoolean("sbt.disable.cont") + val HandleCONT = !java.lang.Boolean.getBoolean("sbt.disable.cont") && Signals.supported(Signals.CONT) } trait LineReader