-
Notifications
You must be signed in to change notification settings - Fork 18
/
tempFileWindows.go
77 lines (67 loc) · 1.85 KB
/
tempFileWindows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright 2020 The Go Cloud Development Kit Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Either windows or windows_test
//go:build windows || windows_test
// +build windows windows_test
// Test this code on any machine with
// go test -tags windows_test
package cmdtest
import (
"io/ioutil"
"os"
"path/filepath"
)
func createTempFile(filename string) (tempFile, error) {
f, err := ioutil.TempFile("", filepath.Base(filename))
if err != nil {
return nil, err
}
return &simpleTempFile{File: f, path: filename}, nil
}
type simpleTempFile struct {
*os.File
path string // rename to this
closed bool // Close was called
done bool // Close and Rename succeeded
}
// Code is taken from github.com/google/renameio@v0.1.0/tempfile.go.
// Although rename can't properly be done atomically on Windows,
// this is the best we have, and it's better than nothing.
func (t *simpleTempFile) Cleanup() error {
if t.done {
return nil
}
var closeErr error
if !t.closed {
closeErr = t.Close()
}
if err := os.Remove(t.Name()); err != nil {
return err
}
return closeErr
}
func (t *simpleTempFile) CloseAtomicallyReplace() error {
if err := t.Sync(); err != nil {
return err
}
t.closed = true
if err := t.Close(); err != nil {
return err
}
if err := os.Rename(t.Name(), t.path); err != nil {
return err
}
t.done = true
return nil
}