Reputation: 11
I am attempting to run a program from the commandline that will run indefinitely if the image file passed through the program is corrupted and/or the named is wrong. I can test to make sure the filename is valid, but that won't help me if a rootkit damaged the image. My understanding is that the only way to quit the program is to create a separate thread, but sys.process.!!
blocks until execution is completed.
val imageInfo: Option[String] = Some(s"python vol.py -f $memFile imageinfo".!!.trim)
Upvotes: 1
Views: 930
Reputation: 14217
You can use Future
with Await
to measure the too long Process, like:
import scala.concurrent.ExecutionContext.Implicits.global
val sb = new StringBuffer // sb for capture output
val io = BasicIO(false, sb, None)// Creates a `ProcessIO` that appends its output to a `StringBuffer`
val p = s"python vol.py -f $memFile imageinfo".run()
val f = Future {
p.exitValue() //Blocks until this process exits and returns the exit code.
Some(sb.toString)// return the process result
}
try {
val str: Option[String] = Await.result(f, Duration.apply(1, TimeUnit.SECONDS))
} catch {
case e: TimeoutException => {
println("run too long")
p.destroy() //destroy this process when too long
}
}
Upvotes: 0
Reputation: 51271
You don't have to let a Process
block until its completion.
import scala.sys.process.{Process, ProcessLogger}
var (iiOut, iiErr) = ("", "") // for collecting Process output
val getii = Process(s"python vol.py -f $memFile imageinfo")
.run(ProcessLogger(iiOut += _, iiErr += _))
// . . .
// do other useful stuff
// or set a timeout alarm and wait for it
// . . .
val imageInfo: Option[String] =
if (getii.isAlive()) {
// report failure
getii.destroy()
None
} else if (getii.exitValue() != 0 || iiErr != "") {
// report failure
None
} else
Some(iiOut.trim)
Upvotes: 1