blob: 7d84e6dd0086277081df1e06aba137f87c3bcffd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package TeXLive
import java.io._
import TeXLive.OsTools._
import scala.collection.mutable.ArrayBuffer
import scala.concurrent.SyncVar
import scala.sys.process._
class TlmgrProcess(updout: String => Unit, upderr: String => Unit) {
val inputString = new SyncVar[String] // used for the tlmgr process input
// val outputString = new SyncVar[String] // used for the tlmgr process output
// val errorBuffer: StringBuffer = new StringBuffer() // buffer used for both tmgr process error console AND logging
val tlroot = "kpsewhich -var-value SELFAUTOPARENT".!!.trim
// println("tlroot ==" + tlroot + "==")
// set in only one place, in the main thread
var process: Process = _
def send_command(input: String): Unit = {
try {
assert(!inputString.isSet)
inputString.put(input)
} catch {
case exc: Throwable =>
upderr("Main thread: " +
(if (exc.isInstanceOf[NoSuchElementException]) "Timeout" else "Exception: " + exc))
}
}
def isAlive(): Boolean = {
if (process != null)
process.isAlive()
else
// return true on not-started process
true
}
def start_process(): Boolean = {
// process creation
if (process == null) {
val procIO = new ProcessIO(inputFn(_), outputFn(_, updout), outputFn(_, upderr))
val processBuilder: ProcessBuilder = Seq({if (isWindows) "tlmgr.bat" else "tlmgr"}, "-v", "--machine-readable", "shell")
process = processBuilder.run(procIO)
}
process.isAlive()
}
def cleanup(): Unit = {
if (process != null) {
send_command("quit")
process.destroy()
}
}
/* The standard input passing function */
private[this] def inputFn(stdin: OutputStream): Unit = {
val writer = new BufferedWriter(new OutputStreamWriter(stdin))
try {
var input = ""
while (true) {
input = inputString.take()
if (input == "quit") {
stdin.close()
return
} else {
writer.write(input + "\n")
// println("writing " + input + " to process")
writer.flush()
}
}
stdin.close()
} catch {
case exc: Throwable =>
stdin.close()
// println("Exception in inputFn thread: " + exc + "\n")
upderr("Input thread: Exception: " + exc + "\n")
}
}
private[this] def outputFn(outStr: InputStream, updfun: String => Unit): Unit = {
val reader = new BufferedReader(new InputStreamReader(outStr))
try {
var line: String = ""
while (true) {
line = reader.readLine
// println("DDD did read " + line + " from process")
try {
updfun(line)
} catch {
case exc: Throwable =>
upderr("Update output line function failed, continuing anyway. Exception: " + exc)
}
}
outStr.close()
} catch {
case exc: Throwable =>
outStr.close()
upderr("Output thread: Exception: " + exc + "\n")
}
}
}
|