-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspawn.go
56 lines (44 loc) · 1.1 KB
/
spawn.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
package lib
import (
"log"
"os"
"os/exec"
"syscall"
"time"
)
// Spawner forks and execs given program, and also detaches form its control tty.
func (c *MyConfig) Spawner() {
for prg := range c.Channels.RunChan {
devnullR, _ := os.Open(os.DevNull)
devnullW, _ := os.OpenFile(os.DevNull, os.O_WRONLY|os.O_APPEND, 0644)
spa := syscall.SysProcAttr{
Setsid: true,
Foreground: false,
}
pa := syscall.ProcAttr{
Dir: os.Getenv(`HOME`),
Env: os.Environ(),
Files: []uintptr{devnullR.Fd(), devnullW.Fd(), devnullW.Fd()},
Sys: &spa,
}
bin, err := exec.LookPath(prg[0])
if err != nil {
log.Printf("Unable to spawn %s: %s", prg[0], err)
}
_, err = syscall.ForkExec(bin, prg, &pa)
if err != nil {
log.Printf("Unable to spawn %s: %s", prg[0], err)
}
// Close file errors we don't handle :) at all.
_ = devnullR.Close()
_ = devnullW.Close()
}
}
// CleanZombies reaps processes spawned by Spawner() and already exited.
func (c *MyConfig) CleanZombies() {
r := syscall.Rusage{}
for {
_, _ = syscall.Wait4(-1, nil, 0, &r)
time.Sleep(1 * time.Minute)
}
}