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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
package hyper
import "fmt"
import "http"
import "bytes"
import "json"
import "os"
type Process struct {
Path string `json:"path"`
Argv []string `json:"argv"`
Envp map[string]string `json:"envp"`
//Stdin string `json:"stdin"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
process *os.Process
process_stdin *os.File
process_stdout *os.File
process_stderr *os.File
id string
client http.Client
}
func (p *Process) Id() string {
return p.id
}
func NewProcess(req *http.Request) (*Process, os.Error) {
body := make([]byte, 4096)
_, err := req.Body.Read(body)
if err != nil {
return nil, err
}
body = bytes.TrimRight(body, string([]byte{0}))
var p Process
if err := json.Unmarshal(body, &p); err != nil {
return nil, err
}
p.id = gensym()
if err := p.Start(); err != nil {
return nil, err
}
return &p, nil
}
func (hp *Process) Write(b []byte) {
n, err := hp.process_stdin.Write(b)
if err != nil {
fmt.Printf("Write: %s\n", err)
} else {
fmt.Printf("Wrote: %d bytes\n", n)
}
}
func (hp *Process) Start() os.Error {
var name = hp.Path //os.Args[1] //"/usr/b"
var argv = hp.Argv //os.Args[1:] //[]string{ "bc" }
//var chroot = false
//var dir = "/var/empty"
var files [3][2]*os.File
var err os.Error
for i, _ := range files {
files[i][0], files[i][1], err = os.Pipe()
if err != nil {
return err
}
}
var env []string
for k, v := range hp.Envp {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
var attr = &os.ProcAttr{
//Dir: dir,
Env: env, //os.Environ(),
Files: []*os.File{ files[0][0], files[1][1], files[2][1]},
}
//var foo, _ = json.Marshal(attr)
//fmt.Printf("%s\n", foo)
hp.process, err = os.StartProcess(name, argv, attr)
if err != nil {
return err
}
hp.process_stdin = files[0][1]
hp.process_stdout = files[1][0]
hp.process_stderr = files[2][0]
for _, file := range attr.Files {
file.Close()
}
go hp.reader(hp.process_stdout, hp.Stdout)
go hp.reader(hp.process_stderr, hp.Stderr)
return nil
}
func (p *Process) reader(file *os.File, url string) {
var b []byte = make([]byte, 1024)
var err os.Error = nil
for err == nil {
var n int
n, err = file.Read(b)
fmt.Printf("data: %d, %s\n", n, b)
res, err := p.client.Post(url, "application/octet-stream", bytes.NewBuffer(b))
res = res
if err != nil {
fmt.Printf("EE: %s: %s\n", url, err)
}
}
}
func gensym() string {
f, _ := os.Open("/dev/urandom")
b := make([]byte, 16)
f.Read(b)
f.Close()
uuid := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
return uuid
}
|