func (f *fs) handleOpen(r *fuse.OpenRequest) { log.Println("Inside handleOpen") log.Println(r) resp := &fuse.OpenResponse{} // For now use the inode as the file handle resp.Handle = f.handles.newFileHandle(r.Node) log.Println(resp) r.Respond(resp) }
func TestOpen(t *testing.T) { t.Parallel() f := &open{} mnt, err := fstestutil.MountedT(t, childMapFS{"child": f}) if err != nil { t.Fatal(err) } defer mnt.Close() // node: mode only matters with O_CREATE fil, err := os.OpenFile(mnt.Dir+"/child", os.O_WRONLY|os.O_APPEND, 0) if err == nil { t.Error("Open err == nil, expected ENAMETOOLONG") fil.Close() return } switch err2 := err.(type) { case *os.PathError: if err2.Err == syscall.ENAMETOOLONG { break } t.Errorf("unexpected inner error: %#v", err2) default: t.Errorf("unexpected error: %v", err) } want := fuse.OpenRequest{Dir: false, Flags: fuse.OpenWriteOnly | fuse.OpenAppend} if runtime.GOOS == "darwin" { // osxfuse does not let O_APPEND through at all // // https://code.google.com/p/macfuse/issues/detail?id=233 // https://code.google.com/p/macfuse/issues/detail?id=132 // https://code.google.com/p/macfuse/issues/detail?id=133 want.Flags &^= fuse.OpenAppend } got := f.RecordedOpen() if runtime.GOOS == "linux" { // Linux <3.7 accidentally leaks O_CLOEXEC through to FUSE; // avoid spurious test failures got.Flags &^= fuse.OpenFlags(syscall.O_CLOEXEC) } if g, e := got, want; g != e { t.Errorf("open saw %v, want %v", g, e) return } }
// Allocate a file handle, held by the kernel until Release func (sc *serveConn) open(req *fuse.OpenRequest) { // This will be cheap, Lookup always preceeds Open, so the cache is warm f, err := sc.db.FileByInode(uint64(req.Header.Node)) if err != nil { req.RespondError(fuse.ENOENT) return } var hId uint64 if !req.Flags.IsReadOnly() { // write access requested if *readOnly { // TODO: if allow_other, require uid == invoking uid to allow writes req.RespondError(fuse.EPERM) return } r, w := io.Pipe() // plumbing between WriteRequest and Drive go sc.updateInDrive(f.File, r) hId = sc.allocHandle(req.Header.Node, w) } else { hId = sc.allocHandle(req.Header.Node, nil) } resp := fuse.OpenResponse{Handle: fuse.HandleID(hId)} fuse.Debug(fmt.Sprintf("Open Response: %+v", resp)) req.Respond(&resp) }