From c590ec4bdaeb55d6db58d3e6e611c0b58f1bb31f Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 11 Mar 2021 17:20:02 -0800 Subject: [PATCH] Fix sbox in chdir mode When running commands in chdir mode sbox needs to translate the directory placeholders to paths relative to the sandbox directory instead of relative to the top of the source tree. Also translate relative PATH entries into absolute paths so they are still valid when the current directory is changed. Bug: 182612695 Test: manual Change-Id: Idcbe20466888909d423d62788bc9c35f4e03b398 --- cmd/sbox/sbox.go | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go index f8919a400..f47c6012e 100644 --- a/cmd/sbox/sbox.go +++ b/cmd/sbox/sbox.go @@ -229,13 +229,18 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er return "", err } + pathToTempDirInSbox := tempDir + if command.GetChdir() { + pathToTempDirInSbox = "." + } + if strings.Contains(rawCommand, depFilePlaceholder) { - depFile = filepath.Join(tempDir, "deps.d") + depFile = filepath.Join(pathToTempDirInSbox, "deps.d") rawCommand = strings.Replace(rawCommand, depFilePlaceholder, depFile, -1) } if strings.Contains(rawCommand, sandboxDirPlaceholder) { - rawCommand = strings.Replace(rawCommand, sandboxDirPlaceholder, tempDir, -1) + rawCommand = strings.Replace(rawCommand, sandboxDirPlaceholder, pathToTempDirInSbox, -1) } // Emulate ninja's behavior of creating the directories for any output files before @@ -254,6 +259,15 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er if command.GetChdir() { cmd.Dir = tempDir + path := os.Getenv("PATH") + absPath, err := makeAbsPathEnv(path) + if err != nil { + return "", err + } + err = os.Setenv("PATH", absPath) + if err != nil { + return "", fmt.Errorf("Failed to update PATH: %w", err) + } } err = cmd.Run() @@ -466,3 +480,17 @@ func joinPath(dir, file string) string { } return filepath.Join(dir, file) } + +func makeAbsPathEnv(pathEnv string) (string, error) { + pathEnvElements := filepath.SplitList(pathEnv) + for i, p := range pathEnvElements { + if !filepath.IsAbs(p) { + absPath, err := filepath.Abs(p) + if err != nil { + return "", fmt.Errorf("failed to make PATH entry %q absolute: %w", p, err) + } + pathEnvElements[i] = absPath + } + } + return strings.Join(pathEnvElements, string(filepath.ListSeparator)), nil +}