
This mainly fixes Linux vs generic Unix differences, with some differences between Darwin and Freebsd (which are close bit not identical). Should make fixing for other Unix platforms easier. Note there are not yet `runc` equivalents for these platforms; my current use case is image manipulation for the `moby` tool. However there is interest in OCI runtime ports for both platforms. Current status is that MacOS can build and run `ctr`, `dist` and `containerd` and some operations are supported. FreeBSD 11 still needs some more fixes to continuity for extended attributes. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
66 lines
1.5 KiB
Go
66 lines
1.5 KiB
Go
// +build darwin freebsd
|
|
|
|
package fs
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"syscall"
|
|
|
|
"github.com/containerd/continuity/sysx"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func copyFileInfo(fi os.FileInfo, name string) error {
|
|
st := fi.Sys().(*syscall.Stat_t)
|
|
if err := os.Lchown(name, int(st.Uid), int(st.Gid)); err != nil {
|
|
return errors.Wrapf(err, "failed to chown %s", name)
|
|
}
|
|
|
|
if (fi.Mode() & os.ModeSymlink) != os.ModeSymlink {
|
|
if err := os.Chmod(name, fi.Mode()); err != nil {
|
|
return errors.Wrapf(err, "failed to chmod %s", name)
|
|
}
|
|
}
|
|
|
|
if err := syscall.UtimesNano(name, []syscall.Timespec{st.Atimespec, st.Mtimespec}); err != nil {
|
|
return errors.Wrapf(err, "failed to utime %s", name)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func copyFileContent(dst, src *os.File) error {
|
|
buf := bufferPool.Get().([]byte)
|
|
_, err := io.CopyBuffer(dst, src, buf)
|
|
bufferPool.Put(buf)
|
|
|
|
return err
|
|
}
|
|
|
|
func copyXAttrs(dst, src string) error {
|
|
xattrKeys, err := sysx.LListxattr(src)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to list xattrs on %s", src)
|
|
}
|
|
for _, xattr := range xattrKeys {
|
|
data, err := sysx.LGetxattr(src, xattr)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to get xattr %q on %s", xattr, src)
|
|
}
|
|
if err := sysx.LSetxattr(dst, xattr, data, 0); err != nil {
|
|
return errors.Wrapf(err, "failed to set xattr %q on %s", xattr, dst)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func copyDevice(dst string, fi os.FileInfo) error {
|
|
st, ok := fi.Sys().(*syscall.Stat_t)
|
|
if !ok {
|
|
return errors.New("unsupported stat type")
|
|
}
|
|
return syscall.Mknod(dst, uint32(fi.Mode()), int(st.Rdev))
|
|
}
|