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 5package libdokan 6 7import ( 8 "runtime/pprof" 9 10 "github.com/keybase/client/go/kbfs/dokan" 11 "github.com/keybase/client/go/kbfs/libfs" 12 "golang.org/x/net/context" 13) 14 15// TODO: Also have a file for CPU profiles. 16 17// ProfileList is a node that can list all of the available profiles. 18type ProfileList struct { 19 fs *FS 20 emptyFile 21} 22 23// GetFileInformation for dokan. 24func (ProfileList) GetFileInformation(ctx context.Context, fi *dokan.FileInfo) (st *dokan.Stat, err error) { 25 return defaultDirectoryInformation() 26} 27 28// open tries to open a file. 29func (pl ProfileList) open(ctx context.Context, oc *openContext, path []string) (dokan.File, dokan.CreateStatus, error) { 30 if len(path) == 0 { 31 return oc.returnDirNoCleanup(ProfileList{}) 32 } 33 if len(path) > 1 || !libfs.IsSupportedProfileName(path[0]) { 34 return nil, 0, dokan.ErrObjectNameNotFound 35 } 36 f := libfs.ProfileGet(path[0]) 37 if f == nil { 38 return nil, 0, dokan.ErrObjectNameNotFound 39 } 40 return oc.returnFileNoCleanup(&SpecialReadFile{read: f, fs: pl.fs}) 41} 42 43// FindFiles does readdir for dokan. 44func (ProfileList) FindFiles(ctx context.Context, fi *dokan.FileInfo, ignored string, callback func(*dokan.NamedStat) error) (err error) { 45 // TODO: eventually this should use `libfs.ListProfileNames`, but 46 // first we have to figure out how to use the dokan API to handle 47 // the timed profiles (i.e., only read them once on open, and not 48 // trigger the timed wait on every read). 49 profiles := pprof.Profiles() 50 var ns dokan.NamedStat 51 ns.FileAttributes = dokan.FileAttributeReadonly 52 for _, p := range profiles { 53 ns.Name = p.Name() 54 if !libfs.IsSupportedProfileName(ns.Name) { 55 continue 56 } 57 err := callback(&ns) 58 if err != nil { 59 return err 60 } 61 } 62 return nil 63} 64