Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec014011 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "sbox: run commands using script for large commands"

parents 3d56ed56 0a5da702
Loading
Loading
Loading
Loading
+29 −3
Original line number Diff line number Diff line
@@ -164,7 +164,7 @@ func run() error {
		if useSubDir {
			localTempDir = filepath.Join(localTempDir, strconv.Itoa(i))
		}
		depFile, err := runCommand(command, localTempDir)
		depFile, err := runCommand(command, localTempDir, i)
		if err != nil {
			// Running the command failed, keep the temporary output directory around in
			// case a user wants to inspect it for debugging purposes.  Soong will delete
@@ -194,6 +194,28 @@ func run() error {
	return nil
}

// createCommandScript will create and return an exec.Cmd that runs rawCommand.
//
// rawCommand is executed via a script in the sandbox.
// tempDir is the temporary where the script is created.
// toDirInSandBox is the path containing the script in the sbox environment.
// toDirInSandBox is the path containing the script in the sbox environment.
// seed is a unique integer used to distinguish different scripts that might be at location.
//
// returns an exec.Cmd that can be ran from within sbox context if no error, or nil if error.
// caller must ensure script is cleaned up if function succeeds.
//
func createCommandScript(rawCommand string, tempDir, toDirInSandbox string, seed int) (*exec.Cmd, error) {
	scriptName := fmt.Sprintf("sbox_command.%d.bash", seed)
	scriptPathAndName := joinPath(tempDir, scriptName)
	err := os.WriteFile(scriptPathAndName, []byte(rawCommand), 0644)
	if err != nil {
		return nil, fmt.Errorf("failed to write command %s... to %s",
			rawCommand[0:40], scriptPathAndName)
	}
	return exec.Command("bash", joinPath(toDirInSandbox, filepath.Base(scriptName))), nil
}

// readManifest reads an sbox manifest from a textproto file.
func readManifest(file string) (*sbox_proto.Manifest, error) {
	manifestData, err := ioutil.ReadFile(file)
@@ -213,7 +235,7 @@ func readManifest(file string) (*sbox_proto.Manifest, error) {

// runCommand runs a single command from a manifest.  If the command references the
// __SBOX_DEPFILE__ placeholder it returns the name of the depfile that was used.
func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, err error) {
func runCommand(command *sbox_proto.Command, tempDir string, commandIndex int) (depFile string, err error) {
	rawCommand := command.GetCommand()
	if rawCommand == "" {
		return "", fmt.Errorf("command is required")
@@ -255,7 +277,11 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er
		return "", err
	}

	cmd := exec.Command("bash", "-c", rawCommand)
	cmd, err := createCommandScript(rawCommand, tempDir, pathToTempDirInSbox, commandIndex)
	if err != nil {
		return "", err
	}

	buf := &bytes.Buffer{}
	cmd.Stdin = os.Stdin
	cmd.Stdout = buf