355 def err: String = cat_lines(err_lines) |
355 def err: String = cat_lines(err_lines) |
356 def add_err(s: String): Bash_Result = copy(err_lines = err_lines ::: List(s)) |
356 def add_err(s: String): Bash_Result = copy(err_lines = err_lines ::: List(s)) |
357 } |
357 } |
358 |
358 |
359 def bash_env(cwd: JFile, env: Map[String, String], script: String, |
359 def bash_env(cwd: JFile, env: Map[String, String], script: String, |
360 out_progress: String => Unit = (_: String) => (), |
360 progress_stdout: String => Unit = (_: String) => (), |
361 err_progress: String => Unit = (_: String) => ()): Bash_Result = |
361 progress_stderr: String => Unit = (_: String) => (), |
|
362 progress_limit: Option[Long] = None): Bash_Result = |
362 { |
363 { |
363 File.with_tmp_file("isabelle_script") { script_file => |
364 File.with_tmp_file("isabelle_script") { script_file => |
364 File.write(script_file, script) |
365 File.write(script_file, script) |
365 val proc = new Managed_Process(cwd, env, false, "bash", posix_path(script_file)) |
366 val proc = new Managed_Process(cwd, env, false, "bash", posix_path(script_file)) |
366 |
|
367 proc.stdin.close |
367 proc.stdin.close |
|
368 |
|
369 val limited = new Object { |
|
370 private var count = 0L |
|
371 def apply(progress: String => Unit)(line: String): Unit = synchronized { |
|
372 count = count + line.length + 1 |
|
373 progress_limit match { |
|
374 case Some(limit) if count > limit => proc.terminate |
|
375 case _ => |
|
376 } |
|
377 } |
|
378 } |
368 val (_, stdout) = |
379 val (_, stdout) = |
369 Simple_Thread.future("bash_stdout") { File.read_lines(proc.stdout, out_progress) } |
380 Simple_Thread.future("bash_stdout") { |
|
381 File.read_lines(proc.stdout, limited(progress_stdout)) |
|
382 } |
370 val (_, stderr) = |
383 val (_, stderr) = |
371 Simple_Thread.future("bash_stderr") { File.read_lines(proc.stderr, err_progress) } |
384 Simple_Thread.future("bash_stderr") { |
|
385 File.read_lines(proc.stderr, limited(progress_stderr)) |
|
386 } |
372 |
387 |
373 val rc = |
388 val rc = |
374 try { proc.join } |
389 try { proc.join } |
375 catch { case e: InterruptedException => proc.terminate; 130 } |
390 catch { case e: InterruptedException => proc.terminate; 130 } |
376 Bash_Result(stdout.join, stderr.join, rc) |
391 Bash_Result(stdout.join, stderr.join, rc) |