-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
129 lines (109 loc) · 2.88 KB
/
main.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
import (
"flag"
"log"
"os"
"os/signal"
"os/user"
"strconv"
"syscall"
"github.com/goodplayer/dstart/dstartcore"
)
var username string
var wd string
var input string
var output string
var erroroutput string
var etoo bool
var configFilePath string
type arrayFlags []string
func (i *arrayFlags) String() string {
return "array flags."
}
func (i *arrayFlags) Set(value string) error {
*i = append(*i, value)
return nil
}
var env arrayFlags
func init() {
flag.StringVar(&username, "u", "", "-u username")
flag.StringVar(&wd, "wd", "", "-wd working_directory")
flag.Var(&env, "env", "-env key=value [-env key=value ...]")
flag.StringVar(&input, "in", "", "-in input_file")
flag.StringVar(&output, "out", "", "-out output_file (currently overwritten file not create a new one)")
flag.StringVar(&erroroutput, "err", "", "-err error_output_file (currently overwritten file not create a new one)")
flag.BoolVar(&etoo, "etoo", false, "-etoo : redirect error output to standard output")
flag.StringVar(&configFilePath, "c", "", "-c <toml config file> : this will override all the other parameters")
}
// dstart [options] executable [params...]
func main() {
flag.Parse()
if len(configFilePath) > 0 {
dstartcore.ProcessDstartFromConfigFile(configFilePath)
return
}
if len(flag.Args()) <= 0 {
log.Fatalln("should have executable file. illegal argument. usage: dstart [options] executable [params...]")
}
attr := new(os.ProcAttr)
attr.Dir = wd
if len(env) > 0 {
attr.Env = append(os.Environ(), env...)
} else {
attr.Env = append(os.Environ())
}
in := os.Stdin
if input != "" {
f, err := os.Open(input)
if err != nil {
log.Fatalln("open input file error: ", err)
}
in = f
}
out := os.Stdout
if output != "" {
f, err := os.OpenFile(output, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
log.Fatalln("open output file error: ", err)
}
out = f
}
erroutput := os.Stderr
if erroroutput != "" {
f, err := os.OpenFile(erroroutput, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
log.Fatalln("open error output file error: ", err)
}
erroutput = f
}
if etoo {
erroutput = out
}
attr.Files = []*os.File{in, out, erroutput} // input/output/error
// user
if username != "" {
u, err := user.Lookup(username)
if err != nil {
log.Fatalln(err)
}
attr.Sys = new(syscall.SysProcAttr)
attr.Sys.Credential = new(syscall.Credential)
uid, err := strconv.Atoi(u.Uid)
if err != nil {
log.Fatalln("strconv uid error: ", err)
}
gid, err := strconv.Atoi(u.Gid)
if err != nil {
log.Fatalln("strconv gid error: ", err)
}
attr.Sys.Credential.Uid = uint32(uid)
attr.Sys.Credential.Gid = uint32(gid)
}
p, err := os.StartProcess(flag.Args()[0], flag.Args(), attr)
signal.Ignore(syscall.SIGCHLD)
if err != nil {
log.Fatalln("start process error: ", err)
} else {
log.Println("start process. pid: ", p.Pid)
}
}