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  }