本文整理匯總了Golang中syscall.Wait4函數的典型用法代碼示例。如果您正苦於以下問題:Golang Wait4函數的具體用法?Golang Wait4怎麽用?Golang Wait4使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了Wait4函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: Run
func (t *tracerImpl) Run() (err error) {
if t.cmd.SysProcAttr == nil {
t.cmd.SysProcAttr = &syscall.SysProcAttr{Ptrace: true}
} else {
t.cmd.SysProcAttr.Ptrace = true
}
runtime.LockOSThread()
if err = t.cmd.Start(); err != nil {
return
}
var waitStatus syscall.WaitStatus
if _, err = syscall.Wait4(t.cmd.Process.Pid, &waitStatus, 0, nil); err != nil {
return
}
if waitStatus.Exited() {
return
}
// Set options to detect our syscalls
if err = syscall.PtraceSetOptions(t.cmd.Process.Pid, syscall.PTRACE_O_TRACESYSGOOD); err != nil {
return
}
var regsEntry, regsExit syscall.PtraceRegs
// Get first syscall
if err = syscall.PtraceGetRegs(t.cmd.Process.Pid, ®sEntry); err != nil {
return
}
var exited bool
for {
if exited, err = wait_for_syscall(t.cmd.Process.Pid); exited || err != nil {
return
}
// Get syscall info
if err = syscall.PtraceGetRegs(t.cmd.Process.Pid, ®sEntry); err != nil {
return
}
// Enter syscall
t.callback(regsEntry, false)
if exited, err = wait_for_syscall(t.cmd.Process.Pid); exited || err != nil {
return
}
// Get syscall returned value
if err = syscall.PtraceGetRegs(t.cmd.Process.Pid, ®sExit); err != nil {
return
}
t.callback(regsExit, true)
}
}
示例2: babySit
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()
}
示例3: Terminate
func (d *driver) Terminate(p *execdriver.Command) error {
// lets check the start time for the process
state, err := libcontainer.GetState(filepath.Join(d.root, p.ID))
if err != nil {
if !os.IsNotExist(err) {
return err
}
// TODO: Remove this part for version 1.2.0
// This is added only to ensure smooth upgrades from pre 1.1.0 to 1.1.0
data, err := ioutil.ReadFile(filepath.Join(d.root, p.ID, "start"))
if err != nil {
// if we don't have the data on disk then we can assume the process is gone
// because this is only removed after we know the process has stopped
if os.IsNotExist(err) {
return nil
}
return err
}
state = &libcontainer.State{InitStartTime: string(data)}
}
currentStartTime, err := system.GetProcessStartTime(p.ProcessConfig.Process.Pid)
if err != nil {
return err
}
if state.InitStartTime == currentStartTime {
err = syscall.Kill(p.ProcessConfig.Process.Pid, 9)
syscall.Wait4(p.ProcessConfig.Process.Pid, nil, 0, nil)
}
d.removeContainerRoot(p.ID)
return err
}
示例4: StartReaper
// StartReaper starts a goroutine to reap processes if called from a process
// that has pid 1.
func StartReaper() {
if os.Getpid() == 1 {
glog.V(4).Infof("Launching reaper")
go func() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGCHLD)
for {
// Wait for a child to terminate
sig := <-sigs
glog.V(4).Infof("Signal received: %v", sig)
for {
// Reap processes
glog.V(4).Infof("Waiting to reap")
cpid, _ := syscall.Wait4(-1, nil, syscall.WNOHANG, nil)
if cpid < 1 {
glog.V(4).Infof("No more processes to reap.")
break
}
glog.V(4).Infof("Reaped process with pid %d", cpid)
}
}
}()
}
}
示例5: reap
func (p *ProcessReaper) reap() {
for {
p.log.Debug("reap")
var status syscall.WaitStatus
var rusage syscall.Rusage
wpid, err := syscall.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); ok {
ch <- status.ExitStatus()
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})
}
}
}
示例6: Terminate
func (d *driver) Terminate(c *execdriver.Command) error {
defer d.cleanContainer(c.ID)
// lets check the start time for the process
active := d.activeContainers[c.ID]
if active == nil {
return fmt.Errorf("active container for %s does not exist", c.ID)
}
state, err := active.State()
if err != nil {
return err
}
pid := state.InitProcessPid
currentStartTime, err := system.GetProcessStartTime(pid)
if err != nil {
return err
}
if state.InitProcessStartTime == currentStartTime {
err = syscall.Kill(pid, 9)
syscall.Wait4(pid, nil, 0, nil)
}
return err
}
示例7: checkForDeath
// 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
}
示例8: monitor
func monitor(active chan bool, notify chan notification) {
for {
monitoring := <-active
for monitoring {
var rusage syscall.Rusage
var status syscall.WaitStatus
options := syscall.WUNTRACED
pid, err := syscall.Wait4(-1, &status, options, &rusage)
if err != nil {
println("Wait4:", err.Error())
}
if pid <= 0 {
break
}
if status.Stopped() {
if pid == task0.Job.Group {
incoming <- syscall.SIGTSTP
}
continue
}
if status.Signaled() {
if status.Signal() == syscall.SIGINT &&
pid == task0.Job.Group {
incoming <- syscall.SIGINT
}
status += 128
}
notify <- notification{pid, status}
monitoring = <-active
}
}
}
示例9: getPassword
// getPassword gets input hidden from the terminal from a user. This is
// accomplished by turning off terminal echo, reading input from the user and
// finally turning on terminal echo.
func getPassword() (password string, err error) {
sig := make(chan os.Signal, 10)
brk := make(chan bool)
// File descriptors for stdin, stdout, and stderr.
fd := []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}
// Setup notifications of termination signals to channel sig, create a process to
// watch for these signals so we can turn back on echo if need be.
signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGQUIT,
syscall.SIGTERM)
go catchSignal(fd, sig, brk)
// Turn off the terminal echo.
pid, err := echoOff(fd)
if err != nil {
return "", err
}
// Turn on the terminal echo and stop listening for signals.
defer signal.Stop(sig)
defer close(brk)
defer echoOn(fd)
syscall.Wait4(pid, nil, 0, nil)
line, err := readline()
if err == nil {
password = strings.TrimSpace(line)
} else {
err = fmt.Errorf("failed during password entry: %s", err)
}
return password, err
}
示例10: babySit
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: StartProcess
// 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
}
示例12: handleSigchld
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()))
}
}
}
}
示例13: waitForContainerToExit
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: CloneFrozen
func (c *CloneParams) CloneFrozen() (int, error) {
pid := callClone(c)
// TODO: clone errors?
c.CommWriter.Close()
c.stdhandles.Close()
c.comm = make(chan CommStatus)
go commReader(c.CommReader, c.comm)
var status syscall.WaitStatus
for {
wpid, err := syscall.Wait4(pid, &status, 0, nil) // TODO: rusage
if err != nil {
return -1, os.NewSyscallError("Wait4", err)
}
if wpid == pid {
break
}
}
if status.Stopped() && status.StopSignal() == syscall.SIGTRAP {
return pid, nil
}
if status.Exited() {
co, ok := <-c.comm
if ok {
return -1, childError(co)
}
return -1, fmt.Errorf("DAFUQ")
}
err := syscall.Kill(pid, syscall.SIGKILL)
if err != nil {
return -1, os.NewSyscallError("Kill", err)
}
return -1, fmt.Errorf("traps, signals, dafuq is this")
}
示例15: ChildWaitingFunc
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)
}