コード例 #1
0
ファイル: init.go プロジェクト: snormore/flynn
func babySit(process *os.Process) int {
	// Forward all signals to the app
	sigchan := make(chan os.Signal, 1)
	sigutil.CatchAll(sigchan)
	go func() {
		for sig := range sigchan {
			if sig == syscall.SIGCHLD {
				continue
			}
			process.Signal(sig)
		}
	}()

	// Wait for the app to exit.  Also, as pid 1 it's our job to reap all
	// orphaned zombies.
	var wstatus syscall.WaitStatus
	for {
		pid, err := syscall.Wait4(-1, &wstatus, 0, nil)
		if err == nil && pid == process.Pid {
			break
		}
	}

	return wstatus.ExitStatus()
}
コード例 #2
0
ファイル: tracer.go プロジェクト: yan/grace
// StartProcess kicks off the event loop and forever waits for signals from
// the traced process. This is currently done in a super-silly fashion and will
// hopefully benefit from Go channels/goroutines in the future.
func (p *Process) StartProcess() (ret int) {
	var status syscall.WaitStatus

L:
	for {
		_, err := syscall.Wait4( /*p.Pid*/ -1, &status, 0, nil)
		p.isRunning = false

		switch {
		// status == 0  means terminated??
		case status.Exited() || status == 0 || err != nil:
			ret = status.ExitStatus()
			break L
		case status.Stopped():
			if bp, hit := p.InBreakpoint(); hit {
				p.handleBreakpoint(bp)
			}

		//case status.Continued():
		//case status.CoreDump():
		//case status.Signaled():
		//case status.ExitStatus():
		//case status.StopSignal():
		//case status.TrapCause():
		default:
			// fmt.Printf("Got status: %v\n", status)
		}

		p.Continue()

	}
	return
}
コード例 #3
0
ファイル: parent.go プロジェクト: rhenium/poe
func handleSigchld(mpid int) *resultPack {
	for {
		var status syscall.WaitStatus
		var spid int
		var err error
		spid, err = syscall.Wait4(-mpid, &status, syscall.WNOHANG|syscall.WALL, nil)
		if err != nil {
			poePanic(err, "wait4 failed")
		} else if spid == 0 {
			return nil
		}

		if spid == mpid && status.Exited() {
			return &resultPack{POE_SUCCESS, status.ExitStatus(), ""}
		} else if spid == mpid && status.Signaled() {
			return &resultPack{POE_SIGNALED, -1, fmt.Sprintf("Program terminated with signal %d (%s)", int(status.Signal()), status.Signal().String())}
		} else if status.Stopped() {
			e := status >> 16 & 0xff
			switch e {
			case PTRACE_EVENT_SECCOMP:
				if res := handleSyscall(spid); res != nil {
					return res
				}
			case syscall.PTRACE_EVENT_CLONE, syscall.PTRACE_EVENT_FORK, syscall.PTRACE_EVENT_VFORK:
				syscall.PtraceCont(spid, 0)
			default:
				syscall.PtraceCont(spid, int(status.StopSignal()))
			}
		}
	}
}
コード例 #4
0
ファイル: exec.go プロジェクト: horryq/elvish
func printStatus(ws syscall.WaitStatus) string {
	switch {
	case ws.Exited():
		es := ws.ExitStatus()
		if es == 0 {
			return ""
		}
		return fmt.Sprintf("exited %v", es)
	case ws.Signaled():
		msg := fmt.Sprintf("signaled %v", ws.Signal())
		if ws.CoreDump() {
			msg += " (core dumped)"
		}
		return msg
	case ws.Stopped():
		msg := fmt.Sprintf("stopped %v", ws.StopSignal())
		trap := ws.TrapCause()
		if trap != -1 {
			msg += fmt.Sprintf(" (trapped %v)", trap)
		}
		return msg
	case ws.Continued():
		return "continued"
	default:
		return fmt.Sprintf("unknown status %v", ws)
	}
}
コード例 #5
0
ファイル: nelly.go プロジェクト: wxdublin/gop
// checkForDeath tries to clean up zombies and then checks if the
// process group is empty.
//
// It returns "true" if the answer is yes and there are no grace pings left
//
func (n *nelly) checkForDeath() bool {

	// Check if there are any zombies to eat. Process.Wait() doesn't
	// support the POSIX WNOHANG for portability reasons, so let's use
	// the syscall.Wait4() which is POSIX-only.
	var w syscall.WaitStatus
	rusage := syscall.Rusage{}
	zpid, err := syscall.Wait4(-1, &w, syscall.WNOHANG, &rusage)
	if err != nil {
		n.Error("Error in Wait4: %s", err.Error())
	}
	if zpid > 0 {
		n.Error("Ate a tasty zombie (pid was %d, status was %d)", zpid, w.ExitStatus())
	}

	if n.processGroupIsEmpty() {
		n.startGracePings--
		if n.startGracePings <= 0 {
			n.Error("Process group [%d] empty - exiting and hoping init sorts it all out", n.pgid)
			return true
		} else {
			n.Error("Process group [%d] empty - grace pings left [%d]", n.pgid, n.startGracePings)
		}
	} else {
		// We've had a good ping, no more Mr Nice Guy
		n.startGracePings = 0
	}
	return false
}
コード例 #6
0
ファイル: exec.go プロジェクト: firebitsbr/elvish
// waitStatusToError converts syscall.WaitStatus to an Error.
func waitStatusToError(ws syscall.WaitStatus) error {
	switch {
	case ws.Exited():
		es := ws.ExitStatus()
		if es == 0 {
			return nil
		}
		return errors.New(fmt.Sprint(es))
	case ws.Signaled():
		msg := fmt.Sprintf("signaled %v", ws.Signal())
		if ws.CoreDump() {
			msg += " (core dumped)"
		}
		return errors.New(msg)
	case ws.Stopped():
		msg := fmt.Sprintf("stopped %v", ws.StopSignal())
		trap := ws.TrapCause()
		if trap != -1 {
			msg += fmt.Sprintf(" (trapped %v)", trap)
		}
		return errors.New(msg)
	/*
		case ws.Continued():
			return newUnexitedStateUpdate("continued")
	*/
	default:
		return fmt.Errorf("unknown WaitStatus", ws)
	}
}
コード例 #7
0
ファイル: lib.go プロジェクト: zxwing/zanker
func Shell(f string, v ...interface{}) (retCode int, stdout, stderr string) {
	var so, se bytes.Buffer
	command := exec.Command("bash", "-c", fmt.Sprintf(f, v...))
	command.Stdout = &so
	command.Stderr = &se

	var waitStatus syscall.WaitStatus
	if err := command.Run(); err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus = exitError.Sys().(syscall.WaitStatus)
			retCode = waitStatus.ExitStatus()
		} else {
			// looks like a system error, for example, IO error
			panic(err)
		}
	} else {
		waitStatus = command.ProcessState.Sys().(syscall.WaitStatus)
		retCode = waitStatus.ExitStatus()
	}

	stdout = string(so.Bytes())
	stderr = string(se.Bytes())

	return
}
コード例 #8
0
ファイル: subprocess_linux.go プロジェクト: contester/runlib
func ChildWaitingFunc(pid int, sig chan *ChildWaitData) {
	var status syscall.WaitStatus
	var rusage syscall.Rusage
	result := &ChildWaitData{}
	for {
		wpid, err := syscall.Wait4(pid, &status, syscall.WUNTRACED|syscall.WCONTINUED, &rusage)
		if wpid != pid {
			continue
		}

		if status.Exited() {
			result.ExitCode = uint32(status.ExitStatus())
			break
		}
		if status.Stopped() {
			result.SuccessCode |= EF_STOPPED
			result.StopSignal = uint32(status.StopSignal())
			syscall.Kill(pid, syscall.SIGKILL)
		}
		if status.Signaled() {
			result.SuccessCode |= EF_KILLED_BY_OTHER
			result.KillSignal = uint32(status.Signal())
			break
		}
		if err != nil {
			break
		}
	}
	result.RusageCpuUser = time.Nanosecond * time.Duration(rusage.Utime.Nano())
	result.RusageCpuKernel = time.Nanosecond * time.Duration(rusage.Stime.Nano())
	sig <- result
	close(sig)
}
コード例 #9
0
ファイル: exec.go プロジェクト: wlihome/elvish
// waitStatusToStateUpdate converts syscall.WaitStatus to a StateUpdate.
func waitStatusToStateUpdate(ws syscall.WaitStatus) *stateUpdate {
	switch {
	case ws.Exited():
		es := ws.ExitStatus()
		if es == 0 {
			return newExitedStateUpdate(ok)
		}
		return newExitedStateUpdate(newFailure(fmt.Sprint(es)))
	case ws.Signaled():
		msg := fmt.Sprintf("signaled %v", ws.Signal())
		if ws.CoreDump() {
			msg += " (core dumped)"
		}
		return newUnexitedStateUpdate(msg)
	case ws.Stopped():
		msg := fmt.Sprintf("stopped %v", ws.StopSignal())
		trap := ws.TrapCause()
		if trap != -1 {
			msg += fmt.Sprintf(" (trapped %v)", trap)
		}
		return newUnexitedStateUpdate(msg)
	case ws.Continued():
		return newUnexitedStateUpdate("continued")
	default:
		return newUnexitedStateUpdate(fmt.Sprint("unknown status", ws))
	}
}
コード例 #10
0
ファイル: init.go プロジェクト: ably-forks/flynn
func babySit(process *os.Process) int {
	log := logger.New("fn", "babySit")

	// Forward all signals to the app
	sigchan := make(chan os.Signal, 1)
	sigutil.CatchAll(sigchan)
	go func() {
		for sig := range sigchan {
			log.Info("received signal", "type", sig)
			if sig == syscall.SIGCHLD {
				continue
			}
			log.Info("forwarding signal to command", "type", sig)
			process.Signal(sig)
		}
	}()

	// Wait for the app to exit.  Also, as pid 1 it's our job to reap all
	// orphaned zombies.
	var wstatus syscall.WaitStatus
	for {
		pid, err := syscall.Wait4(-1, &wstatus, 0, nil)
		if err == nil && pid == process.Pid {
			break
		}
	}

	if wstatus.Signaled() {
		log.Info("command exited due to signal")
		return 0
	}
	return wstatus.ExitStatus()
}
コード例 #11
0
ファイル: hello.go プロジェクト: ritzalam/voiceconfmanager
func ConvertOfficeDocToPdf2(file string) {
	args := []string{"-f", "pdf",
		"-eSelectPdfVersion=1",
		"-eReduceImageResolution=true",
		"-eMaxImageResolution=300",
		"-p",
		"8200",
		"-o",
		"~/foo1.pdf",
		"~/foo.pptx",
	}
	cmd := exec.Command("unoconv", args...)
	var waitStatus syscall.WaitStatus
	if err := cmd.Run(); err != nil {
		//fmt.Printf("Error:", err)
		// Did the command fail because of an unsuccessful exit code
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus = exitError.Sys().(syscall.WaitStatus)
			fmt.Printf("Failed: %d", waitStatus.ExitStatus())
		}
	} else {
		// Command was successful
		waitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
		fmt.Printf("Success: %d", waitStatus.ExitStatus())
	}
}
コード例 #12
0
ファイル: system.go プロジェクト: zealot-wei/go
func ExecBash(command string, args []string) (int, string, error) {
	cmd := exec.Command(command, args...)
	var waitStatus syscall.WaitStatus

	//Stdout buffer
	cmdOutput := &bytes.Buffer{}

	//Attach buffer to command stdout
	cmd.Stdout = cmdOutput

	//Execute command
	err := cmd.Run()

	defer func() {
		if r := recover(); r != nil {
			fmt.Printf("Command:%s execute error\n", command)
		}
	}()

	if err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus = exitError.Sys().(syscall.WaitStatus)
			return waitStatus.ExitStatus(), "", err
		} else {
			fmt.Println("something wrong")
		}
	}
	waitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
	return waitStatus.ExitStatus(), cmdOutput.String(), nil

}
コード例 #13
0
ファイル: main_linux.go プロジェクト: cloudfoundry/guardian
func waitForContainerToExit(dir string, containerPid int, signals chan os.Signal) (exitCode int) {
	for range signals {
		for {
			var status syscall.WaitStatus
			var rusage syscall.Rusage
			wpid, err := syscall.Wait4(-1, &status, syscall.WNOHANG, &rusage)
			if err != nil || wpid <= 0 {
				break // wait for next SIGCHLD
			}

			if wpid == containerPid {
				exitCode = status.ExitStatus()
				if status.Signaled() {
					exitCode = 128 + int(status.Signal())
				}

				ioWg.Wait() // wait for full output to be collected

				check(ioutil.WriteFile(filepath.Join(dir, "exitcode"), []byte(strconv.Itoa(exitCode)), 0700))
				return exitCode
			}
		}
	}

	panic("ran out of signals") // cant happen
}
コード例 #14
0
func (p *ProcessReaper) reap() {
	for {
		p.log.Debug("reap")
		var status syscall.WaitStatus
		var rusage syscall.Rusage
		wpid, err := p.wait4(-1, &status, syscall.WNOHANG, &rusage)

		if wpid == 0 || (wpid == -1 && err.Error() == "no child processes") {
			break
		}

		if err != nil {
			p.log.Error("reaper-wait-error", err, lager.Data{"wpid": wpid})
			break
		}

		p.log.Info("reaped", lager.Data{"pid": wpid, "status": status, "rusage": rusage})

		if ch, ok := p.waitChan(wpid); p.monitoredPids[wpid] && ok {
			ch <- status.ExitStatus()
			p.unmonitorPid(wpid)

			p.log.Info("wait-once-sent-exit-status", lager.Data{"pid": wpid, "status": status, "rusage": rusage})
		} else {
			p.log.Info("wait-once-not-found", lager.Data{"pid": wpid, "status": status, "rusage": rusage})
		}
	}
}
コード例 #15
0
ファイル: checks.go プロジェクト: qanx/bmad
// Called on running checks, to determine if they have finished
// running.
//
// If the Check has not finished executing, returns false.
//
// If the Check has been running for longer than its Timeout,
// a SIGTERM (and failing that a SIGKILL) is issued to forcibly
// terminate the rogue Check process. In either case, this returns
// as if the check has not yet finished, and Reap() will need to be
// called again to fully reap the Check
//
// If the Check has finished execution (on its own, or via forced
// termination), it will return true.
//
// Once complete, some additional meta-stats for the check execution
// are appended to the check output, to be submit up to bolo
func (self *Check) Reap() bool {
	pid := self.process.Process.Pid

	var ws syscall.WaitStatus
	status, err := syscall.Wait4(pid, &ws, syscall.WNOHANG, nil)
	if err != nil {
		log.Error("Error waiting on check %s[%d]: %s", self.Name, pid, err.Error())
		return false
	}
	if status == 0 {
		// self to see if we need to sigkill due to failed sigterm
		if time.Now().After(self.started_at.Add(time.Duration(self.Timeout+2) * time.Second)) {
			log.Warn("Check %s[%d] has been running too long, sending SIGKILL", self.Name, pid)
			if err := syscall.Kill(pid, syscall.SIGKILL); err != nil {
				log.Error("Error sending SIGKILL to check %s[%d]: %s", self.Name, pid, err.Error())
			}
			self.sig_kill = true
		}
		// self to see if we need to sigterm due to self timeout expiry
		if !self.sig_kill && time.Now().After(self.started_at.Add(time.Duration(self.Timeout)*time.Second)) {
			log.Warn("Check %s[%d] has been running too long, sending SIGTERM", self.Name, pid)
			if err := syscall.Kill(pid, syscall.SIGTERM); err != nil {
				log.Error("Error sending SIGTERM to check %s[%d]: %s", self.Name, pid, err.Error())
			}
			self.sig_term = true
		}
		return false
	}

	self.ended_at = time.Now()
	self.running = false
	self.duration = time.Since(self.started_at)
	self.latency = self.started_at.Sub(self.next_run)
	self.output = string(self.stdout.Bytes())
	self.err_msg = string(self.stderr.Bytes())

	if ws.Exited() {
		self.rc = ws.ExitStatus()
	} else {
		log.Debug("Check %s[%d] exited abnormally (signaled/stopped). Setting rc to UNKNOWN", self.Name, pid)
		self.rc = UNKNOWN
	}
	if self.rc > UNKNOWN {
		log.Debug("Check %s[%d] returned with an invalid exit code. Setting rc to UNKOWN", self.Name, pid)
		self.rc = UNKNOWN
	}

	self.reschedule()

	if self.ended_at.After(self.next_run) {
		timeout_triggered := "not reached"
		if self.sig_term || self.sig_kill {
			timeout_triggered = "reached"
		}
		log.Warn("Check %s[%d] took %0.3f seconds to run, at interval %d (timeout of %d was %s)",
			self.Name, pid, self.duration.Seconds(), self.Every, self.Timeout, timeout_triggered)
	}
	return true
}
コード例 #16
0
ファイル: utils.go プロジェクト: tomologic/wrench
func GetCommandExitCode(err error) int {
	var waitStatus syscall.WaitStatus
	if exitError, ok := err.(*exec.ExitError); ok {
		waitStatus = exitError.Sys().(syscall.WaitStatus)
		return waitStatus.ExitStatus()
	}
	return 0
}
コード例 #17
0
ファイル: proc.go プロジェクト: ric03uec/nstop
func (proc *Proc) Start() (safeExit bool, err error) {
	log.Printf("supervisor running command: %s\n", proc.command)
	commandParts := strings.Fields(proc.command)
	commandString := commandParts[0]
	commandArgs := commandParts[1:len(commandParts)]

	proc.cmd = exec.Command(commandString, commandArgs...)

	proc.cmd.Stdout = os.Stdout
	proc.cmd.Stderr = os.Stderr

	proc.AddSignalHandlers()
	cmdErr := proc.cmd.Start()
	if cmdErr != nil {
		log.Fatal(cmdErr)
	}

	done := make(chan error, 1)
	go func() {
		done <- proc.cmd.Wait()
	}()

	//process waits here
	exitCode := <-done
	if exitCode != nil {
		// Type Assertion of exitCode with exec.ExitError struct
		var waitStatus syscall.WaitStatus
		exitError, ok := exitCode.(*exec.ExitError)
		if ok {
			// exitError.Sys() returns system specific exit info
			// Type Assertion of exitError.Sys() to sysCall.Waitstatus for Unix
			waitStatus = exitError.Sys().(syscall.WaitStatus)
			exitStatus := waitStatus.ExitStatus()
			if exitStatus == 130 {
				log.Printf("Process killed manually, aborting restart \n")
				return true, nil
			} else {
				proc.exitCode = exitStatus
				proc.procError = fmt.Sprintf("%v", exitCode)
				log.Printf("%v", proc.procError)
				if proc.restartCount < proc.maxRestartCount {
					log.Printf("Restarting app, Restart count %d, Max restart count %d", proc.restartCount, proc.maxRestartCount)
					proc.restartCount += 1
					proc.Start()
				} else {
					log.Printf("Max restart count (%d) reached, exiting", proc.maxRestartCount)
					log.Printf("--------- Command exited ----------- \n")
				}
			}
		}
	} else {
		// command exited successfully with return code = 0
		proc.exitCode = 0
		proc.restartCount += 1
		proc.Start()
	}
	return true, nil
}
コード例 #18
0
ファイル: slave.go プロジェクト: swisscoders/gobuilder
func (self *server) Execute(req *pb.ExecutionRequest, resp pb.Builder_ExecuteServer) error {
	if len(req.Args) == 0 {
		return fmt.Errorf("Request has no command to execute.")
	}

	var args []string
	if len(req.Args) > 1 {
		args = req.Args[1:]
	}

	if req.BuildEnv == nil {
		return fmt.Errorf("No build environment present")
	} else if err := sig.VerifyEnv(req.BuildEnv); err != nil {
		return fmt.Errorf("Failure verifying build environment: %s", err)
	}
	cmd := exec.Command(req.Args[0], args...)
	cmd.Env = convertEnv(req.GetEnv())
	cmd.Stdin = bytes.NewReader(req.Stdin)
	cmd.Dir = req.BuildEnv.Path

	glog.V(1).Infof("Commands to execute %v (build dir: %s)", req, cmd.Dir)

	stdoutPipe, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}

	stderrPipe, err := cmd.StderrPipe()
	if err != nil {
		return err
	}

	if err = cmd.Start(); err != nil {
		return err
	}
	streamReader(stdoutPipe, stderrPipe, resp)
	err = cmd.Wait()

	var status syscall.WaitStatus
	if err != nil {
		if _, ok := err.(*exec.ExitError); ok {
			status = err.(*exec.ExitError).Sys().(syscall.WaitStatus)
		} else {
			return err
		}
	} else if cmd.ProcessState != nil {
		status = cmd.ProcessState.Sys().(syscall.WaitStatus)
	}
	s := &pb.Status{
		CoreDump:   status.CoreDump(),
		Exited:     status.Exited(),
		ExitStatus: int32(status.ExitStatus()),
		Signaled:   status.Signaled(),
		Signal:     int32(status.Signal()),
	}
	resp.Send(&pb.ExecutionResponse{Status: s})
	return nil
}
コード例 #19
0
ファイル: process.go プロジェクト: jojomi/go-script
// ExitCode returns the exit code of the command denoted by this struct
func (pr *ProcessResult) ExitCode() int {
	var waitStatus syscall.WaitStatus
	if exitError, ok := pr.ProcessError.(*exec.ExitError); ok {
		waitStatus = exitError.Sys().(syscall.WaitStatus)
	} else {
		waitStatus = pr.ProcessState.Sys().(syscall.WaitStatus)
	}
	return waitStatus.ExitStatus()
}
コード例 #20
0
ファイル: error.go プロジェクト: zhsj/elvish
func NewExternalCmdExit(name string, ws syscall.WaitStatus, pid int) error {
	if ws.Exited() && ws.ExitStatus() == 0 {
		return nil
	}
	if !ws.Stopped() {
		pid = 0
	}
	return ExternalCmdExit{ws, name, pid}
}
コード例 #21
0
ファイル: daemon.go プロジェクト: RoPe93/oz
func (d *daemonState) handleChildExit(pid int, wstatus syscall.WaitStatus) {
	d.Debug("Child process pid=%d exited from daemon with status %d", pid, wstatus.ExitStatus())
	for _, sbox := range d.sandboxes {
		if sbox.init.Process.Pid == pid {
			sbox.remove(d.log)
			return
		}
	}
	d.Notice("No sandbox found with oz-init pid = %d", pid)
}
コード例 #22
0
ファイル: commands_test.go プロジェクト: viking/go-hourglass
/* output diff */
func checkStringsEqual(expected, actual string) (ok bool, diff string, err error) {
	if expected == actual {
		ok = true
		return
	}

	var exp *os.File
	exp, err = ioutil.TempFile("", "expected")
	if err != nil {
		return
	}
	defer exp.Close()
	defer os.Remove(exp.Name())
	_, err = exp.Write([]byte(expected))
	if err != nil {
		return
	}
	exp.Sync()

	var act *os.File
	act, err = ioutil.TempFile("", "actual")
	if err != nil {
		return
	}
	defer act.Close()
	defer os.Remove(act.Name())
	_, err = act.Write([]byte(actual))
	if err != nil {
		return
	}
	act.Sync()

	// diff's exit status is 1 if the files differ, and Go returns an error
	// when the exit status is non-zero
	cmd := exec.Command("diff", "-u", exp.Name(), act.Name())
	var cmdOutput []byte
	cmdOutput, err = cmd.Output()
	if err != nil {
		var typeOk bool
		var exitErr *exec.ExitError
		exitErr, typeOk = err.(*exec.ExitError)
		if !typeOk {
			return
		}

		var status syscall.WaitStatus
		status, typeOk = exitErr.Sys().(syscall.WaitStatus)
		if !typeOk || status.ExitStatus() > 1 {
			return
		}
		err = nil
	}
	diff = string(cmdOutput)
	return
}
コード例 #23
0
ファイル: main_linux.go プロジェクト: cloudfoundry/guardian
func run() int {
	flag.Parse()

	runtime := flag.Args()[1] // e.g. runc
	dir := flag.Args()[2]     // bundlePath for run, processPath for exec
	containerId := flag.Args()[3]

	signals := make(chan os.Signal, 100)
	signal.Notify(signals, syscall.SIGCHLD)

	fd3 := os.NewFile(3, "/proc/self/fd/3")
	logFile := fmt.Sprintf("/proc/%d/fd/4", os.Getpid())
	logFD := os.NewFile(4, "/proc/self/fd/4")
	syncPipe := os.NewFile(5, "/proc/self/fd/5")
	pidFilePath := filepath.Join(dir, "pidfile")

	stdin, stdout, stderr, winsz := openPipes(dir)

	syncPipe.Write([]byte{0})

	var runcStartCmd *exec.Cmd
	if *tty {
		ttySlave := setupTty(stdin, stdout, pidFilePath, winsz, garden.WindowSize{Rows: *rows, Columns: *cols})
		runcStartCmd = exec.Command(runtime, "-debug", "-log", logFile, "exec", "-d", "-tty", "-console", ttySlave.Name(), "-p", fmt.Sprintf("/proc/%d/fd/0", os.Getpid()), "-pid-file", pidFilePath, containerId)
	} else {
		runcStartCmd = exec.Command(runtime, "-debug", "-log", logFile, "exec", "-p", fmt.Sprintf("/proc/%d/fd/0", os.Getpid()), "-d", "-pid-file", pidFilePath, containerId)
		runcStartCmd.Stdin = stdin
		runcStartCmd.Stdout = stdout
		runcStartCmd.Stderr = stderr
	}

	// we need to be the subreaper so we can wait on the detached container process
	system.SetSubreaper(os.Getpid())

	if err := runcStartCmd.Start(); err != nil {
		fd3.Write([]byte{2})
		return 2
	}

	var status syscall.WaitStatus
	var rusage syscall.Rusage
	_, err := syscall.Wait4(runcStartCmd.Process.Pid, &status, 0, &rusage)
	check(err)    // Start succeeded but Wait4 failed, this can only be a programmer error
	logFD.Close() // No more logs from runc so close fd

	fd3.Write([]byte{byte(status.ExitStatus())})
	if status.ExitStatus() != 0 {
		return 3 // nothing to wait for, container didn't launch
	}

	containerPid, err := parsePid(pidFilePath)
	check(err)

	return waitForContainerToExit(dir, containerPid, signals)
}
コード例 #24
0
ファイル: jstree.go プロジェクト: dirk/jstree
func ParseFile(file string) (*Program, error) {
	var status syscall.WaitStatus
	var exitCode int
	var err error

	acornPath := GetAcornPath()

	cmd := exec.Command(acornPath, "--ecma6", "--module", file)

	stdoutBuffer := &bytes.Buffer{}
	stderrBuffer := &bytes.Buffer{}

	cmd.Stdout = stdoutBuffer
	cmd.Stderr = stderrBuffer

	err = cmd.Run()
	if err != nil {
		exitError, _ := err.(*exec.ExitError)
		status = exitError.Sys().(syscall.WaitStatus)
		exitCode = status.ExitStatus()
	} else {
		exitCode = -1
	}

	stdoutBytes, err := ioutil.ReadAll(stdoutBuffer)
	if err != nil {
		log.Fatal(err)
	}

	stderrBytes, err := ioutil.ReadAll(stderrBuffer)
	if err != nil {
		log.Fatal(err)
	}

	if exitCode > -1 {
		if len(stdoutBytes) > 0 {
			fmt.Println(string(stdoutBytes))
		}
		if len(stderrBytes) > 0 {
			fmt.Println(string(stderrBytes))
		}

		return nil, fmt.Errorf("Exited with code: %d; %s", exitCode, string(stderrBytes))
	}

	json, err := simplejson.NewJson(stdoutBytes)
	if err != nil {
		return nil, err
	}

	return ParseProgram(json)
}
コード例 #25
0
ファイル: process.go プロジェクト: hbouvier/watchgod
func Wait(pid int) (int, error) {
	var wstat syscall.WaitStatus
	_, err := syscall.Wait4(pid, &wstat, 0, nil)
	if err != nil {
		if err.Error() != "no child processes" {
			log.Printf("[ERROR] [process] [%d] Wait >>> %s\n", pid, err)
			return -1, err
		}
		log.Printf("[DEBUG] [process] [%d] Wait >>> %s\n", pid, err)
		return -1, nil
	}

	status := wstat.ExitStatus()
	return status, nil
}
コード例 #26
0
ファイル: process.go プロジェクト: docker/containerd
func (p *process) Wait() (uint32, error) {
	if p.status != execution.Stopped {
		var wstatus syscall.WaitStatus
		_, err := syscall.Wait4(p.pid, &wstatus, 0, nil)
		if err != nil {
			// This process doesn't belong to us
			p.exitCode = execution.UnknownStatusCode
			return p.exitCode, nil
		}
		// TODO: implement kill-all if we are the init pid?
		p.status = execution.Stopped
		p.exitCode = uint32(wstatus.ExitStatus())
	}
	return p.exitCode, nil

}
コード例 #27
0
ファイル: execution.go プロジェクト: echocat/caretakerd
func (instance *Execution) runCommand(cmd *exec.Cmd) (values.ExitCode, error) {
	var waitStatus syscall.WaitStatus
	if err := cmd.Run(); err != nil {
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus = exitError.Sys().(syscall.WaitStatus)
			exitSignal := waitStatus.Signal()
			if exitSignal > 0 {
				return values.ExitCode(int(exitSignal) + 128), nil
			}
			return values.ExitCode(waitStatus.ExitStatus()), nil
		}
		return values.ExitCode(0), UnrecoverableError{error: err}
	}
	waitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
	return values.ExitCode(waitStatus.ExitStatus()), nil
}
コード例 #28
0
ファイル: init.go プロジェクト: tdr130/oz
func (st *initState) handleChildExit(pid int, wstatus syscall.WaitStatus) {
	st.log.Debug("Child process pid=%d exited from init with status %d", pid, wstatus.ExitStatus())
	track := st.children[pid].track
	if len(st.profile.Watchdog) > 0 {
		if track == true {
			track = false
		} else {
			track = !st.getProcessExists(st.profile.Watchdog)
		}
	}
	st.removeChildProcess(pid)
	if track == true && st.profile.AutoShutdown == oz.PROFILE_SHUTDOWN_YES {
		st.log.Info("Shutting down sandbox after child exit.")
		st.shutdown()
	}
}
コード例 #29
0
ファイル: volumes.go プロジェクト: rawlingsj/gofabric8
// if we are on minikube or minishift lets try to create the
// hostPath folders with relaxed persmissions
func configureHostPathVolume(c *k8sclient.Client, ns string, hostPath string, sshCommand string) error {
	cli := sshCommand

	if len(cli) == 0 {
		context, isMini, _ := util.GetMiniType()
		if isMini {
			cli = context
		}
	}
	if len(cli) == 0 {
		// lets default to using vagrant if we have a Vagrantfile
		if _, err := os.Stat("Vagrantfile"); err == nil {
			cli = "vagrant"
		}
	}
	if len(cli) == 0 {
		return nil
	}

	shellCommands := []string{
		fmt.Sprintf("sudo mkdir -p %s", hostPath),
		fmt.Sprintf("sudo chmod 777 %s", hostPath),
		fmt.Sprintf("echo hostPath is setup correctly at: %s", hostPath),
	}
	util.Infof("About to modify host paths on the VM via the command: %s\n", cli)

	for _, shellCmd := range shellCommands {
		args := []string{"ssh", fmt.Sprintf("/bin/sh -c '%s'", shellCmd)}
		cmd := exec.Command(cli, args...)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		var waitStatus syscall.WaitStatus
		if err := cmd.Run(); err != nil {
			printErr(err)
			if exitError, ok := err.(*exec.ExitError); ok {
				waitStatus = exitError.Sys().(syscall.WaitStatus)
				printStatus(waitStatus.ExitStatus())
			}
			return err
		} else {
			waitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus)
			printStatus(waitStatus.ExitStatus())
		}
	}
	return nil
}
コード例 #30
0
ファイル: hello.go プロジェクト: ismadeandres/h
func main() {

	//path search
	flag.Parse()
	root := flag.Arg(0)
	err3 := filepath.Walk(root, visit)
	fmt.Printf("filepath.Walk() returned %v\n", err3)

	// Now from anywhere else in your program, you can use this:
	log.Print("Hello Logs!")

	//cmdRun
	var (
		cmdOut []byte
		err    error
	)
	fmt.Println("Hello, new gopher!")
	cmd := "ls"
	args := []string{"-l", "-a"}
	if cmdOut, err = exec.Command(cmd, args...).Output(); err != nil {
		fmt.Println(err)
		fmt.Println("Ha habido algun error")
		os.Exit(1)
	}
	fmt.Println(string(cmdOut))
	//#	fini,_ := ini.Load("/tmp/example.ini")
	//#fmt.Println( ini.GetString("Wine","Grape" ) )

	cmd2 := exec.Command("ls", "/tmp")
	var waitStatus syscall.WaitStatus
	if err := cmd2.Run(); err != nil {
		printError(err)
		// Did the command fail because of an unsuccessful exit code
		if exitError, ok := err.(*exec.ExitError); ok {
			waitStatus = exitError.Sys().(syscall.WaitStatus)
			printOutput([]byte(fmt.Sprintf("%d", waitStatus.ExitStatus())))
		}
	} else {
		// Command was successful
		waitStatus = cmd2.ProcessState.Sys().(syscall.WaitStatus)
		printOutput([]byte(fmt.Sprintf("%d", waitStatus.ExitStatus())))
	}
}