Source file 
src/os/exec_unix.go
     1  
     2  
     3  
     4  
     5  
     6  
     7  package os
     8  
     9  import (
    10  	"errors"
    11  	"syscall"
    12  	"time"
    13  )
    14  
    15  const (
    16  	
    17  	pidUnset    = 0
    18  	pidReleased = -1
    19  )
    20  
    21  func (p *Process) wait() (ps *ProcessState, err error) {
    22  	
    23  	if p.handle != nil {
    24  		
    25  		return p.pidfdWait()
    26  	} else {
    27  		
    28  		return p.pidWait()
    29  	}
    30  }
    31  
    32  func (p *Process) pidWait() (*ProcessState, error) {
    33  	
    34  	
    35  	
    36  	
    37  	
    38  	
    39  	switch p.pidStatus() {
    40  	case statusReleased:
    41  		return nil, syscall.EINVAL
    42  	}
    43  
    44  	
    45  	ready, err := p.blockUntilWaitable()
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	if ready {
    50  		
    51  		
    52  		p.doRelease(statusDone)
    53  		
    54  		
    55  		p.sigMu.Lock()
    56  		p.sigMu.Unlock()
    57  	}
    58  
    59  	var (
    60  		status syscall.WaitStatus
    61  		rusage syscall.Rusage
    62  	)
    63  	pid1, err := ignoringEINTR2(func() (int, error) {
    64  		return syscall.Wait4(p.Pid, &status, 0, &rusage)
    65  	})
    66  	if err != nil {
    67  		return nil, NewSyscallError("wait", err)
    68  	}
    69  	p.doRelease(statusDone)
    70  	return &ProcessState{
    71  		pid:    pid1,
    72  		status: status,
    73  		rusage: &rusage,
    74  	}, nil
    75  }
    76  
    77  func (p *Process) signal(sig Signal) error {
    78  	s, ok := sig.(syscall.Signal)
    79  	if !ok {
    80  		return errors.New("os: unsupported signal type")
    81  	}
    82  
    83  	
    84  	if p.handle != nil {
    85  		
    86  		return p.pidfdSendSignal(s)
    87  	} else {
    88  		
    89  		return p.pidSignal(s)
    90  	}
    91  }
    92  
    93  func (p *Process) pidSignal(s syscall.Signal) error {
    94  	if p.Pid == pidReleased {
    95  		return errProcessReleased
    96  	}
    97  	if p.Pid == pidUnset {
    98  		return errors.New("os: process not initialized")
    99  	}
   100  
   101  	p.sigMu.RLock()
   102  	defer p.sigMu.RUnlock()
   103  
   104  	switch p.pidStatus() {
   105  	case statusDone:
   106  		return ErrProcessDone
   107  	case statusReleased:
   108  		return errProcessReleased
   109  	}
   110  
   111  	return convertESRCH(syscall.Kill(p.Pid, s))
   112  }
   113  
   114  func convertESRCH(err error) error {
   115  	if err == syscall.ESRCH {
   116  		return ErrProcessDone
   117  	}
   118  	return err
   119  }
   120  
   121  func findProcess(pid int) (p *Process, err error) {
   122  	h, err := pidfdFind(pid)
   123  	if err == ErrProcessDone {
   124  		
   125  		
   126  		
   127  		return newDoneProcess(pid), nil
   128  	} else if err != nil {
   129  		
   130  		
   131  		return newPIDProcess(pid), nil
   132  	}
   133  	
   134  	return newHandleProcess(pid, h), nil
   135  }
   136  
   137  func (p *ProcessState) userTime() time.Duration {
   138  	return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
   139  }
   140  
   141  func (p *ProcessState) systemTime() time.Duration {
   142  	return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
   143  }
   144  
View as plain text