go.talks/present: code cleanups

R=r
CC=golang-dev
https://golang.org/cl/6721050
diff --git a/present/socket.go b/present/socket.go
index 0cfd146..18795e7 100644
--- a/present/socket.go
+++ b/present/socket.go
@@ -14,30 +14,22 @@
 	"os"
 	"os/exec"
 	"path/filepath"
-	"runtime"
 	"strconv"
 
 	"code.google.com/p/go.net/websocket"
 )
 
-const socketPresent = true
+const (
+	socketPresent = true // tell main.go that socket is implemented
+	msgLimit      = 1000 // max number of messages to send per session
+)
 
+// HandleSocket registers the websocket handler with http.DefaultServeMux
+// under the given path.
 func HandleSocket(path string) {
 	http.Handle(path, websocket.Handler(socketHandler))
 }
 
-const msgLimit = 1000 // max number of messages to send per session
-
-var uniq = make(chan int) // a source of numbers for naming temporary files
-
-func init() {
-	go func() {
-		for i := 0; ; i++ {
-			uniq <- i
-		}
-	}()
-}
-
 // Message is the wire format for the websocket connection to the browser.
 // It is used for both sending output messages and receiving commands, as
 // distinguished by the Kind field.
@@ -109,6 +101,7 @@
 	out  chan<- *Message
 	done chan struct{} // closed when wait completes
 	run  *exec.Cmd
+	src  string // source file; to be removed when wait returns
 }
 
 // StartProcess builds and runs the given program, sending its output
@@ -119,13 +112,11 @@
 		out:  out,
 		done: make(chan struct{}),
 	}
-	cmd, err := p.start(body)
-	if err != nil {
+	if err := p.start(body); err != nil {
 		p.end(err)
 		return nil
 	}
-	p.run = cmd
-	go p.wait(cmd)
+	go p.wait()
 	return p
 }
 
@@ -134,49 +125,38 @@
 	if p == nil {
 		return
 	}
-	if p.run != nil {
-		p.run.Process.Kill()
-	}
-	<-p.done
+	p.run.Process.Kill()
+	<-p.done // block until process exits
 }
 
-// start builds and starts the given program, sending its output to p.out,
-// and returns the associated *exec.Cmd.
-func (p *Process) start(body string) (*exec.Cmd, error) {
-	// x is the base name for .go and executable files
-	x := filepath.Join(tmpdir, "compile"+strconv.Itoa(<-uniq))
-	src := x + ".go"
-	bin := x
-	if runtime.GOOS == "windows" {
-		bin += ".exe"
-	}
-
+// start runs the given program with "go run", sends its output to p.out,
+// and stores the running *exec.Command in the run field.
+func (p *Process) start(body string) error {
 	// write body to x.go
-	defer os.Remove(src)
+	src := filepath.Join(tmpdir, "compile"+strconv.Itoa(<-uniq)) + ".go"
 	if err := ioutil.WriteFile(src, []byte(body), 0666); err != nil {
-		return nil, err
+		return err
 	}
 
-	// build x.go, creating x
+	// run x.go
 	dir, file := filepath.Split(src)
-	err := p.cmd(dir, "go", "build", "-o", bin, file).Run()
-	defer os.Remove(bin)
-	if err != nil {
-		return nil, err
+	cmd := p.cmd(dir, "go", "run", file)
+	if err := cmd.Start(); err != nil {
+		os.Remove(src)
+		return err
 	}
 
-	// run x
-	cmd := p.cmd("", bin)
-	if err = cmd.Start(); err != nil {
-		return nil, err
-	}
-	return cmd, nil
+	p.run = cmd
+	p.src = src
+	return nil
 }
 
-// wait waits for the running process to complete and returns its error state.
-func (p *Process) wait(cmd *exec.Cmd) {
-	defer close(p.done)
-	p.end(cmd.Wait())
+// wait waits for the running process to complete
+// and sends its error state to the client.
+func (p *Process) wait() {
+	p.end(p.run.Wait())
+	close(p.done) // unblock waiting Kill calls
+	os.Remove(p.src)
 }
 
 // end sends an "end" message to the client, containing the process id and the
@@ -245,3 +225,13 @@
 		log.Fatal(err)
 	}
 }
+
+var uniq = make(chan int) // a source of numbers for naming temporary files
+
+func init() {
+	go func() {
+		for i := 0; ; i++ {
+			uniq <- i
+		}
+	}()
+}