...

Source file src/github.com/Microsoft/hcsshim/process.go

Documentation: github.com/Microsoft/hcsshim

     1  //go:build windows
     2  
     3  package hcsshim
     4  
     5  import (
     6  	"context"
     7  	"io"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/Microsoft/hcsshim/internal/hcs"
    12  )
    13  
    14  // ContainerError is an error encountered in HCS
    15  type process struct {
    16  	p        *hcs.Process
    17  	waitOnce sync.Once
    18  	waitCh   chan struct{}
    19  	waitErr  error
    20  }
    21  
    22  // Pid returns the process ID of the process within the container.
    23  func (process *process) Pid() int {
    24  	return process.p.Pid()
    25  }
    26  
    27  // Kill signals the process to terminate but does not wait for it to finish terminating.
    28  func (process *process) Kill() error {
    29  	found, err := process.p.Kill(context.Background())
    30  	if err != nil {
    31  		return convertProcessError(err, process)
    32  	}
    33  	if !found {
    34  		return &ProcessError{Process: process, Err: ErrElementNotFound, Operation: "hcsshim::Process::Kill"}
    35  	}
    36  	return nil
    37  }
    38  
    39  // Wait waits for the process to exit.
    40  func (process *process) Wait() error {
    41  	return convertProcessError(process.p.Wait(), process)
    42  }
    43  
    44  // WaitTimeout waits for the process to exit or the duration to elapse. It returns
    45  // false if timeout occurs.
    46  func (process *process) WaitTimeout(timeout time.Duration) error {
    47  	process.waitOnce.Do(func() {
    48  		process.waitCh = make(chan struct{})
    49  		go func() {
    50  			process.waitErr = process.Wait()
    51  			close(process.waitCh)
    52  		}()
    53  	})
    54  	t := time.NewTimer(timeout)
    55  	defer t.Stop()
    56  	select {
    57  	case <-t.C:
    58  		return &ProcessError{Process: process, Err: ErrTimeout, Operation: "hcsshim::Process::Wait"}
    59  	case <-process.waitCh:
    60  		return process.waitErr
    61  	}
    62  }
    63  
    64  // ExitCode returns the exit code of the process. The process must have
    65  // already terminated.
    66  func (process *process) ExitCode() (int, error) {
    67  	code, err := process.p.ExitCode()
    68  	if err != nil {
    69  		err = convertProcessError(err, process)
    70  	}
    71  	return code, err
    72  }
    73  
    74  // ResizeConsole resizes the console of the process.
    75  func (process *process) ResizeConsole(width, height uint16) error {
    76  	return convertProcessError(process.p.ResizeConsole(context.Background(), width, height), process)
    77  }
    78  
    79  // Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
    80  // these pipes does not close the underlying pipes; it should be possible to
    81  // call this multiple times to get multiple interfaces.
    82  func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
    83  	stdin, stdout, stderr, err := process.p.StdioLegacy()
    84  	if err != nil {
    85  		err = convertProcessError(err, process)
    86  	}
    87  	return stdin, stdout, stderr, err
    88  }
    89  
    90  // CloseStdin closes the write side of the stdin pipe so that the process is
    91  // notified on the read side that there is no more data in stdin.
    92  func (process *process) CloseStdin() error {
    93  	return convertProcessError(process.p.CloseStdin(context.Background()), process)
    94  }
    95  
    96  // Close cleans up any state associated with the process but does not kill
    97  // or wait on it.
    98  func (process *process) Close() error {
    99  	return convertProcessError(process.p.Close(), process)
   100  }
   101  

View as plain text