Beispiel #1
0
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)
}
Beispiel #2
0
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
	}
}
Beispiel #3
0
// 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)
}