@@ -44,6 +44,9 @@ func (fi fileInfo) Sys() interface{} {
44
44
}
45
45
46
46
func (fi fileInfo ) Size () int64 {
47
+ if fi .dir {
48
+ return 0
49
+ }
47
50
fi .mutex .RLock ()
48
51
l := len (* (fi .buf ))
49
52
fi .mutex .RUnlock ()
@@ -54,6 +57,11 @@ func (fi fileInfo) IsDir() bool {
54
57
return fi .dir
55
58
}
56
59
60
+ // ModTime returns the modification time.
61
+ // Modification time is updated on:
62
+ // - Creation
63
+ // - Rename
64
+ // - Open
57
65
func (fi fileInfo ) ModTime () time.Time {
58
66
return fi .modTime
59
67
}
@@ -88,6 +96,8 @@ func MemFS() vfs.Filesystem {
88
96
89
97
// Mkdir creates a new directory with given permissions
90
98
func (fs * memFS ) Mkdir (name string , perm os.FileMode ) error {
99
+ fs .lock .Lock ()
100
+ defer fs .lock .Unlock ()
91
101
name = filepath .Clean (name )
92
102
base := filepath .Base (name )
93
103
parent , fi , err := fs .fileInfo (name )
@@ -99,11 +109,12 @@ func (fs *memFS) Mkdir(name string, perm os.FileMode) error {
99
109
}
100
110
101
111
fi = & fileInfo {
102
- name : base ,
103
- dir : true ,
104
- mode : perm ,
105
- parent : parent ,
106
- fs : fs ,
112
+ name : base ,
113
+ dir : true ,
114
+ mode : perm ,
115
+ parent : parent ,
116
+ modTime : time .Now (),
117
+ fs : fs ,
107
118
}
108
119
parent .childs [base ] = fi
109
120
return nil
@@ -122,6 +133,9 @@ func (f byName) Less(i, j int) bool { return f[i].Name() < f[j].Name() }
122
133
func (f byName ) Swap (i , j int ) { f [i ], f [j ] = f [j ], f [i ] }
123
134
124
135
func (fs * memFS ) ReadDir (path string ) ([]os.FileInfo , error ) {
136
+ fs .lock .RLock ()
137
+ defer fs .lock .RUnlock ()
138
+
125
139
path = filepath .Clean (path )
126
140
_ , fi , err := fs .fileInfo (path )
127
141
if err != nil {
@@ -199,6 +213,9 @@ func checkFlag(flag int, flags int) bool {
199
213
// If success the returned File can be used for I/O. Otherwise an error is returned, which
200
214
// is a *os.PathError and can be extracted for further information.
201
215
func (fs * memFS ) OpenFile (name string , flag int , perm os.FileMode ) (vfs.File , error ) {
216
+ fs .lock .Lock ()
217
+ defer fs .lock .Unlock ()
218
+
202
219
name = filepath .Clean (name )
203
220
base := filepath .Base (name )
204
221
fiParent , fiNode , err := fs .fileInfo (name )
@@ -215,11 +232,12 @@ func (fs *memFS) OpenFile(name string, flag int, perm os.FileMode) (vfs.File, er
215
232
}
216
233
}
217
234
fiNode = & fileInfo {
218
- name : base ,
219
- dir : false ,
220
- mode : perm ,
221
- parent : fiParent ,
222
- fs : fs ,
235
+ name : base ,
236
+ dir : false ,
237
+ mode : perm ,
238
+ parent : fiParent ,
239
+ modTime : time .Now (),
240
+ fs : fs ,
223
241
}
224
242
fiParent .childs [base ] = fiNode
225
243
} else { // find existing
@@ -230,7 +248,7 @@ func (fs *memFS) OpenFile(name string, flag int, perm os.FileMode) (vfs.File, er
230
248
return nil , & os.PathError {"open" , name , ErrIsDirectory }
231
249
}
232
250
}
233
-
251
+ fiNode . modTime = time . Now ()
234
252
return fiNode .file (flag )
235
253
}
236
254
@@ -276,6 +294,9 @@ func (f *woFile) Read(p []byte) (n int, err error) {
276
294
}
277
295
278
296
func (fs * memFS ) Remove (name string ) error {
297
+ fs .lock .Lock ()
298
+ defer fs .lock .Unlock ()
299
+
279
300
name = filepath .Clean (name )
280
301
fiParent , fiNode , err := fs .fileInfo (name )
281
302
if err != nil {
@@ -290,6 +311,9 @@ func (fs *memFS) Remove(name string) error {
290
311
}
291
312
292
313
func (fs * memFS ) Rename (oldpath , newpath string ) error {
314
+ fs .lock .Lock ()
315
+ defer fs .lock .Unlock ()
316
+
293
317
// OldPath
294
318
oldpath = filepath .Clean (oldpath )
295
319
// oldDir, oldBase := filepath.Split(oldpath)
@@ -317,11 +341,15 @@ func (fs *memFS) Rename(oldpath, newpath string) error {
317
341
delete (fiOldParent .childs , fiOld .name )
318
342
fiOld .parent = fiNewParent
319
343
fiOld .name = newBase
344
+ fiOld .modTime = time .Now ()
320
345
fiNewParent .childs [fiOld .name ] = fiOld
321
346
return nil
322
347
}
323
348
324
349
func (fs * memFS ) Stat (name string ) (os.FileInfo , error ) {
350
+ fs .lock .RLock ()
351
+ defer fs .lock .RUnlock ()
352
+
325
353
name = filepath .Clean (name )
326
354
// dir, base := filepath.Split(name)
327
355
_ , fi , err := fs .fileInfo (name )
0 commit comments