github.com/puellanivis/breton@v0.2.16/lib/files/fd.go (about) 1 package files 2 3 import ( 4 "context" 5 "net/url" 6 "os" 7 "strings" 8 ) 9 10 type descriptorHandler struct{} 11 12 func init() { 13 RegisterScheme(&descriptorHandler{}, "fd") 14 } 15 16 func openFD(uri *url.URL) (*os.File, error) { 17 if uri.Host != "" || uri.User != nil { 18 return nil, os.ErrInvalid 19 } 20 21 num := strings.TrimPrefix(uri.Path, "/") 22 if num == "" { 23 var err error 24 num, err = url.PathUnescape(uri.Opaque) 25 if err != nil { 26 return nil, os.ErrInvalid 27 } 28 } 29 30 fd, err := resolveFileHandle(num) 31 if err != nil { 32 return nil, err 33 } 34 35 // Canonicalize the name. 36 uri = &url.URL{ 37 Scheme: "fd", 38 Opaque: url.PathEscape(num), 39 } 40 41 return os.NewFile(uintptr(fd), uri.String()), nil 42 } 43 44 func (*descriptorHandler) Open(ctx context.Context, uri *url.URL) (Reader, error) { 45 f, err := openFD(uri) 46 if err != nil { 47 return nil, &os.PathError{ 48 Op: "open", 49 Path: uri.String(), 50 Err: err, 51 } 52 } 53 54 return f, nil 55 } 56 57 func (*descriptorHandler) Create(ctx context.Context, uri *url.URL) (Writer, error) { 58 f, err := openFD(uri) 59 if err != nil { 60 return nil, &os.PathError{ 61 Op: "create", 62 Path: uri.String(), 63 Err: err, 64 } 65 } 66 67 return f, nil 68 } 69 70 func (*descriptorHandler) List(ctx context.Context, uri *url.URL) ([]os.FileInfo, error) { 71 f, err := openFD(uri) 72 if err != nil { 73 return nil, &os.PathError{ 74 Op: "open", 75 Path: uri.String(), 76 Err: err, 77 } 78 } 79 80 return f.Readdir(0) 81 }