Skip to content

Commit

Permalink
Merge pull request #454 from 99designs/fix-exec
Browse files Browse the repository at this point in the history
Do a real exec on execution
  • Loading branch information
mtibben authored Nov 18, 2019
2 parents 3bcd8a9 + 7b38071 commit 7ad5e22
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 37 deletions.
39 changes: 2 additions & 37 deletions cli/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import (
"fmt"
"log"
"os"
"os/exec"
"os/signal"
"strings"
"syscall"

"github.com/99designs/aws-vault/prompt"
"github.com/99designs/aws-vault/server"
Expand Down Expand Up @@ -180,42 +177,10 @@ func ExecCommand(app *kingpin.Application, input ExecCommandInput) {
}
}

cmd := exec.Command(input.Command, input.Args...)
cmd.Env = env
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
signal.Notify(input.Signals, os.Interrupt, os.Kill)

if err := cmd.Start(); err != nil {
err = exec(input.Command, input.Args, env)
if err != nil {
app.Fatalf("%v", err)
}
// wait for the command to finish
waitCh := make(chan error, 1)
go func() {
waitCh <- cmd.Wait()
close(waitCh)
}()

for {
select {
case sig := <-input.Signals:
if err = cmd.Process.Signal(sig); err != nil {
app.Errorf("%v", err)
break
}
case err := <-waitCh:
var waitStatus syscall.WaitStatus
if exitError, ok := err.(*exec.ExitError); ok {
waitStatus = exitError.Sys().(syscall.WaitStatus)
os.Exit(waitStatus.ExitStatus())
}
if err != nil {
app.Fatalf("%v", err)
}
return
}
}
}
}

Expand Down
42 changes: 42 additions & 0 deletions cli/exec_default.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// +build !linux,!darwin

package cli

import (
"errors"
"os"
osexec "os/exec"
"os/signal"
"syscall"
)

func exec(command string, args []string, env []string) error {
cmd := osexec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = env

sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan)

if err := cmd.Start(); err != nil {
return errors.New("Failed to start command: %v", err)
}

go func() {
for {
sig := <-sigChan
cmd.Process.Signal(sig)
}
}()

if err := cmd.Wait(); err != nil {
ecmd.Process.Signal(os.Kill)
return errors.New("Failed to wait for command termination: %v", err)
}

waitStatus := cmd.ProcessState.Sys().(syscall.WaitStatus)
os.Exit(waitStatus.ExitStatus())
return nil
}
21 changes: 21 additions & 0 deletions cli/exec_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// +build linux darwin

package cli

import (
osexec "os/exec"
"syscall"
)

func exec(command string, args []string, env []string) error {
argv0, err := osexec.LookPath(command)
if err != nil {
return err
}

argv := make([]string, 0, 1+len(args))
argv = append(argv, command)
argv = append(argv, args...)

return syscall.Exec(argv0, argv, env)
}

0 comments on commit 7ad5e22

Please sign in to comment.