github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libfuse/special_read_file.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 // 5 //go:build !windows 6 // +build !windows 7 8 package libfuse 9 10 import ( 11 "time" 12 13 "bazil.org/fuse" 14 "bazil.org/fuse/fs" 15 "golang.org/x/net/context" 16 ) 17 18 // SpecialReadFile represents a file whose contents are determined by 19 // a function. 20 type SpecialReadFile struct { 21 read func(context.Context) ([]byte, time.Time, error) 22 } 23 24 var _ fs.Node = (*SpecialReadFile)(nil) 25 26 // Attr implements the fs.Node interface for SpecialReadFile. 27 func (f *SpecialReadFile) Attr(ctx context.Context, a *fuse.Attr) error { 28 data, t, err := f.read(ctx) 29 if err != nil { 30 return err 31 } 32 33 // Have a low non-zero value for Valid to avoid being swamped 34 // with requests, while still keeping the size up to date. 35 a.Valid = 1 * time.Second 36 // Some apps (e.g., Chrome) get confused if we use a 0 size 37 // here, as is usual for pseudofiles. So return the actual 38 // size, even though it may be racy. 39 a.Size = uint64(len(data)) 40 a.Mtime = t 41 a.Ctime = t 42 a.Mode = 0444 43 return nil 44 } 45 46 var _ fs.NodeOpener = (*SpecialReadFile)(nil) 47 48 // Open implements the fs.NodeOpener interface for SpecialReadFile. 49 func (f *SpecialReadFile) Open(ctx context.Context, req *fuse.OpenRequest, 50 resp *fuse.OpenResponse) (fs.Handle, error) { 51 data, _, err := f.read(ctx) 52 if err != nil { 53 return nil, err 54 } 55 56 resp.Flags |= fuse.OpenDirectIO 57 return fs.DataHandle(data), nil 58 }