-
Notifications
You must be signed in to change notification settings - Fork 0
/
acme.go
111 lines (102 loc) · 2.36 KB
/
acme.go
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
105
106
107
108
109
110
111
package main
import (
"fmt"
"io"
"os"
"os/user"
"strconv"
"strings"
"9fans.net/go/acme"
)
// We would use io.Copy except for a bug in acme
// where it crashes when reading trying to read more
// than the negotiated 9P message size.
func copyBody(w io.Writer, win *acme.Win) error {
buf := make([]byte, 8000)
for {
n, err := win.Read("body", buf)
if err == io.EOF {
break
}
if err != nil {
return err
}
if _, err := w.Write(buf[0:n]); err != nil {
return fmt.Errorf("write error: %v", err)
}
}
return nil
}
func acmeCurrentWin() (*acme.Win, error) {
winid := os.Getenv("winid")
if winid == "" {
return nil, fmt.Errorf("$winid not set - not running inside acme?")
}
id, err := strconv.Atoi(winid)
if err != nil {
return nil, fmt.Errorf("invalid $winid %q", winid)
}
if err := setNameSpace(); err != nil {
return nil, err
}
win, err := acme.Open(id, nil)
if err != nil {
return nil, fmt.Errorf("cannot open acme window: %v", err)
}
return win, nil
}
func runeOffset2ByteOffset(b []byte, off int) int {
r := 0
for i, _ := range string(b) {
if r == off {
return i
}
r++
}
return len(b)
}
func setNameSpace() error {
if ns := os.Getenv("NAMESPACE"); ns != "" {
return nil
}
ns, err := nsFromDisplay()
if err != nil {
return fmt.Errorf("cannot get name space: %v", err)
}
os.Setenv("NAMESPACE", ns)
return nil
}
// taken from src/lib9/getns.c
// This should go into goplan9/plan9/client.
func nsFromDisplay() (string, error) {
disp := os.Getenv("DISPLAY")
if disp == "" {
// original code had heuristic for OS X here;
// we'll just assume that and fail anyway if it
// doesn't work.
disp = ":0.0"
}
// canonicalize: xxx:0.0 => xxx:0
if i := strings.LastIndex(disp, ":"); i >= 0 {
if strings.HasSuffix(disp, ".0") {
disp = disp[:len(disp)-2]
}
}
// turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5)
disp = strings.Replace(disp, "/", "_", -1)
u, err := user.Current()
if err != nil {
return "", fmt.Errorf("cannot get current user name: %v", err)
}
ns := fmt.Sprintf("/tmp/ns.%s.%s", u.Username, disp)
_, err = os.Stat(ns)
if os.IsNotExist(err) {
return "", fmt.Errorf("no name space directory found")
}
if err != nil {
return "", fmt.Errorf("cannot stat name space directory: %v", err)
}
// heuristics for checking permissions and owner of name space
// directory omitted.
return ns, nil
}