Created
April 23, 2019 08:29
-
-
Save rikonor/bdae8510d8ed5a8decd1c99d62f2350d to your computer and use it in GitHub Desktop.
Rename a file with fallback when encountering "invalid cross-device link"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package rename | |
| // renameFile renames a file | |
| // it can be used instead of os.Rename in cases where we attempt | |
| // to move files between partitions (e.g when using Docker volumes) | |
| func renameFile(src string, dst string) error { | |
| err := os.Rename(src, dst) | |
| if err == nil { | |
| return nil | |
| } | |
| if !isInvalidCrossDeviceLinkErr(err) { | |
| return errs.Append(err, "failed to rename file") | |
| } | |
| // fallback to manual copying of the file | |
| if err := copyFile(src, dst); err != nil { | |
| return errs.Append(err, "failed to copy file") | |
| } | |
| // remove src file | |
| if err := os.Remove(src); err != nil { | |
| return errs.Append(err, "failed to remove src file") | |
| } | |
| return nil | |
| } | |
| func copyFile(src string, dst string) error { | |
| // Open source file | |
| fSrc, err := os.Open(src) | |
| if err != nil { | |
| return err | |
| } | |
| defer fSrc.Close() | |
| // Create destination file | |
| fDst, err := os.Create(dst) | |
| if err != nil { | |
| return err | |
| } | |
| defer fDst.Close() | |
| // Copy from source to destination | |
| if _, err := io.Copy(fDst, fSrc); err != nil { | |
| return err | |
| } | |
| return nil | |
| } | |
| func isInvalidCrossDeviceLinkErr(err error) bool { | |
| lErr, ok := err.(*os.LinkError) | |
| if !ok { | |
| return false | |
| } | |
| uErr, ok := lErr.Err.(syscall.Errno) | |
| if !ok { | |
| return false | |
| } | |
| if int(uErr) != 18 { | |
| return false | |
| } | |
| return true | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment