diff --git a/main-command/src/main/scala/sbt/BasicCommandStrings.scala b/main-command/src/main/scala/sbt/BasicCommandStrings.scala index 77a3b6fc3..754fd19c8 100644 --- a/main-command/src/main/scala/sbt/BasicCommandStrings.scala +++ b/main-command/src/main/scala/sbt/BasicCommandStrings.scala @@ -203,6 +203,7 @@ $AliasCommand name= "Provides an interactive prompt from which commands can be run on a server." def DashClient: String = "-client" def DashDashClient: String = "--client" + def CloseIOStreams: String = "--close-io-streams" def StashOnFailure: String = "sbtStashOnFailure" def PopOnFailure: String = "sbtPopOnFailure" diff --git a/main-command/src/main/scala/sbt/BasicKeys.scala b/main-command/src/main/scala/sbt/BasicKeys.scala index 985ed5879..942698870 100644 --- a/main-command/src/main/scala/sbt/BasicKeys.scala +++ b/main-command/src/main/scala/sbt/BasicKeys.scala @@ -114,6 +114,11 @@ object BasicKeys { "List of template resolver infos.", 1000 ) + private[sbt] val closeIOStreams = AttributeKey[Boolean]( + "close-io-streams", + "Toggles wheter or not to close system in, out and error when the server starts.", + 1000 + ) } case class TemplateResolverInfo(module: ModuleID, implementationClass: String) diff --git a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala index 10634bb83..c118e650c 100644 --- a/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala +++ b/main-command/src/main/scala/sbt/internal/client/NetworkClient.scala @@ -160,7 +160,7 @@ class NetworkClient( else Nil val args = color ++ superShell ++ arguments.sbtArguments - val cmd = arguments.sbtScript +: args + val cmd = arguments.sbtScript +: args :+ BasicCommandStrings.CloseIOStreams val process = new ProcessBuilder(cmd: _*) .directory(arguments.baseDirectory) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index cd513f456..2e26f1046 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -68,11 +68,14 @@ private[sbt] object xMain { NetworkClient.run(configuration, args) Exit(0) } else { - val state = StandardMain.initialState( - configuration, - Seq(defaults, early), - runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil - ) + val closeStreams = userCommands.exists(_ == BasicCommandStrings.CloseIOStreams) + val state = StandardMain + .initialState( + configuration, + Seq(defaults, early), + runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil + ) + .put(BasicKeys.closeIOStreams, closeStreams) StandardMain.runManaged(state) } } @@ -183,7 +186,8 @@ object StandardMain { sys.props.put("jna.nosys", "true") import BasicCommandStrings.isEarlyCommand - val userCommands = configuration.arguments.map(_.trim) + val userCommands = + configuration.arguments.map(_.trim).filterNot(_ == BasicCommandStrings.CloseIOStreams) val (earlyCommands, normalCommands) = (preCommands ++ userCommands).partition(isEarlyCommand) val commands = (earlyCommands ++ normalCommands).toList map { x => Exec(x, None) diff --git a/main/src/main/scala/sbt/internal/CommandExchange.scala b/main/src/main/scala/sbt/internal/CommandExchange.scala index 3d47351be..ad756d32d 100644 --- a/main/src/main/scala/sbt/internal/CommandExchange.scala +++ b/main/src/main/scala/sbt/internal/CommandExchange.scala @@ -217,6 +217,7 @@ private[sbt] final class CommandExchange { server = None firstInstance.set(false) } + if (s.get(BasicKeys.closeIOStreams).getOrElse(false)) Terminal.close() } s }