github.com/cycloidio/terraform@v1.1.10-0.20220513142504-76d5c768dc63/replacefile/replacefile_windows.go (about) 1 //go:build windows 2 // +build windows 3 4 package replacefile 5 6 import ( 7 "os" 8 "syscall" 9 10 "golang.org/x/sys/windows" 11 ) 12 13 // AtomicRename renames from the source path to the destination path, 14 // atomically replacing any file that might already exist at the destination. 15 // 16 // Typically this operation can succeed only if the source and destination 17 // are within the same physical filesystem, so this function is best reserved 18 // for cases where the source and destination exist in the same directory and 19 // only the local filename differs between them. 20 func AtomicRename(source, destination string) error { 21 // On Windows, renaming one file over another is not atomic and certain 22 // error conditions can result in having only the source file and nothing 23 // at the destination file. Instead, we need to call into the MoveFileEx 24 // Windows API function, setting two flags to opt in to replacing an 25 // existing file. 26 srcPtr, err := syscall.UTF16PtrFromString(source) 27 if err != nil { 28 return &os.LinkError{"replace", source, destination, err} 29 } 30 destPtr, err := syscall.UTF16PtrFromString(destination) 31 if err != nil { 32 return &os.LinkError{"replace", source, destination, err} 33 } 34 35 flags := uint32(windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH) 36 err = windows.MoveFileEx(srcPtr, destPtr, flags) 37 if err != nil { 38 return &os.LinkError{"replace", source, destination, err} 39 } 40 return nil 41 }