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