summaryrefslogtreecommitdiffstats
path: root/sandbox/hyper/process/src/hyper/process/process.go
blob: 18cf55fba98d4bb4fb84b1ee085561b93c3ac71f (plain)
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
}