diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2025-04-10 15:08:06 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2025-04-11 10:07:50 +0000 |
| commit | dfb5be349af98db984a0944f49896f454e4bc8a6 (patch) | |
| tree | dab54a5476b759b2ff9f4ce7a71b30a6ef1b02be /pkg/osutil/tar.go | |
| parent | a2335417592dcd4545c1953807ae9c8906e133d5 (diff) | |
pkg/osutil: add tar.gz generation helpers
Diffstat (limited to 'pkg/osutil/tar.go')
| -rw-r--r-- | pkg/osutil/tar.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/pkg/osutil/tar.go b/pkg/osutil/tar.go new file mode 100644 index 000000000..32500e7e4 --- /dev/null +++ b/pkg/osutil/tar.go @@ -0,0 +1,67 @@ +// Copyright 2025 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package osutil + +import ( + "archive/tar" + "compress/gzip" + "io" + "io/fs" + "os" + "path/filepath" + "strings" +) + +func TarGzDirectory(dir string, writer io.Writer) error { + gzw := gzip.NewWriter(writer) + defer gzw.Close() + return tarDirectory(dir, gzw) +} + +func tarDirectory(dir string, writer io.Writer) error { + tw := tar.NewWriter(writer) + defer tw.Close() + + return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if err != nil || path == dir { + return err + } + typ := d.Type() + if !typ.IsDir() && !typ.IsRegular() { + // Only folders and regular files. + return nil + } + relPath, err := filepath.Rel(dir, path) + if err != nil { + return err + } + relPath = filepath.ToSlash(relPath) + info, err := d.Info() + if err != nil { + return err + } + header, err := tar.FileInfoHeader(info, "") + if err != nil { + return err + } + header.Name = relPath + if typ.IsDir() && !strings.HasSuffix(header.Name, "/") { + header.Name += "/" + } + if err := tw.WriteHeader(header); err != nil { + return err + } + if typ.IsDir() { + return nil + } + // Write the file content. + f, err := os.Open(path) + if err != nil { + return err + } + _, err = io.Copy(tw, f) + f.Close() + return err + }) +} |
