123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- //go:build windows
- package hcsshim
- import (
- "context"
- "io"
- "sync"
- "time"
- "github.com/Microsoft/hcsshim/internal/hcs"
- )
- // ContainerError is an error encountered in HCS
- type process struct {
- p *hcs.Process
- waitOnce sync.Once
- waitCh chan struct{}
- waitErr error
- }
- // Pid returns the process ID of the process within the container.
- func (process *process) Pid() int {
- return process.p.Pid()
- }
- // Kill signals the process to terminate but does not wait for it to finish terminating.
- func (process *process) Kill() error {
- found, err := process.p.Kill(context.Background())
- if err != nil {
- return convertProcessError(err, process)
- }
- if !found {
- return &ProcessError{Process: process, Err: ErrElementNotFound, Operation: "hcsshim::Process::Kill"}
- }
- return nil
- }
- // Wait waits for the process to exit.
- func (process *process) Wait() error {
- return convertProcessError(process.p.Wait(), process)
- }
- // WaitTimeout waits for the process to exit or the duration to elapse. It returns
- // false if timeout occurs.
- func (process *process) WaitTimeout(timeout time.Duration) error {
- process.waitOnce.Do(func() {
- process.waitCh = make(chan struct{})
- go func() {
- process.waitErr = process.Wait()
- close(process.waitCh)
- }()
- })
- t := time.NewTimer(timeout)
- defer t.Stop()
- select {
- case <-t.C:
- return &ProcessError{Process: process, Err: ErrTimeout, Operation: "hcsshim::Process::Wait"}
- case <-process.waitCh:
- return process.waitErr
- }
- }
- // ExitCode returns the exit code of the process. The process must have
- // already terminated.
- func (process *process) ExitCode() (int, error) {
- code, err := process.p.ExitCode()
- if err != nil {
- err = convertProcessError(err, process)
- }
- return code, err
- }
- // ResizeConsole resizes the console of the process.
- func (process *process) ResizeConsole(width, height uint16) error {
- return convertProcessError(process.p.ResizeConsole(context.Background(), width, height), process)
- }
- // Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
- // these pipes does not close the underlying pipes; it should be possible to
- // call this multiple times to get multiple interfaces.
- func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, error) {
- stdin, stdout, stderr, err := process.p.StdioLegacy()
- if err != nil {
- err = convertProcessError(err, process)
- }
- return stdin, stdout, stderr, err
- }
- // CloseStdin closes the write side of the stdin pipe so that the process is
- // notified on the read side that there is no more data in stdin.
- func (process *process) CloseStdin() error {
- return convertProcessError(process.p.CloseStdin(context.Background()), process)
- }
- // Close cleans up any state associated with the process but does not kill
- // or wait on it.
- func (process *process) Close() error {
- return convertProcessError(process.p.Close(), process)
- }
|