wenzelm@45919
|
1 |
/* Title: Pure/System/system_channel.scala
|
wenzelm@45919
|
2 |
Author: Makarius
|
wenzelm@45919
|
3 |
|
wenzelm@45920
|
4 |
Portable system channel for inter-process communication, based on
|
wenzelm@45920
|
5 |
named pipes or sockets.
|
wenzelm@45919
|
6 |
*/
|
wenzelm@45919
|
7 |
|
wenzelm@45919
|
8 |
package isabelle
|
wenzelm@45919
|
9 |
|
wenzelm@45919
|
10 |
|
wenzelm@49424
|
11 |
import java.io.{InputStream, OutputStream, File => JFile, FileInputStream,
|
wenzelm@49424
|
12 |
FileOutputStream, IOException}
|
wenzelm@45920
|
13 |
import java.net.{ServerSocket, InetAddress}
|
wenzelm@45919
|
14 |
|
wenzelm@45919
|
15 |
|
wenzelm@45919
|
16 |
object System_Channel
|
wenzelm@45919
|
17 |
{
|
wenzelm@45931
|
18 |
def apply(use_socket: Boolean = false): System_Channel =
|
wenzelm@46031
|
19 |
if (Platform.is_windows) new Socket_Channel else new Fifo_Channel
|
wenzelm@45919
|
20 |
}
|
wenzelm@45919
|
21 |
|
wenzelm@45919
|
22 |
abstract class System_Channel
|
wenzelm@45919
|
23 |
{
|
wenzelm@45919
|
24 |
def isabelle_args: List[String]
|
wenzelm@45919
|
25 |
def rendezvous(): (OutputStream, InputStream)
|
wenzelm@45919
|
26 |
def accepted(): Unit
|
wenzelm@45919
|
27 |
}
|
wenzelm@45919
|
28 |
|
wenzelm@45919
|
29 |
|
wenzelm@45920
|
30 |
/** named pipes **/
|
wenzelm@45920
|
31 |
|
wenzelm@46122
|
32 |
private object Fifo_Channel
|
wenzelm@45919
|
33 |
{
|
wenzelm@46114
|
34 |
private val next_fifo = Counter()
|
wenzelm@45919
|
35 |
}
|
wenzelm@45919
|
36 |
|
wenzelm@46122
|
37 |
private class Fifo_Channel extends System_Channel
|
wenzelm@45919
|
38 |
{
|
wenzelm@45919
|
39 |
private def mk_fifo(): String =
|
wenzelm@45919
|
40 |
{
|
wenzelm@45919
|
41 |
val i = Fifo_Channel.next_fifo()
|
wenzelm@45919
|
42 |
val script =
|
wenzelm@45919
|
43 |
"FIFO=\"/tmp/isabelle-fifo-${PPID}-$$" + i + "\"\n" +
|
wenzelm@45919
|
44 |
"echo -n \"$FIFO\"\n" +
|
wenzelm@45919
|
45 |
"mkfifo -m 600 \"$FIFO\"\n"
|
wenzelm@45919
|
46 |
val (out, err, rc) = Isabelle_System.bash(script)
|
wenzelm@45919
|
47 |
if (rc == 0) out else error(err.trim)
|
wenzelm@45919
|
48 |
}
|
wenzelm@45919
|
49 |
|
wenzelm@45919
|
50 |
private def rm_fifo(fifo: String): Boolean =
|
wenzelm@49388
|
51 |
Path.explode(if (Platform.is_windows) fifo + ".lnk" else fifo).file.delete
|
wenzelm@45919
|
52 |
|
wenzelm@45919
|
53 |
private def fifo_input_stream(fifo: String): InputStream =
|
wenzelm@45919
|
54 |
{
|
wenzelm@46031
|
55 |
require(!Platform.is_windows)
|
wenzelm@46031
|
56 |
new FileInputStream(fifo)
|
wenzelm@45919
|
57 |
}
|
wenzelm@45919
|
58 |
|
wenzelm@45919
|
59 |
private def fifo_output_stream(fifo: String): OutputStream =
|
wenzelm@45919
|
60 |
{
|
wenzelm@46031
|
61 |
require(!Platform.is_windows)
|
wenzelm@46031
|
62 |
new FileOutputStream(fifo)
|
wenzelm@45919
|
63 |
}
|
wenzelm@45919
|
64 |
|
wenzelm@45919
|
65 |
|
wenzelm@45919
|
66 |
private val fifo1 = mk_fifo()
|
wenzelm@45919
|
67 |
private val fifo2 = mk_fifo()
|
wenzelm@45919
|
68 |
|
wenzelm@45919
|
69 |
val isabelle_args: List[String] = List ("-W", fifo1 + ":" + fifo2)
|
wenzelm@45919
|
70 |
|
wenzelm@45919
|
71 |
def rendezvous(): (OutputStream, InputStream) =
|
wenzelm@45919
|
72 |
{
|
wenzelm@45919
|
73 |
val output_stream = fifo_output_stream(fifo1)
|
wenzelm@45919
|
74 |
val input_stream = fifo_input_stream(fifo2)
|
wenzelm@45919
|
75 |
(output_stream, input_stream)
|
wenzelm@45919
|
76 |
}
|
wenzelm@45919
|
77 |
|
wenzelm@45919
|
78 |
def accepted() { rm_fifo(fifo1); rm_fifo(fifo2) }
|
wenzelm@45919
|
79 |
}
|
wenzelm@45920
|
80 |
|
wenzelm@45920
|
81 |
|
wenzelm@45920
|
82 |
/** sockets **/
|
wenzelm@45920
|
83 |
|
wenzelm@46122
|
84 |
private class Socket_Channel extends System_Channel
|
wenzelm@45920
|
85 |
{
|
wenzelm@45920
|
86 |
private val server = new ServerSocket(0, 2, InetAddress.getByName("127.0.0.1"))
|
wenzelm@45920
|
87 |
|
wenzelm@45920
|
88 |
def isabelle_args: List[String] = List("-T", "127.0.0.1:" + server.getLocalPort)
|
wenzelm@45920
|
89 |
|
wenzelm@45920
|
90 |
def rendezvous(): (OutputStream, InputStream) =
|
wenzelm@45920
|
91 |
{
|
wenzelm@45920
|
92 |
val socket = server.accept
|
wenzelm@45920
|
93 |
(socket.getOutputStream, socket.getInputStream)
|
wenzelm@45920
|
94 |
}
|
wenzelm@45920
|
95 |
|
wenzelm@45920
|
96 |
def accepted() { server.close }
|
wenzelm@45920
|
97 |
}
|