Skip to content

Instantly share code, notes, and snippets.

@hisui
Created August 22, 2013 05:07
Show Gist options
  • Save hisui/6303412 to your computer and use it in GitHub Desktop.
Save hisui/6303412 to your computer and use it in GitHub Desktop.
Using java.lang.Process in Scala.
package jp.segfault.cvs.util
import scala.concurrent.duration.Duration
import scala.collection.mutable.ArrayBuffer
import scala.util.Try
import java.io._
case class TtyOutput(data:Array[Byte], isError:Boolean)
object TtyOutput {
def exec(cmd:Array[String], timeout:Duration):Try[Seq[TtyOutput]] =
Try(Runtime.getRuntime.exec(cmd)) flatMap (read _)
def read(process:Process):Try[Seq[TtyOutput]] = Try {
val stdout = process.getInputStream
val stderr = process.getErrorStream
var flag = false
val out1 = new ByteArrayOutputStream()
val out2 = new ByteArrayOutputStream()
val tmp = new ArrayBuffer[TtyOutput]()
val buf = new Array[Byte](2048)
def flow(in:InputStream, out:OutputStream) {
var n = in.available()
while (n > 0) {
in.read(buf, 0, buf.length min n) match {
case -1 => n = 0
case m => n -= m
out.write(buf, 0, m)
}
}
}
while (Try(process.exitValue()).isFailure) {
Thread.sleep(1)
flow(stdout, out1)
flow(stderr, out2)
flag = if (out1.size() * out2.size() == 0) out2.size() > 0
else {
val out = if (flag) out2 else out1
tmp += TtyOutput(out.toByteArray, flag)
out.reset()
!flag
}
}
val out = if (flag) out2 else out1
if (out.size() > 0) {
tmp += TtyOutput(out.toByteArray, flag)
}
tmp.toSeq
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment