diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/io/Process.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Process.scala | 202 |
1 files changed, 0 insertions, 202 deletions
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() -} - |