diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/cmd/program/Scmp.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/CompileSocket.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/InterpreterLoop.scala | 19 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/MainGenericRunner.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Process.scala | 202 |
5 files changed, 19 insertions, 226 deletions
diff --git a/src/compiler/scala/tools/cmd/program/Scmp.scala b/src/compiler/scala/tools/cmd/program/Scmp.scala index 25ead1fcf1..6f39c29a77 100644 --- a/src/compiler/scala/tools/cmd/program/Scmp.scala +++ b/src/compiler/scala/tools/cmd/program/Scmp.scala @@ -8,6 +8,7 @@ package cmd package program import nsc.io._ +import scala.sys.process._ object Scmp { private val scmpUsage = """ @@ -42,16 +43,16 @@ object Scmp { fromArgs(residualArgs.patch(1, toArgs(extras), 0)) def runCmd(cmd: String) = { - val output = Process(cmd, redirect = true).slurp() - - returning(File.makeTemp())(_ writeAll output) + val tmpfile = File.makeTemp() + (cmd #> tmpfile.jfile !) + tmpfile } val cmds = List(p1args, p2args) map createCmd println(cmds.mkString("Running command lines:\n ", "\n ", "")) val files = cmds map runCmd map (_.path) - val diff = Process("diff %s %s".format(files: _*)).slurp() + val diff = "diff %s %s".format(files: _*).!! if (diff.isEmpty) println("No differences.") else println(diff) diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala index 570066327f..cba1ce132e 100644 --- a/src/compiler/scala/tools/nsc/CompileSocket.scala +++ b/src/compiler/scala/tools/nsc/CompileSocket.scala @@ -11,9 +11,10 @@ import java.util.regex.Pattern import java.net._ import java.security.SecureRandom -import io.{ File, Path, Process, Socket } +import io.{ File, Path, Socket } import scala.util.control.Exception.catching import scala.tools.util.StringOps.splitWhere +import scala.sys.process._ /** This class manages sockets for the fsc offline compiler. */ class CompileSocket { @@ -47,7 +48,7 @@ class CompileSocket { protected def fatal(msg: String) = { fscError(msg) - throw new Exception("fsc failure") + sys.error("fsc failure") } protected def info(msg: String) = @@ -82,12 +83,10 @@ class CompileSocket { Seq(vmCommand) ++ vmArgs ++ Seq(serverClass) filterNot (_ == "") /** Start a new server; returns true iff it succeeds */ - private def startNewServer(vmArgs: String) { + private def startNewServer(vmArgs: String) = { val cmd = serverCommand(vmArgs split " " toSeq) - info("[Executed command: %s]" format cmd) - try Process exec cmd catch { - case ex: IOException => fatal("Cannot start compilation daemon.\ntried command: %s" format cmd) - } + info("[Executing command: %s]" format cmd) + (cmd.! == 0) || fatal("Cannot start compilation daemon.\ntried command: %s" format cmd) } /** The port identification file */ diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala index 7c25b36d7d..4131061faa 100644 --- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala +++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala @@ -9,6 +9,7 @@ import Predef.{ println => _, _ } import java.io.{ BufferedReader, FileReader, PrintWriter } import java.io.IOException +import scala.sys.process.Process import scala.tools.nsc.{ InterpreterResults => IR } import scala.tools.util.SignalManager import scala.annotation.tailrec @@ -17,7 +18,7 @@ import scala.collection.mutable.ListBuffer import scala.concurrent.ops import util.{ ClassPath } import interpreter._ -import io.{ File, Process } +import io.File // Classes to wrap up interpreter commands and their results // You can add new commands by adding entries to val commands @@ -317,17 +318,11 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite } /** fork a shell and run a command */ - def runShellCmd(line: String) { - // we assume if they're using :sh they'd appreciate being able to pipeline - interpreter.beQuietDuring { - interpreter.interpret("import _root_.scala.tools.nsc.io.Process.Pipe._") - } - val p = Process(line) - // only bind non-empty streams - def add(name: String, it: Iterator[String]) = - if (it.hasNext) interpreter.bind(name, "scala.List[String]", it.toList) - - List(("stdout", p.stdout), ("stderr", p.stderr)) foreach (add _).tupled + def runShellCmd(cmd: String) { + interpreter.beQuietDuring { interpreter.interpret("import _root_.scala.sys.process._") } + val xs = Process(cmd).lines + if (xs.nonEmpty) + interpreter.bind("stdout", "scala.Stream[String]", xs) } def withFile(filename: String)(action: File => Unit) { diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala index 702e3843fb..6b6f140dcc 100644 --- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala +++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala @@ -11,7 +11,7 @@ import java.lang.{ClassNotFoundException, NoSuchMethodException} import java.net.{ URL, MalformedURLException } import scala.tools.util.PathResolver -import io.{ File, Process } +import io.{ File } import util.{ ClassPath, ScalaClassLoader } import Properties.{ versionString, copyrightString } diff --git a/src/compiler/scala/tools/nsc/io/Process.scala b/src/compiler/scala/tools/nsc/io/Process.scala deleted file mode 100644 index 083b25f2a1..0000000000 --- a/src/compiler/scala/tools/nsc/io/Process.scala +++ /dev/null @@ -1,202 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2011 LAMP/EPFL - */ - -package scala.tools.nsc -package io - -import concurrent.ThreadRunner -import scala.annotation.tailrec -import scala.util.Properties.{ isWin, isMac, lineSeparator } -import scala.util.control.Exception.catching -import java.lang.{ Process => JProcess, ProcessBuilder => JProcessBuilder } -import java.io.{ IOException, InputStream, OutputStream, BufferedReader, InputStreamReader, PrintWriter, File => JFile } -import java.util.concurrent.LinkedBlockingQueue - -/** The <code>Process</code> object contains convenience functions - * for running external processes. - * - * An example usage: - * <pre> - * io.Process("ls", cwd = io.File("/")) foreach println - * </pre> - * - * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4109888 - * for a dated list of the many obstacles to a clean interface. - * - * This is not finished!! Do not rely upon it yet. - * - * TODO - remove requirement that process complete before we - * can get an iterator. - * - * @author Paul Phillips - * @since 2.8 - */ - -object Process -{ - def javaVmArguments: List[String] = { - import collection.JavaConversions._ - - java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toList - } - lazy val runtime = Runtime.getRuntime() - - class Pipe[T](xs: Seq[T], stringify: T => String) { - def |(cmd: String): Seq[String] = { - val p = Process(cmd) - xs foreach (x => p.stdin println stringify(x)) - p.stdin.close() - p.stdout.toList - } - } - - object Pipe { - /* After importing this implicit you can say for instance - * xs | "grep foo" | "grep bar" - * and it will execute shells and pipe input/output. You can - * also implicitly or explicitly supply a function which translates - * the opening sequence into Strings; if none is given toString is used. - * - * Also, once you use :sh in the repl, this is auto-imported. - */ - implicit def seqToPipelinedProcess[T] - (xs: Seq[T]) - (implicit stringify: T => String = (x: T) => x.toString): Pipe[T] = - { - new Pipe(xs, stringify) - } - } - - private[Process] class ProcessBuilder(val pb: JProcessBuilder) { - def this(cmd: String*) = this(new JProcessBuilder(cmd: _*)) - def start() = new Process(() => pb.start()) - - def withOnlyEnv(env: Map[String, String]): this.type = { - pb.environment.clear() - withEnv(env) - } - - def withEnv(env: Map[String,String]): this.type = { - if (env != null) { - val jmap = pb.environment() - for ((k, v) <- env) jmap.put(k, v) - } - this - } - - def withCwd(cwd: Path): this.type = { - if (cwd != null) - pb directory cwd.jfile - - this - } - def withRedirectedErrorStream(merged: Boolean): this.type = { - pb redirectErrorStream merged - this - } - - override def toString() = "ProcessBuilder(%s)" format pb.command() - } - - // This can be fleshed out if more variations come up - private val shell: String => Array[String] = - if (isWin) Array("cmd.exe", "/C", _) - else Array("sh", "-c", _) - - /** Executes the given command line in a shell. - * - * @param command the command line - * @return a Process object - */ - def apply( - command: String, - env: Map[String, String] = null, - cwd: Path = null, - redirect: Boolean = false - ): Process = - exec(shell(command), env, cwd, redirect) - - /** Executes the given command line. - * - * @param command the command line - * @return a Process object - */ - def exec( - command: Seq[String], - env: Map[String, String] = null, - cwd: Path = null, - redirect: Boolean = false - ): Process = - new ProcessBuilder(command: _*) withEnv env withCwd cwd withRedirectedErrorStream redirect start -} -import Process._ - -class Process(processCreator: () => JProcess) extends Iterable[String] { - lazy val process = processCreator() - - def exitValue(): Option[Int] = - catching(classOf[IllegalThreadStateException]) opt process.exitValue() - - def waitFor() = process.waitFor() - def destroy() = process.destroy() - def rerun() = new Process(processCreator) - - def slurp() = _out.slurp() - def stdout = iterator - def iterator = _out.iterator - def stderr = _err.iterator - lazy val stdin = new PrintWriter(_in, true) - - class StreamedConsumer(in: InputStream) extends Thread with Iterable[String] { - private val queue = new LinkedBlockingQueue[String] - private val reader = new BufferedReader(new InputStreamReader(in)) - - private def finish() { - // make sure this thread is complete - join() - } - - def slurp(): String = { - finish() - queue.toArray map (_ + lineSeparator) mkString - } - - def iterator = { - finish() - new Iterator[String] { - val it = queue.iterator() - def hasNext = it.hasNext - def next = it.next - } - } - override final def run() { - @tailrec def loop() { - reader.readLine match { - case null => - reader.close() - case x => - queue put x - loop() - } - } - - try loop() - catch { case _: IOException => () } - } - } - - private val _err = createConsumer(process.getErrorStream) - private val _out = createConsumer(process.getInputStream) - private val _in = process.getOutputStream() - - private def createConsumer(in: InputStream) = { - val t = new StreamedConsumer(in) - t setDaemon true - t.start() - t - } - - override def toString() = "Process(%s)" format process.toString() -} - |