aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorCole Faust <colefaust@google.com>2023-11-28 17:34:38 -0800
committerCole Faust <colefaust@google.com>2023-11-28 17:34:38 -0800
commitdd9529050d0ef329cec4ea6c426e9c134c6055c5 (patch)
treecd77d1f8c866047cbed6d7da78ae49f67ce6b128 /cmd
parent74656ccf352aa979fa14c2f8a7790edf5fc6259d (diff)
downloadsoong-dd9529050d0ef329cec4ea6c426e9c134c6055c5.tar.gz
Handle symlinks in sbox
Previously, sbox would follow the symlink and copy the symlink's target into the sbox, instead of the symlink itself. camera-its is a genrule that zips up a folder that includes a symlink, so we want the symlink to still be there instead of a copy of the file it points to. Bug: 307824623 Test: ./build/soong/tests/genrule_sandbox_test.py camera-its Change-Id: Ib81f6fd6745ec2c58580082c73e33760d5051f5e
Diffstat (limited to 'cmd')
-rw-r--r--cmd/sbox/sbox.go25
1 files changed, 23 insertions, 2 deletions
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 3364f503f..e69a93067 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -22,6 +22,7 @@ import (
"flag"
"fmt"
"io"
+ "io/fs"
"io/ioutil"
"os"
"os/exec"
@@ -478,7 +479,8 @@ func copyFiles(copies []*sbox_proto.Copy, fromDir, toDir string, exists existsTy
// copyOneFile copies a file and its permissions. If forceExecutable is true it adds u+x to the
// permissions. If exists is allowFromNotExists it returns nil if the from path doesn't exist.
// If write is onlyWriteIfChanged then the output file is compared to the input file and not written to
-// if it is the same, avoiding updating the timestamp.
+// if it is the same, avoiding updating the timestamp. If from is a symlink, the symlink itself
+// will be copied, instead of what it points to.
func copyOneFile(from string, to string, forceExecutable bool, exists existsType,
write writeType) error {
err := os.MkdirAll(filepath.Dir(to), 0777)
@@ -486,7 +488,7 @@ func copyOneFile(from string, to string, forceExecutable bool, exists existsType
return err
}
- stat, err := os.Stat(from)
+ stat, err := os.Lstat(from)
if err != nil {
if os.IsNotExist(err) && exists == allowFromNotExists {
return nil
@@ -494,6 +496,25 @@ func copyOneFile(from string, to string, forceExecutable bool, exists existsType
return err
}
+ if stat.Mode()&fs.ModeSymlink != 0 {
+ linkTarget, err := os.Readlink(from)
+ if err != nil {
+ return err
+ }
+ if write == onlyWriteIfChanged {
+ toLinkTarget, err := os.Readlink(to)
+ if err == nil && toLinkTarget == linkTarget {
+ return nil
+ }
+ }
+ err = os.Remove(to)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
+ return os.Symlink(linkTarget, to)
+ }
+
perm := stat.Mode()
if forceExecutable {
perm = perm | 0100 // u+x