github.com/opencontainers/umoci@v0.4.8-0.20240508124516-656e4836fb0d/pkg/system/copy.go (about) 1 /* 2 * umoci: Umoci Modifies Open Containers' Images 3 * Copyright (C) 2016-2022 SUSE LLC 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package system 19 20 import ( 21 "errors" 22 "io" 23 24 "golang.org/x/sys/unix" 25 ) 26 27 // Copy has identical semantics to io.Copy except it will automatically resume 28 // the copy after it receives an EINTR error. 29 func Copy(dst io.Writer, src io.Reader) (int64, error) { 30 // Make a buffer so io.Copy doesn't make one for each iteration. 31 var buf []byte 32 size := 32 * 1024 33 if lr, ok := src.(*io.LimitedReader); ok && lr.N < int64(size) { 34 if lr.N < 1 { 35 size = 1 36 } else { 37 size = int(lr.N) 38 } 39 } 40 buf = make([]byte, size) 41 42 var written int64 43 for { 44 n, err := io.CopyBuffer(dst, src, buf) 45 written += n // n is always non-negative 46 if errors.Is(err, unix.EINTR) { 47 continue 48 } 49 return written, err 50 } 51 } 52 53 // CopyN has identical semantics to io.CopyN except it will automatically 54 // resume the copy after it receives an EINTR error. 55 func CopyN(dst io.Writer, src io.Reader, n int64) (written int64, err error) { 56 // This is based on the stdlib io.CopyN implementation. 57 written, err = Copy(dst, io.LimitReader(src, n)) 58 if written == n { 59 err = nil // somewhat confusing io.CopyN semantics 60 } 61 if written < n && err == nil { 62 err = io.EOF // if the source ends prematurely, io.EOF 63 } 64 return 65 }