2024-10-24 07:43:17 +02:00
|
|
|
//go:build windows
|
|
|
|
|
|
|
|
// Copyright 2024, Command Line Inc.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
package wsl
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/ubuntu/gowsl"
|
|
|
|
)
|
|
|
|
|
|
|
|
var RegisteredDistros = gowsl.RegisteredDistros
|
|
|
|
var DefaultDistro = gowsl.DefaultDistro
|
|
|
|
|
|
|
|
type Distro struct {
|
|
|
|
gowsl.Distro
|
|
|
|
}
|
|
|
|
|
|
|
|
type WslCmd struct {
|
|
|
|
c *gowsl.Cmd
|
|
|
|
wg *sync.WaitGroup
|
|
|
|
once *sync.Once
|
|
|
|
lock *sync.Mutex
|
|
|
|
waitErr error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Distro) WslCommand(ctx context.Context, cmd string) *WslCmd {
|
|
|
|
if ctx == nil {
|
|
|
|
panic("nil Context")
|
|
|
|
}
|
|
|
|
innerCmd := d.Command(ctx, cmd)
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
var lock *sync.Mutex
|
|
|
|
return &WslCmd{innerCmd, &wg, new(sync.Once), lock, nil}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *WslCmd) CombinedOutput() (out []byte, err error) {
|
|
|
|
return c.c.CombinedOutput()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) Output() (out []byte, err error) {
|
|
|
|
return c.c.Output()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) Run() error {
|
|
|
|
return c.c.Run()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) Start() (err error) {
|
|
|
|
return c.c.Start()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) StderrPipe() (r io.ReadCloser, err error) {
|
|
|
|
return c.c.StderrPipe()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) StdinPipe() (w io.WriteCloser, err error) {
|
|
|
|
return c.c.StdinPipe()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) StdoutPipe() (r io.ReadCloser, err error) {
|
|
|
|
return c.c.StdoutPipe()
|
|
|
|
}
|
|
|
|
func (c *WslCmd) Wait() (err error) {
|
|
|
|
c.wg.Add(1)
|
|
|
|
c.once.Do(func() {
|
|
|
|
c.waitErr = c.c.Wait()
|
|
|
|
})
|
|
|
|
c.wg.Done()
|
|
|
|
c.wg.Wait()
|
|
|
|
if c.waitErr != nil && c.waitErr.Error() == "not started" {
|
|
|
|
c.once = new(sync.Once)
|
|
|
|
return c.waitErr
|
|
|
|
}
|
|
|
|
return c.waitErr
|
|
|
|
}
|
2024-12-04 23:16:50 +01:00
|
|
|
func (c *WslCmd) ExitCode() int {
|
|
|
|
state := c.c.ProcessState
|
|
|
|
if state == nil {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return state.ExitCode()
|
|
|
|
}
|
2024-10-24 07:43:17 +02:00
|
|
|
func (c *WslCmd) GetProcess() *os.Process {
|
|
|
|
return c.c.Process
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *WslCmd) GetProcessState() *os.ProcessState {
|
|
|
|
return c.c.ProcessState
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *WslCmd) SetStdin(stdin io.Reader) {
|
|
|
|
c.c.Stdin = stdin
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *WslCmd) SetStdout(stdout io.Writer) {
|
|
|
|
c.c.Stdout = stdout
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *WslCmd) SetStderr(stderr io.Writer) {
|
|
|
|
c.c.Stdout = stderr
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetDistroCmd(ctx context.Context, wslDistroName string, cmd string) (*WslCmd, error) {
|
|
|
|
distros, err := RegisteredDistros(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, distro := range distros {
|
|
|
|
if distro.Name() != wslDistroName {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
wrappedDistro := Distro{distro}
|
|
|
|
return wrappedDistro.WslCommand(ctx, cmd), nil
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("wsl distro %s not found", wslDistroName)
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetDistro(ctx context.Context, wslDistroName WslName) (*Distro, error) {
|
|
|
|
distros, err := RegisteredDistros(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, distro := range distros {
|
|
|
|
if distro.Name() != wslDistroName.Distro {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
wrappedDistro := Distro{distro}
|
|
|
|
return &wrappedDistro, nil
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("wsl distro %s not found", wslDistroName)
|
|
|
|
}
|