...
Source file src/pkg/cmd/go/internal/renameio/renameio.go
1
2
3
4
5
6 package renameio
7
8 import (
9 "bytes"
10 "io"
11 "math/rand"
12 "os"
13 "path/filepath"
14 "strconv"
15
16 "cmd/go/internal/robustio"
17 )
18
19 const patternSuffix = ".tmp"
20
21
22
23 func Pattern(filename string) string {
24 return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix)
25 }
26
27
28
29
30
31
32 func WriteFile(filename string, data []byte, perm os.FileMode) (err error) {
33 return WriteToFile(filename, bytes.NewReader(data), perm)
34 }
35
36
37
38 func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) {
39 f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm)
40 if err != nil {
41 return err
42 }
43 defer func() {
44
45
46
47 if err != nil {
48 f.Close()
49 os.Remove(f.Name())
50 }
51 }()
52
53 if _, err := io.Copy(f, data); err != nil {
54 return err
55 }
56
57
58
59 if err := f.Sync(); err != nil {
60 return err
61 }
62 if err := f.Close(); err != nil {
63 return err
64 }
65
66 return robustio.Rename(f.Name(), filename)
67 }
68
69
70
71
72
73
74
75
76
77
78 func ReadFile(filename string) ([]byte, error) {
79 return robustio.ReadFile(filename)
80 }
81
82
83 func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) {
84 for i := 0; i < 10000; i++ {
85 name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix)
86 f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm)
87 if os.IsExist(err) {
88 continue
89 }
90 break
91 }
92 return
93 }
94
View as plain text