// 处理系统信号 // 监听系统信号,重启或停止服务 func trapSignal(server client.Encoder) { sch := make(chan os.Signal, 10) signal.Notify(sch, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGINT, syscall.SIGHUP, syscall.SIGSTOP, syscall.SIGQUIT) go func(ch <-chan os.Signal) { sig := <-ch server.Shutdown("signal recieved " + sig.String() + ", at: " + time.Now().String()) if sig == syscall.SIGHUP { server.Info("autoencode restart now...") procAttr := new(os.ProcAttr) procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr} procAttr.Dir = os.Getenv("PWD") procAttr.Env = os.Environ() process, err := os.StartProcess(os.Args[0], os.Args, procAttr) if err != nil { server.Info("autoencode restart process failed:" + err.Error()) return } waitMsg, err := process.Wait() if err != nil { server.Info("autoencode restart wait error:" + err.Error()) } server.Info(waitMsg) } else { server.Info("autoencode shutdown now...") } }(sch) }
func (e *Environment) Spawn(cmd []string, extraVars map[string]string) (*int, error) { if len(cmd) == 0 { return nil, ErrInvalidCommand } // lookup the path of the executable cmdpath, err := exec.LookPath(cmd[0]) if err != nil { return nil, fmt.Errorf("Cannot find executable %s: %v", cmd[0], err) } // copy the extra vars so we can mutate it vars := make(map[string]string) for key, value := range extraVars { vars[key] = value } // start the agent sock, err := e.startProxyKeyring() if err != nil { return nil, err } vars["SSH_AUTH_SOCK"] = sock // start the process var attr os.ProcAttr attr.Env = e.buildEnviron(vars) attr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr} proc, err := os.StartProcess(cmdpath, cmd, &attr) if err != nil { return nil, fmt.Errorf("Failed to execute command: %v", err) } // wait for the process to exit state, _ := proc.Wait() var exitStatus int if !state.Success() { if status, ok := state.Sys().(syscall.WaitStatus); ok { exitStatus = status.ExitStatus() } else { exitStatus = 255 } } // we only return an error if spawning the process failed, not if // the spawned command returned a failure status code. return &exitStatus, nil }
// 执行截图 func exec(url, pic, width, height, delay string) (string, error) { if url == "" { return "", errors.New("url is none.") } if width == "" { width = strconv.Itoa(conf.width) } if height == "" { height = strconv.Itoa(conf.height) } if delay == "" { delay = strconv.Itoa(conf.delay) } procAttr := new(os.ProcAttr) procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr} procAttr.Dir = os.Getenv("PWD") procAttr.Env = os.Environ() var args []string args = make([]string, 7) args[0] = PHANTOMJS args[1] = conf.dir + "/" + SNAP_JS args[2] = url args[3] = pic args[4] = delay args[5] = width args[6] = height process, err := os.StartProcess(PHANTOMJS, args, procAttr) if err != nil { if conf.debug == true { log.Println("PhantomJS start failed:" + err.Error()) } return "", err } waitMsg, err := process.Wait() if err != nil { if conf.debug == true { log.Println("PhantomJS start wait error:" + err.Error()) } return "", err } if conf.debug == true { log.Println(waitMsg) } return args[3], nil }
func doExecution(task *TaskRequest, completionChannel chan<- *TaskResponse) { // we must notify the parent when we exit. defer func(c chan<- *TaskResponse, task *TaskRequest) { c <- task.MyResponse }(completionChannel, task) // first of all, verify that the score exists at all. score, exists := Scores[task.Score] if !exists { o.Warn("job%d: request for unknown score: %s", task.Id, task.Score) task.MyResponse.State = RESP_FAILED_UNKNOWN_SCORE return } si := NewScoreInterface(task) if si == nil { o.Warn("job%d: couldn't initialise score interface", task.Id) task.MyResponse.State = RESP_FAILED_HOST_ERROR return } if !si.Prepare() { o.Warn("job%d: couldn't prepare score interface", task.Id) task.MyResponse.State = RESP_FAILED_HOST_ERROR return } defer si.Cleanup() eenv := si.SetupProcess() task.MyResponse.State = RESP_RUNNING procenv := new(os.ProcAttr) // Build the default environment. procenv.Env = peSetEnv(procenv.Env, "PATH", "/usr/bin:/usr/sbin:/bin:/sbin") procenv.Env = peSetEnv(procenv.Env, "IFS", " \t\n") pwd, err := os.Getwd() if err != nil { task.MyResponse.State = RESP_FAILED_HOST_ERROR o.Warn("job%d: couldn't resolve PWD: %s", task.Id, err) return } procenv.Env = peSetEnv(procenv.Env, "PWD", pwd) // copy in the environment overrides for k, v := range eenv.Environment { procenv.Env = peSetEnv(procenv.Env, k, v) } // attach FDs to procenv. procenv.Files = make([]*os.File, 3) // first off, attach /dev/null to stdin and stdout devNull, err := os.OpenFile(os.DevNull, os.O_RDWR|os.O_APPEND, 0666) o.MightFail(err, "couldn't open DevNull") defer devNull.Close() for i := 0; i < 2; i++ { procenv.Files[i] = devNull } // attach STDERR to to our logger via pipe. lr, lw, err := os.Pipe() o.MightFail(err, "Couldn't create pipe") defer lw.Close() // lr will be closed by the logger. procenv.Files[2] = lw // check the environment's configuration and allow it to override stdin, stdout, and FDs 3+ if nil != eenv.Files { for i := range eenv.Files { if i < 2 { procenv.Files[i] = eenv.Files[i] } else { procenv.Files = append(procenv.Files, eenv.Files[i]) } } } var args []string args = append(args, eenv.Arguments...) o.Info("job%d: executing %s...", task.Id, score.Executable) go batchLogger(task.Id, lr) proc, err := os.StartProcess(score.Executable, args, procenv) if err != nil { o.Warn("job%d: failed to start process", task.Id) task.MyResponse.State = RESP_FAILED_HOST_ERROR return } wm, err := proc.Wait() if err != nil { o.Warn("job%d: error waiting for process", task.Id) task.MyResponse.State = RESP_FAILED_UNKNOWN // Worse of all, we don't even know if we succeeded. return } ws, _ := wm.Sys().(syscall.WaitStatus) if !(ws.Signaled() || ws.Exited()) { o.Assert("Non Terminal notification received when not expected.") return } if ws.Signaled() { o.Warn("job%d: process got signalled", task.Id) task.MyResponse.State = RESP_FAILED_UNKNOWN return } if ws.Exited() { if 0 == ws.ExitStatus() { o.Warn("job%d: process exited OK", task.Id) task.MyResponse.State = RESP_FINISHED } else { o.Warn("job%d: process exited with failure", task.Id) task.MyResponse.State = RESP_FAILED } return } o.Assert("Should never get here.") }