// ensureOwnerExists makes sure that at least one owner exists in the database. func (bot *Bot) ensureOwnerExists() { result, err := bot.Db.Query(`SELECT EXISTS(SELECT 1 FROM users WHERE owner=1 LIMIT 1);`) if err != nil { bot.Log.Fatalf("Can't check if owner exists: %s", err) } defer result.Close() if result.Next() { var ownerExists bool if err = result.Scan(&ownerExists); err != nil { bot.Log.Fatalf("Can't check if owner exists: %s", err) } if !ownerExists { bot.Log.Warningf("No owner found in the database. Must create one.") stty, _ := exec.LookPath("stty") sttyArgs := syscall.ProcAttr{ "", []string{}, []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}, nil, } reader := bufio.NewReader(os.Stdin) fmt.Print("Enter owner's nick: ") nick, _ := reader.ReadString('\n') // Disable echo. if stty != "" { syscall.ForkExec(stty, []string{"stty", "-echo"}, &sttyArgs) } // Get password. fmt.Print("Enter owner's password: "******"\nConfirm owner's password: "******"Passwords don't match.") } fmt.Print("\n") // Enable echo. if stty != "" { syscall.ForkExec(stty, []string{"stty", "echo"}, &sttyArgs) } result.Close() if bot.addUser(utils.CleanString(nick, false), utils.CleanString(pass1, false), true, true); err != nil { bot.Log.Fatalf("%s", err) } } } }
// echoOff turns off the terminal echo. func echoOff(fd []uintptr) (int, error) { pid, err := syscall.ForkExec(sttyArg0, sttyArgvEOff, &syscall.ProcAttr{Dir: "", Files: fd}) if err != nil { return 0, fmt.Errorf("failed turning off console echo for password entry:\n\t%s", err) } return pid, nil }
func (pluginReg *PluginReg) startPlugin(startFile string) (int, error) { // Change the file permission err := os.Chmod(startFile, 0777) if err != nil { log.DEBUG.Printf("Failed to change mode: %v", err) return 0, err } dir := filepath.Dir(startFile) startPath, _ := filepath.Abs(dir) file := path.Base(startFile) _, lookErr := exec.LookPath(startFile) if lookErr != nil { log.DEBUG.Printf("Lookerror") return 0, lookErr } env := os.Environ() attr := &syscall.ProcAttr{Dir: startPath, Env: env} pid, execErr := syscall.ForkExec(file, nil, attr) if execErr != nil { log.DEBUG.Printf("Exeerror") return 0, execErr } log.DEBUG.Printf("Started process: %d\n", pid) return pid, nil }
// echoOn turns back on the terminal echo. func echoOn(fd []uintptr) { // Turn on the terminal echo. pid, e := syscall.ForkExec(sttyArg0, sttyArgvEOn, &syscall.ProcAttr{Dir: "", Files: fd}) if e == nil { syscall.Wait4(pid, nil, 0, nil) } }
// execExternal executes an external command. func (ev *Evaluator) execExternal(fm *form) <-chan *StateUpdate { files := make([]uintptr, len(fm.ports)) for i, port := range fm.ports { if port == nil || port.f == nil { files[i] = FdNil } else { files[i] = port.f.Fd() } } args := make([]string, len(fm.args)+1) args[0] = fm.Path for i, a := range fm.args { // NOTE Maybe we should enfore string arguments instead of coercing all // args into string args[i+1] = a.String(ev) } sys := syscall.SysProcAttr{} attr := syscall.ProcAttr{Env: ev.env.Export(), Files: files[:], Sys: &sys} pid, err := syscall.ForkExec(fm.Path, args, &attr) // Streams are closed after fork-exec of external is complete. fm.closePorts(ev) update := make(chan *StateUpdate) if err != nil { update <- &StateUpdate{Terminated: true, Msg: err.Error()} close(update) } else { go waitStateUpdate(pid, update) } return update }
// maybeFork will fork & detach if background is true. First it will rename the out and // cache dirs so it's safe to run another plz in this repo, then fork & detach child // processes to do the actual cleaning. // The parent will then die quietly and the children will continue to actually remove the // directories. func maybeFork(outDir, cacheDir string, cleanCache bool) error { rm, err := exec.LookPath("rm") if err != nil { return err } if !core.PathExists(outDir) || !core.PathExists(cacheDir) { return nil } newOutDir, err := moveDir(outDir) if err != nil { return err } args := []string{rm, "-rf", newOutDir} if cleanCache { newCacheDir, err := moveDir(cacheDir) if err != nil { return err } args = append(args, newCacheDir) } // Note that we can't fork() directly and continue running Go code, but ForkExec() works okay. _, err = syscall.ForkExec(rm, args, nil) if err == nil { // Success if we get here. fmt.Println("Cleaning in background; you may continue to do pleasing things in this repo in the meantime.") os.Exit(0) } return err }
// 启动子进程执行新程序 func (this *Server) startNewProcess() error { listenerFd, err := this.listener.(*Listener).GetFd() if err != nil { return fmt.Errorf("failed to get socket file descriptor: %v", err) } path := os.Args[0] // 设置标识优雅重启的环境变量 environList := []string{} for _, value := range os.Environ() { if value != GRACEFUL_ENVIRON_STRING { environList = append(environList, value) } } environList = append(environList, GRACEFUL_ENVIRON_STRING) execSpec := &syscall.ProcAttr{ Env: environList, Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd(), listenerFd}, } fork, err := syscall.ForkExec(path, os.Args, execSpec) if err != nil { return fmt.Errorf("failed to forkexec: %v", err) } this.logf("start new process success, pid %d.", fork) return nil }
// spawn spawns the given filename in background using syscall func spawn(name string) { filepath := path.Join("/init/services", name) stdinpath := path.Join("/logs/", name+".stdin") stdoutpath := path.Join("/logs/", name+".stdout") stderrpath := path.Join("/logs/", name+".stderr") os.MkdirAll(path.Dir(stdinpath), 0777) os.MkdirAll(path.Dir(stdoutpath), 0777) os.MkdirAll(path.Dir(stderrpath), 0777) fstdin, err := os.Create(stdinpath) if err != nil { log.Println("waat", err) } fstdout, err := os.Create(stdoutpath) if err != nil { log.Println("waat", err) } fstderr, err := os.Create(stderrpath) if err != nil { log.Println("waat", err) } // Open Files for stdout, stderr procAttr := &syscall.ProcAttr{ Dir: "/", Env: []string{"MYVAR=345"}, Files: []uintptr{fstdin.Fd(), fstdout.Fd(), fstderr.Fd()}, Sys: nil, } pid, err := syscall.ForkExec(filepath, nil, procAttr) if err != nil { log.WithFields(log.Fields{ "service": filepath, "error": err, }).Error("Could not start service.") } else { log.WithFields(log.Fields{ "service": filepath, "pid": pid, }).Info("Started service succesfully") } log.Info("Waiting for 3 seconds") time.Sleep(3 * time.Second) a, err1 := ioutil.ReadFile(stdoutpath) b, err2 := ioutil.ReadFile(stderrpath) if err1 != nil || err2 != nil { log.Error("Could not read", err1, err2) } else { log.WithFields(log.Fields{ "service": name, "stdout": string(a), "stderr": string(b), }).Info("Service ended.") } }
func newDirCache(config *core.Configuration) *dirCache { cache := new(dirCache) // Absolute paths are allowed. Relative paths are interpreted relative to the repo root. if config.Cache.Dir[0] == '/' { cache.Dir = config.Cache.Dir } else { cache.Dir = path.Join(core.RepoRoot, config.Cache.Dir) } // Make directory if it doesn't exist. if err := os.MkdirAll(cache.Dir, core.DirPermissions); err != nil { panic(fmt.Sprintf("Failed to create root cache directory %s: %s", cache.Dir, err)) } // Fire off the cache cleaner process. if config.Cache.DirCacheCleaner != "" && config.Cache.DirCacheCleaner != "none" { go func() { cleaner := core.ExpandHomePath(config.Cache.DirCacheCleaner) log.Info("Running cache cleaner: %s --dir %s --high_water_mark %s --low_water_mark %s", cleaner, cache.Dir, config.Cache.DirCacheHighWaterMark, config.Cache.DirCacheLowWaterMark) if _, err := syscall.ForkExec(cleaner, []string{ cleaner, "--dir", cache.Dir, "--high_water_mark", config.Cache.DirCacheHighWaterMark, "--low_water_mark", config.Cache.DirCacheLowWaterMark, }, nil); err != nil { log.Errorf("Failed to start cache cleaner: %s", err) } }() } return cache }
func (s *Server) Serve() error { log.Debug("this is ddbatman v4") s.running = true var sessionId int64 = 0 for s.running { select { case sessionChan <- sessionId: //do nothing default: //warnning! log.Warnf("TASK_CHANNEL is full!") } conn, err := s.Accept() if err != nil { log.Warning("accept error %s", err.Error()) continue } //allocate a sessionId for a session go s.onConn(conn) sessionId += 1 } if s.restart == true { log.Debug("Begin to restart graceful") listenerFile, err := s.listener.(*net.TCPListener).File() if err != nil { log.Fatal("Fail to get socket file descriptor:", err) } listenerFd := listenerFile.Fd() os.Setenv("_GRACEFUL_RESTART", "true") execSpec := &syscall.ProcAttr{ Env: os.Environ(), Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd(), listenerFd}, } fork, err := syscall.ForkExec(os.Args[0], os.Args, execSpec) if err != nil { return fmt.Errorf("failed to forkexec: %v", err) } log.Infof("start new process success, pid %d.", fork) } timeout := time.NewTimer(time.Minute) wait := make(chan struct{}) go func() { s.wg.Wait() wait <- struct{}{} }() select { case <-timeout.C: log.Error("server : Waittimeout error when close the service") return nil case <-wait: log.Info("server : all goroutine has been done") return nil } return nil }
func echoOff(pa syscall.ProcAttr) int { pid, err := syscall.ForkExec(sttyCmd, sttyArgvEchoOff, &pa) if err != nil { fmt.Printf("Error setting echo off: %s\n", err) } return pid }
func echoOn(pa syscall.ProcAttr) { pid, err := syscall.ForkExec(sttyCmd, sttyArgvEchoOn, &pa) if err == nil { syscall.Wait4(pid, &waitStatus, 0, nil) } else { fmt.Printf("Error setting echo on: %s\n", err) } }
func echoOff(fd []uintptr) (int, error) { pid, err := syscall.ForkExec(sttyArg0, sttyArgvEOff, &syscall.ProcAttr{Dir: exec_cwdir, Files: fd}) if err != nil { return 0, fmt.Errorf("failed turning off console echo for password entry:\n{{.ErrorDescription}}", map[string]interface{}{"ErrorDescription": err}) } return pid, nil }
// setup and fork/exec myself. Make sure to keep open important FD's that won't get re-created by the child // specifically, std* and your listen socket func forker(srv *falcore.Server) (pid int, err int) { fmt.Printf("Forking now with socket: %v\n", srv.SocketFd()) mypath := os.Args[0] args := []string{mypath, "-socket", fmt.Sprintf("%v", srv.SocketFd())} attr := new(syscall.ProcAttr) attr.Files = append([]int(nil), 0, 1, 2, srv.SocketFd()) pid, err = syscall.ForkExec(mypath, args, attr) return }
func echoOff(fd []uintptr) (int, error) { pid, err := syscall.ForkExec(sttyArg0, sttyArgvEOff, &syscall.ProcAttr{Dir: exec_cwdir, Files: fd}) if err != nil { //Removed error and replaced with nil return 0, nil } return pid, nil }
func (pm *ProcessManager) doStart(executablePath string, args []string, procattr *syscall.ProcAttr) { var err error log.Infof("Getting Ready to start process: %v with args: %v and ProcAttr: %+v", executablePath, args, procattr) pm.pid, err = syscall.ForkExec(executablePath, args, procattr) if err != nil { log.Panicf("Error starting process %v", err) } else { log.Infof("Process Manager started to manage %v at PID: %v", executablePath, pm.pid) } }
func forkMyself() error { exe, err := platform.Getexe() os.Setenv(MAGICENV, Viper.GetString("socket")) attr := &syscall.ProcAttr{ Dir: "/", Env: os.Environ(), Files: []uintptr{0, 1, 2}} _, err = syscall.ForkExec(exe, os.Args, attr) return err }
// Call calls an external command. func (e ExternalCmd) Call(ec *EvalCtx, argVals []Value, opts map[string]Value) { if len(opts) > 0 { throw(ErrExternalCmdOpts) } if util.DontSearch(e.Name) { stat, err := os.Stat(e.Name) if err == nil && stat.IsDir() { // implicit cd if len(argVals) > 0 { throw(ErrCdNoArg) } cdInner(e.Name, ec) return } } files := make([]uintptr, len(ec.ports)) for i, port := range ec.ports { if port == nil || port.File == nil { files[i] = fdNil } else { files[i] = port.File.Fd() } } args := make([]string, len(argVals)+1) for i, a := range argVals { // NOTE Maybe we should enfore string arguments instead of coercing all // args into string args[i+1] = ToString(a) } sys := syscall.SysProcAttr{Setpgid: ec.background} attr := syscall.ProcAttr{Env: os.Environ(), Files: files[:], Sys: &sys} path, err := ec.Search(e.Name) if err != nil { throw(err) } args[0] = path pid, err := syscall.ForkExec(path, args, &attr) if err != nil { throw(errors.New("forkExec: " + err.Error())) } var ws syscall.WaitStatus _, err = syscall.Wait4(pid, &ws, syscall.WUNTRACED, nil) if err != nil { throw(fmt.Errorf("wait: %s", err.Error())) } else { maybeThrow(NewExternalCmdExit(e.Name, ws, pid)) } }
// echoOn turns back on the terminal echo. func echoOn(fd []uintptr) { sttyArg0, sttyErr := getSttyArg0() if sttyErr != nil { return } // Turn on the terminal echo. pid, e := syscall.ForkExec(sttyArg0, sttyArgvEOn, &syscall.ProcAttr{Dir: "", Files: fd}) if e == nil { syscall.Wait4(pid, &ws, 0, nil) } }
func spawnServer(cl libkb.CommandLine) (err error) { var files []uintptr var cmd string var args []string var devnull, log *os.File var pid int defer func() { if err != nil { if devnull != nil { devnull.Close() } if log != nil { log.Close() } } }() if devnull, err = os.OpenFile("/dev/null", os.O_RDONLY, 0); err != nil { return } files = append(files, devnull.Fd()) if G.Env.GetSplitLogOutput() { files = append(files, uintptr(1), uintptr(2)) } else { if _, log, err = libkb.OpenLogFile(); err != nil { return } files = append(files, log.Fd(), log.Fd()) } attr := syscall.ProcAttr{ Env: os.Environ(), Sys: &syscall.SysProcAttr{Setsid: true}, Files: files, } cmd, args, err = makeServerCommandLine(cl) if err != nil { return err } pid, err = syscall.ForkExec(cmd, args, &attr) if err != nil { err = fmt.Errorf("Error in ForkExec: %s", err) } else { G.Log.Info("Forking background server with pid=%d", pid) } return err }
func getPassword() string { // turn echo off var ws syscall.WaitStatus = 0 idk := &syscall.ProcAttr{Dir: "", Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}} if pid, err := syscall.ForkExec("/bin/stty", []string{"stty", "-echo"}, idk); err == nil { syscall.Wait4(pid, &ws, 0, nil) } // read the password var password string fmt.Print("Enter your password: "******"/bin/stty", []string{"stty", "echo"}, idk); err == nil { syscall.Wait4(pid, &ws, 0, nil) } return password }
func main() { flag.Parse() fmt.Println(os.Args) wd, err := os.Getwd() if err != nil { panic(err) } fmt.Println("wd:", wd) p := "/home/vcap/app/bin/dumb" if *numChild > 0 { pid, err := syscall.ForkExec(p, []string{p, "-numChild", strconv.Itoa(*numChild - 1)}, &syscall.ProcAttr{ Env: os.Environ(), Dir: wd, }) if err != nil { panic(err) } fmt.Println("i made a first pid! it is:", pid) pid, err = syscall.ForkExec(p, []string{p, "-numChild", strconv.Itoa(*numChild - 1)}, &syscall.ProcAttr{ Env: os.Environ(), Dir: wd, }) if err != nil { panic(err) } fmt.Println("i made a second pid! it is:", pid) } for { fmt.Println("heartbeat") time.Sleep(time.Second) } }
func (su *Supervise) Daemon() { if su.background { su.FlushPid() return } else if su.daemon { os.Setenv("SU_BACKGROUND", "1") var procAttr = syscall.ProcAttr{ su.cwd, os.Environ(), nil, nil, } syscall.ForkExec(su.exec, os.Args, &procAttr) os.Exit(SU_OK) } }
// Call calls an external command. func (e ExternalCmd) Call(ec *evalCtx, argVals []Value) { if DontSearch(e.Name) { stat, err := os.Stat(e.Name) if err == nil && stat.IsDir() { // implicit cd cdInner(e.Name, ec) } } files := make([]uintptr, len(ec.ports)) for i, port := range ec.ports { if port == nil || port.f == nil { files[i] = fdNil } else { files[i] = port.f.Fd() } } args := make([]string, len(argVals)+1) for i, a := range argVals { // NOTE Maybe we should enfore string arguments instead of coercing all // args into string args[i+1] = ToString(a) } sys := syscall.SysProcAttr{} attr := syscall.ProcAttr{Env: os.Environ(), Files: files[:], Sys: &sys} path, err := ec.Search(e.Name) if err != nil { throw(errors.New("search: " + err.Error())) } args[0] = path pid, err := syscall.ForkExec(path, args, &attr) if err != nil { throw(errors.New("forkExec: " + err.Error())) } var ws syscall.WaitStatus _, err = syscall.Wait4(pid, &ws, 0, nil) if err != nil { throw(fmt.Errorf("wait:", err.Error())) } else { maybeThrow(waitStatusToError(ws)) } }
func pwinput(prompt string) (pw string, err error) { fmt.Print(prompt) cmd := "/bin/stty" args := []string{"stty", "-echo"} fd := []uintptr{uintptr(syscall.Stdin), uintptr(syscall.Stdout), uintptr(syscall.Stderr)} proc := new(syscall.ProcAttr) proc.Files = fd _, err = syscall.ForkExec(cmd, args, proc) if err != nil { return pw, errors.New("failed forkexec") } bytes := make([]byte, 1000) os.Stdin.Read(bytes) pw = strings.TrimRight(string(bytes), string([]byte{0})) pw = strings.TrimRight(pw, "\n") return }
// ForkExec forks the current process and invokes Exec with the file, arguments, // and environment specified by argv0, argv, and envv. It returns the process // id of the forked process and an Error, if any. The fd array specifies the // file descriptors to be set up in the new process: fd[0] will be Unix file // descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil entry // will cause the child to have no open file descriptor with that index. // If dir is not empty, the child chdirs into the directory before execing the program. func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*File) (pid int, err Error) { // Create array of integer (system) fds. intfd := make([]int, len(fd)) for i, f := range fd { if f == nil { intfd[i] = -1 } else { intfd[i] = f.Fd() } } p, e := syscall.ForkExec(argv0, argv, envv, dir, intfd) if e != 0 { return 0, &PathError{"fork/exec", argv0, Errno(e)} } return p, nil }
func detachCommand(command ...string) { sys := syscall.SysProcAttr{} files := []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()} attr := syscall.ProcAttr{ Env: os.Environ(), Files: files, Sys: &sys, } pid, err := syscall.ForkExec(command[0], command[1:], &attr) if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err.Error()) return } closePorts() waitPid(pid) }
func (su *Supervise) Spawn() { var args = make([]string, 3) args[0] = "/bin/bash" args[1] = "-c" args[2] = su.cmd var sysProcAttr = syscall.SysProcAttr{} sysProcAttr.Setsid = true var procAttr = syscall.ProcAttr{ su.cwd, os.Environ(), nil, &sysProcAttr, } var pid, _ = syscall.ForkExec("/bin/bash", args, &procAttr) su.pid = pid su.FlushStatus() su.WriteLog("child %d started", su.pid) }
// Exec executes an external command. func (e externalCmd) Exec(ec *evalCtx, argVals []Value) <-chan *stateUpdate { files := make([]uintptr, len(ec.ports)) for i, port := range ec.ports { if port == nil || port.f == nil { files[i] = fdNil } else { files[i] = port.f.Fd() } } args := make([]string, len(argVals)+1) for i, a := range argVals { // NOTE Maybe we should enfore string arguments instead of coercing all // args into string args[i+1] = toString(a) } sys := syscall.SysProcAttr{} attr := syscall.ProcAttr{Env: os.Environ(), Files: files[:], Sys: &sys} path, err := ec.search(e.Name) var pid int if err == nil { args[0] = path pid, err = syscall.ForkExec(path, args, &attr) } // Ports are closed after fork-exec of external is complete. ec.closePorts() update := make(chan *stateUpdate) if err != nil { go func() { update <- newExitedStateUpdate(newFailure(err.Error())) close(update) }() } else { go waitStateUpdate(pid, update) } return update }
// setup and fork/exec myself. Make sure to keep open important FD's that won't get re-created by the child // specifically, std* and your listen socket func forker(srv *falcore.Server) (pid int, err error) { var socket string // At version 1.0.3 the socket FD behavior changed and the fork socket is always 3 // 0 = stdin, 1 = stdout, 2 = stderr, 3 = acceptor socket // This is because the ForkExec dups all the saved FDs down to // start at 0. This is also why you MUST include 0,1,2 in the // attr.Files if goVersion103OrAbove() { socket = "3" } else { socket = fmt.Sprintf("%v", srv.SocketFd()) } fmt.Printf("Forking now with socket: %v\n", socket) mypath := os.Args[0] args := []string{mypath, "-socket", socket} attr := new(syscall.ProcAttr) attr.Files = append([]uintptr(nil), 0, 1, 2, uintptr(srv.SocketFd())) pid, err = syscall.ForkExec(mypath, args, attr) return }