blob: 72284a774cfa9964a1e425186367095ee17e7ff5 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package fuzz
import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/golang/glog"
)
// This is similar to io.MultiReader but works in parallel instead of
// serial. This means ordering is not guaranteed, but this is no different
// than what would happen if we redirected stderr to stdout in any other
// way.
// TODO(https://fxbug.dev/42057415): Once we are using only exec.Cmd and not ssh.Session
// we may be able to simply assign the same pipe object to Stdout and Stderr,
// but this does not work for ssh.Session (see comments about KillCloser)
func parallelMultiReader(readers ...io.Reader) io.ReadCloser {
r, w := io.Pipe()
errChs := make([]chan error, len(readers))
for j, reader := range readers {
errChs[j] = make(chan error, 1)
go func(errCh chan<- error, r io.Reader) {
_, err := io.Copy(w, r)
errCh <- err
}(errChs[j], reader)
}
go func() {
// After all readers have stopped, propagate EOF.
for j, errCh := range errChs {
if err := <-errCh; err != nil {
glog.Warningf("Error copying from reader %d: %s", j, err)
}
}
w.Close()
}()
return r
}
func moveAllFiles(srcDir, dstDir string) error {
entries, err := os.ReadDir(srcDir)
if err != nil {
return fmt.Errorf("error reading dir %s: %s", srcDir, err)
}
for _, entry := range entries {
if entry.IsDir() {
continue
}
oldPath := filepath.Join(srcDir, entry.Name())
newPath := filepath.Join(dstDir, entry.Name())
if err := os.Rename(oldPath, newPath); err != nil {
return fmt.Errorf("error renaming %s: %s", oldPath, err)
}
}
return nil
}
func fileExists(path string) bool {
_, err := os.Stat(path)
return !os.IsNotExist(err)
}