2020-08-11 23:05:34 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2020-08-11 23:05:34 +03:00
package util
import (
"os"
2021-07-20 20:23:01 +03:00
"runtime"
2020-08-11 23:05:34 +03:00
"syscall"
"time"
)
2021-07-20 20:23:01 +03:00
const windowsSharingViolationError syscall . Errno = 32
2020-08-11 23:05:34 +03:00
// Remove removes the named file or (empty) directory with at most 5 attempts.
func Remove ( name string ) error {
var err error
for i := 0 ; i < 5 ; i ++ {
err = os . Remove ( name )
if err == nil {
break
}
unwrapped := err . ( * os . PathError ) . Err
if unwrapped == syscall . EBUSY || unwrapped == syscall . ENOTEMPTY || unwrapped == syscall . EPERM || unwrapped == syscall . EMFILE || unwrapped == syscall . ENFILE {
// try again
<- time . After ( 100 * time . Millisecond )
continue
}
2021-07-20 20:23:01 +03:00
if unwrapped == windowsSharingViolationError && runtime . GOOS == "windows" {
// try again
<- time . After ( 100 * time . Millisecond )
continue
}
2020-08-11 23:05:34 +03:00
if unwrapped == syscall . ENOENT {
// it's already gone
return nil
}
}
return err
}
2021-07-15 18:46:07 +03:00
// RemoveAll removes the named file or (empty) directory with at most 5 attempts.
2020-08-11 23:05:34 +03:00
func RemoveAll ( name string ) error {
var err error
for i := 0 ; i < 5 ; i ++ {
err = os . RemoveAll ( name )
if err == nil {
break
}
unwrapped := err . ( * os . PathError ) . Err
if unwrapped == syscall . EBUSY || unwrapped == syscall . ENOTEMPTY || unwrapped == syscall . EPERM || unwrapped == syscall . EMFILE || unwrapped == syscall . ENFILE {
// try again
<- time . After ( 100 * time . Millisecond )
continue
}
2021-07-20 20:23:01 +03:00
if unwrapped == windowsSharingViolationError && runtime . GOOS == "windows" {
// try again
<- time . After ( 100 * time . Millisecond )
continue
}
2020-08-11 23:05:34 +03:00
if unwrapped == syscall . ENOENT {
// it's already gone
return nil
}
}
return err
}
2021-07-15 18:46:07 +03:00
// Rename renames (moves) oldpath to newpath with at most 5 attempts.
func Rename ( oldpath , newpath string ) error {
var err error
for i := 0 ; i < 5 ; i ++ {
err = os . Rename ( oldpath , newpath )
if err == nil {
break
}
2021-07-16 20:16:04 +03:00
unwrapped := err . ( * os . LinkError ) . Err
2021-07-15 18:46:07 +03:00
if unwrapped == syscall . EBUSY || unwrapped == syscall . ENOTEMPTY || unwrapped == syscall . EPERM || unwrapped == syscall . EMFILE || unwrapped == syscall . ENFILE {
// try again
<- time . After ( 100 * time . Millisecond )
continue
}
2021-07-20 20:23:01 +03:00
if unwrapped == windowsSharingViolationError && runtime . GOOS == "windows" {
// try again
<- time . After ( 100 * time . Millisecond )
continue
}
2021-07-15 18:46:07 +03:00
if i == 0 && os . IsNotExist ( err ) {
return err
}
if unwrapped == syscall . ENOENT {
// it's already gone
return nil
}
}
return err
}