...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package atomicfile
18
19 import (
20 "io"
21 "os"
22 )
23
24 type nopAtomic struct {
25 *os.File
26 doClose bool
27 }
28
29 func (a nopAtomic) GetFile() *os.File {
30 return a.File
31 }
32
33 func (a nopAtomic) Commit() error {
34 if a.doClose {
35 return a.Close()
36 }
37 return nil
38 }
39
40 func isSpecial(path string) bool {
41 if stat, err := os.Stat(path); err == nil {
42 if !stat.Mode().IsRegular() {
43 return true
44 }
45 }
46 return false
47 }
48
49
50
51 func WriteAny(path string) (AtomicFile, error) {
52 if path == "-" {
53 return nopAtomic{os.Stdout, false}, nil
54 }
55 if isSpecial(path) {
56 f, err := os.Create(path)
57 return nopAtomic{f, true}, err
58 }
59 return New(path)
60 }
61
62
63
64
65 func WriteInPlace(src *os.File, dest string) (AtomicFile, error) {
66 if src.Name() == dest {
67 return nopAtomic{src, false}, nil
68 }
69 outfile, err := New(dest)
70 if err != nil {
71 return nil, err
72 }
73 src.Seek(0, 0)
74 if _, err := io.Copy(outfile, src); err != nil {
75 return nil, err
76 }
77 outfile.Seek(0, 0)
78 src.Close()
79 return outfile, nil
80 }
81
82
83 func WriteFile(path string, data []byte) error {
84 f, err := WriteAny(path)
85 if err != nil {
86 return err
87 }
88 defer f.Close()
89 if _, err := f.Write(data); err != nil {
90 return err
91 }
92 return f.Commit()
93 }
94
View as plain text