// SPDX-FileCopyrightText: Copyright The Lima Authors1// SPDX-License-Identifier: Apache-2.023// From https://raw.githubusercontent.com/norouter/norouter/v0.6.5/pkg/agent/bicopy/bicopy.go4/*5Copyright (C) NoRouter authors.67Copyright (C) libnetwork authors.89Licensed under the Apache License, Version 2.0 (the "License");10you may not use this file except in compliance with the License.11You may obtain a copy of the License at1213http://www.apache.org/licenses/LICENSE-2.01415Unless required by applicable law or agreed to in writing, software16distributed under the License is distributed on an "AS IS" BASIS,17WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.18See the License for the specific language governing permissions and19limitations under the License.20*/2122package bicopy2324import (25"io"26"sync"2728"github.com/sirupsen/logrus"29)3031// Bicopy is from https://github.com/rootless-containers/rootlesskit/blob/v0.10.1/pkg/port/builtin/parent/tcp/tcp.go#L73-L10432// (originally from libnetwork, Apache License 2.0).33func Bicopy(x, y io.ReadWriter, quit <-chan struct{}) {34type closeReader interface {35CloseRead() error36}37type closeWriter interface {38CloseWrite() error39}40var wg sync.WaitGroup41broker := func(to, from io.ReadWriter) {42if _, err := io.Copy(to, from); err != nil {43logrus.WithError(err).Debug("failed to call io.Copy")44}45if fromCR, ok := from.(closeReader); ok {46if err := fromCR.CloseRead(); err != nil {47logrus.WithError(err).Debug("failed to call CloseRead")48}49}50if toCW, ok := to.(closeWriter); ok {51if err := toCW.CloseWrite(); err != nil {52logrus.WithError(err).Debug("failed to call CloseWrite")53}54}55wg.Done()56}5758wg.Add(2)59go broker(x, y)60go broker(y, x)61finish := make(chan struct{})62go func() {63wg.Wait()64close(finish)65}()6667select {68case <-quit:69case <-finish:70}71if xCloser, ok := x.(io.Closer); ok {72if err := xCloser.Close(); err != nil {73logrus.WithError(err).Debug("failed to call xCloser.Close")74}75}76if yCloser, ok := y.(io.Closer); ok {77if err := yCloser.Close(); err != nil {78logrus.WithError(err).Debug("failed to call yCloser.Close")79}80}81<-finish82// TODO: return copied bytes83}848586