aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/os/exec/exec.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/os/exec/exec.go')
-rw-r--r--src/pkg/os/exec/exec.go37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/pkg/os/exec/exec.go b/src/pkg/os/exec/exec.go
index d2cee03fcd..44b9cc08ce 100644
--- a/src/pkg/os/exec/exec.go
+++ b/src/pkg/os/exec/exec.go
@@ -13,7 +13,9 @@ import (
"io"
"os"
"path/filepath"
+ "runtime"
"strconv"
+ "strings"
"sync"
"syscall"
)
@@ -237,6 +239,32 @@ func (c *Cmd) Run() error {
return c.Wait()
}
+// lookExtensions finds windows executable by its dir and path.
+// It uses LookPath to try appropriate extensions.
+// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
+func lookExtensions(path, dir string) (string, error) {
+ if filepath.Base(path) == path {
+ path = filepath.Join(".", path)
+ }
+ if dir == "" {
+ return LookPath(path)
+ }
+ if filepath.VolumeName(path) != "" {
+ return LookPath(path)
+ }
+ if len(path) > 1 && os.IsPathSeparator(path[0]) {
+ return LookPath(path)
+ }
+ dirandpath := filepath.Join(dir, path)
+ // We assume that LookPath will only add file extension.
+ lp, err := LookPath(dirandpath)
+ if err != nil {
+ return "", err
+ }
+ ext := strings.TrimPrefix(lp, dirandpath)
+ return path + ext, nil
+}
+
// Start starts the specified command but does not wait for it to complete.
//
// The Wait method will return the exit code and release associated resources
@@ -247,6 +275,15 @@ func (c *Cmd) Start() error {
c.closeDescriptors(c.closeAfterWait)
return c.lookPathErr
}
+ if runtime.GOOS == "windows" {
+ lp, err := lookExtensions(c.Path, c.Dir)
+ if err != nil {
+ c.closeDescriptors(c.closeAfterStart)
+ c.closeDescriptors(c.closeAfterWait)
+ return err
+ }
+ c.Path = lp
+ }
if c.Process != nil {
return errors.New("exec: already started")
}