diff options
author | Cole Faust <colefaust@google.com> | 2023-11-28 17:34:38 -0800 |
---|---|---|
committer | Cole Faust <colefaust@google.com> | 2023-11-28 17:34:38 -0800 |
commit | dd9529050d0ef329cec4ea6c426e9c134c6055c5 (patch) | |
tree | cd77d1f8c866047cbed6d7da78ae49f67ce6b128 /cmd | |
parent | 74656ccf352aa979fa14c2f8a7790edf5fc6259d (diff) | |
download | soong-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.go | 25 |
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 |