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  }