Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 73 lines (65 sloc) 2.08 kb
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
/* sbt -- Simple Build Tool
* Copyright 2009 Mark Harrah
*/
package xsbt

import java.io.{BufferedReader, BufferedWriter, InputStream, InputStreamReader, OutputStreamWriter, OutputStream}
import java.net.{InetAddress, ServerSocket, Socket}

object IPC
{
private val portMin = 1025
private val portMax = 65536
private val loopback = InetAddress.getByName(null) // loopback

def client[T](port: Int)(f: IPC => T): T =
ipc(new Socket(loopback, port))(f)

def pullServer[T](f: Server => T): T =
{
val server = makeServer
try { f(new Server(server)) }
finally { server.close() }
}
def makeServer: ServerSocket =
{
val random = new java.util.Random
def nextPort = random.nextInt(portMax - portMin + 1) + portMin
def createServer(attempts: Int): ServerSocket =
if(attempts > 0)
try { new ServerSocket(nextPort, 1, loopback) }
catch { case _: Exception => createServer(attempts - 1) }
else
error("Could not connect to socket: maximum attempts exceeded")
createServer(10)
}
def server[T](f: IPC => Option[T]): T = serverImpl(makeServer, f)
def server[T](port: Int)(f: IPC => Option[T]): T =
serverImpl(new ServerSocket(port, 1, loopback), f)
private def serverImpl[T](server: ServerSocket, f: IPC => Option[T]): T =
{
def listen(): T =
{
ipc(server.accept())(f) match
{
case Some(done) => done
case None => listen()
}
}

try { listen() }
finally { server.close() }
}
private def ipc[T](s: Socket)(f: IPC => T): T =
try { f(new IPC(s)) }
finally { s.close() }

final class Server private[IPC](s: ServerSocket) extends NotNull
{
def port = s.getLocalPort
def close() = s.close()
def connection[T](f: IPC => T): T = IPC.ipc(s.accept())(f)
}
}
final class IPC private(s: Socket) extends NotNull
{
def port = s.getLocalPort
private val in = new BufferedReader(new InputStreamReader(s.getInputStream))
private val out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream))

def send(s: String) = { out.write(s); out.newLine(); out.flush() }
def receive: String = in.readLine()
}
Something went wrong with that request. Please try again.