github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/util/remove.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package util 7 8 import ( 9 "os" 10 "runtime" 11 "syscall" 12 "time" 13 ) 14 15 const windowsSharingViolationError syscall.Errno = 32 16 17 // Remove removes the named file or (empty) directory with at most 5 attempts. 18 func Remove(name string) error { 19 var err error 20 for i := 0; i < 5; i++ { 21 err = os.Remove(name) 22 if err == nil { 23 break 24 } 25 unwrapped := err.(*os.PathError).Err 26 if unwrapped == syscall.EBUSY || unwrapped == syscall.ENOTEMPTY || unwrapped == syscall.EPERM || unwrapped == syscall.EMFILE || unwrapped == syscall.ENFILE { 27 // try again 28 <-time.After(100 * time.Millisecond) 29 continue 30 } 31 32 if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" { 33 // try again 34 <-time.After(100 * time.Millisecond) 35 continue 36 } 37 38 if unwrapped == syscall.ENOENT { 39 // it's already gone 40 return nil 41 } 42 } 43 return err 44 } 45 46 // RemoveAll removes the named file or (empty) directory with at most 5 attempts. 47 func RemoveAll(name string) error { 48 var err error 49 for i := 0; i < 5; i++ { 50 err = os.RemoveAll(name) 51 if err == nil { 52 break 53 } 54 unwrapped := err.(*os.PathError).Err 55 if unwrapped == syscall.EBUSY || unwrapped == syscall.ENOTEMPTY || unwrapped == syscall.EPERM || unwrapped == syscall.EMFILE || unwrapped == syscall.ENFILE { 56 // try again 57 <-time.After(100 * time.Millisecond) 58 continue 59 } 60 61 if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" { 62 // try again 63 <-time.After(100 * time.Millisecond) 64 continue 65 } 66 67 if unwrapped == syscall.ENOENT { 68 // it's already gone 69 return nil 70 } 71 } 72 return err 73 } 74 75 // Rename renames (moves) oldpath to newpath with at most 5 attempts. 76 func Rename(oldpath, newpath string) error { 77 var err error 78 for i := 0; i < 5; i++ { 79 err = os.Rename(oldpath, newpath) 80 if err == nil { 81 break 82 } 83 unwrapped := err.(*os.LinkError).Err 84 if unwrapped == syscall.EBUSY || unwrapped == syscall.ENOTEMPTY || unwrapped == syscall.EPERM || unwrapped == syscall.EMFILE || unwrapped == syscall.ENFILE { 85 // try again 86 <-time.After(100 * time.Millisecond) 87 continue 88 } 89 90 if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" { 91 // try again 92 <-time.After(100 * time.Millisecond) 93 continue 94 } 95 96 if i == 0 && os.IsNotExist(err) { 97 return err 98 } 99 100 if unwrapped == syscall.ENOENT { 101 // it's already gone 102 return nil 103 } 104 } 105 return err 106 }