(dstPath string, srcPath string, perms os.FileMode)
| 831 | } |
| 832 | |
| 833 | func AtomicRenameCopy(dstPath string, srcPath string, perms os.FileMode) error { |
| 834 | // first copy the file to dstPath.new, then rename into place |
| 835 | srcFd, err := os.Open(srcPath) |
| 836 | if err != nil { |
| 837 | return err |
| 838 | } |
| 839 | defer srcFd.Close() |
| 840 | tempName := dstPath + ".new" |
| 841 | dstFd, err := os.Create(tempName) |
| 842 | if err != nil { |
| 843 | return err |
| 844 | } |
| 845 | _, err = io.Copy(dstFd, srcFd) |
| 846 | if err != nil { |
| 847 | dstFd.Close() |
| 848 | return err |
| 849 | } |
| 850 | err = dstFd.Close() |
| 851 | if err != nil { |
| 852 | return err |
| 853 | } |
| 854 | err = os.Chmod(tempName, perms) |
| 855 | if err != nil { |
| 856 | return err |
| 857 | } |
| 858 | err = os.Rename(tempName, dstPath) |
| 859 | if err != nil { |
| 860 | return err |
| 861 | } |
| 862 | return nil |
| 863 | } |
| 864 | |
| 865 | func AtoiNoErr(str string) int { |
| 866 | val, err := strconv.Atoi(str) |
no test coverage detected