-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
file.go
234 lines (205 loc) · 6.3 KB
/
file.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
package hackpadfs
import (
"io"
gofs "io/fs"
"syscall"
"time"
)
// Flags are bit-wise OR'd with each other in fs.OpenFile().
// Exactly one of Read/Write flags must be specified, and any other flags can be OR'd together.
const (
FlagReadOnly int = syscall.O_RDONLY
FlagWriteOnly int = syscall.O_WRONLY
FlagReadWrite int = syscall.O_RDWR
FlagAppend int = syscall.O_APPEND
FlagCreate int = syscall.O_CREAT
FlagExclusive int = syscall.O_EXCL
FlagSync int = syscall.O_SYNC
FlagTruncate int = syscall.O_TRUNC
)
// FileMode represents a file's mode and permission bits. Mirrors io/fs.FileMode.
type FileMode = gofs.FileMode
// Mode values are bit-wise OR'd with a file's permissions to form the FileMode. Mirror io/fs.Mode... values.
const (
ModeDir = gofs.ModeDir
ModeAppend = gofs.ModeAppend
ModeExclusive = gofs.ModeExclusive
ModeTemporary = gofs.ModeTemporary
ModeSymlink = gofs.ModeSymlink
ModeDevice = gofs.ModeDevice
ModeNamedPipe = gofs.ModeNamedPipe
ModeSocket = gofs.ModeSocket
ModeSetuid = gofs.ModeSetuid
ModeSetgid = gofs.ModeSetgid
ModeCharDevice = gofs.ModeCharDevice
ModeSticky = gofs.ModeSticky
ModeIrregular = gofs.ModeIrregular
ModeType = gofs.ModeType
ModePerm = gofs.ModePerm
)
// FileInfo describes a file and is returned by Stat(). Mirrors io/fs.FileInfo.
type FileInfo = gofs.FileInfo
// DirEntry is an entry read from a directory. Mirrors io/fs.DirEntry.
type DirEntry = gofs.DirEntry
// File provides access to a file. Mirrors io/fs.File.
type File = gofs.File
// ReadWriterFile is a File that supports Write() operations.
type ReadWriterFile interface {
File
io.Writer
}
// ReaderAtFile is a File that supports ReadAt() operations.
type ReaderAtFile interface {
File
io.ReaderAt
}
// WriterAtFile is a File that supports WriteAt() operations.
type WriterAtFile interface {
File
io.WriterAt
}
// DirReaderFile is a File that supports ReadDir() operations. Mirrors io/fs.ReadDirFile.
type DirReaderFile interface {
File
ReadDir(n int) ([]DirEntry, error)
}
// SeekerFile is a File that supports Seek() operations.
type SeekerFile interface {
File
io.Seeker
}
// SyncerFile is a File that supports Sync() operations.
type SyncerFile interface {
File
Sync() error
}
// TruncaterFile is a File that supports Truncate() operations.
type TruncaterFile interface {
File
Truncate(size int64) error
}
// ChmoderFile is a File that supports Chmod() operations.
type ChmoderFile interface {
File
Chmod(mode FileMode) error
}
// ChownerFile is a File that supports Chown() operations.
type ChownerFile interface {
File
Chown(uid, gid int) error
}
// ChtimeserFile is a File that supports Chtimes() operations.
type ChtimeserFile interface {
File
Chtimes(atime time.Time, mtime time.Time) error
}
// ChmodFile runs file.Chmod() is available, fails with a not implemented error otherwise.
func ChmodFile(file File, mode FileMode) error {
if file, ok := file.(ChmoderFile); ok {
return file.Chmod(mode)
}
info, err := file.Stat()
if err != nil {
return err
}
return &PathError{Op: "chmod", Path: info.Name(), Err: ErrNotImplemented}
}
// ChownFile runs file.Chown() is available, fails with a not implemented error otherwise.
func ChownFile(file File, uid, gid int) error {
if file, ok := file.(ChownerFile); ok {
return file.Chown(uid, gid)
}
info, err := file.Stat()
if err != nil {
return err
}
return &PathError{Op: "chmod", Path: info.Name(), Err: ErrNotImplemented}
}
// ChtimesFile runs file.Chtimes() is available, fails with a not implemented error otherwise.
func ChtimesFile(file File, atime, mtime time.Time) error {
if file, ok := file.(ChtimeserFile); ok {
return file.Chtimes(atime, mtime)
}
info, err := file.Stat()
if err != nil {
return err
}
return &PathError{Op: "chtimes", Path: info.Name(), Err: ErrNotImplemented}
}
// ReadAtFile runs file.ReadAt() is available, fails with a not implemented error otherwise.
func ReadAtFile(file File, p []byte, off int64) (n int, err error) {
if file, ok := file.(ReaderAtFile); ok {
return file.ReadAt(p, off)
}
info, err := file.Stat()
if err != nil {
return 0, err
}
return 0, &PathError{Op: "readat", Path: info.Name(), Err: ErrNotImplemented}
}
// WriteFile runs file.Write() is available, fails with a not implemented error otherwise.
func WriteFile(file File, p []byte) (n int, err error) {
if file, ok := file.(ReadWriterFile); ok {
return file.Write(p)
}
info, err := file.Stat()
if err != nil {
return 0, err
}
return 0, &PathError{Op: "write", Path: info.Name(), Err: ErrNotImplemented}
}
// WriteAtFile runs file.WriteAt() is available, fails with a not implemented error otherwise.
func WriteAtFile(file File, p []byte, off int64) (n int, err error) {
if file, ok := file.(WriterAtFile); ok {
return file.WriteAt(p, off)
}
info, err := file.Stat()
if err != nil {
return 0, err
}
return 0, &PathError{Op: "writeat", Path: info.Name(), Err: ErrNotImplemented}
}
// ReadDirFile runs file.ReadDir() is available, fails with a not implemented error otherwise.
func ReadDirFile(file File, n int) ([]DirEntry, error) {
if file, ok := file.(DirReaderFile); ok {
return file.ReadDir(n)
}
info, err := file.Stat()
if err != nil {
return nil, err
}
return nil, &PathError{Op: "readdir", Path: info.Name(), Err: ErrNotImplemented}
}
// SeekFile runs file.Seek() is available, fails with a not implemented error otherwise.
func SeekFile(file File, offset int64, whence int) (int64, error) {
if file, ok := file.(SeekerFile); ok {
return file.Seek(offset, whence)
}
info, err := file.Stat()
if err != nil {
return 0, err
}
return 0, &PathError{Op: "seek", Path: info.Name(), Err: ErrNotImplemented}
}
// SyncFile runs file.Sync() is available, fails with a not implemented error otherwise.
func SyncFile(file File) error {
if file, ok := file.(SyncerFile); ok {
return file.Sync()
}
info, err := file.Stat()
if err != nil {
return err
}
return &PathError{Op: "sync", Path: info.Name(), Err: ErrNotImplemented}
}
// TruncateFile runs file.Truncate() is available, fails with a not implemented error otherwise.
func TruncateFile(file File, size int64) error {
if file, ok := file.(TruncaterFile); ok {
return file.Truncate(size)
}
info, err := file.Stat()
if err != nil {
return err
}
return &PathError{Op: "truncate", Path: info.Name(), Err: ErrNotImplemented}
}