From e98648f76f6ee3a56194500f5ab1fdee9130b8db Mon Sep 17 00:00:00 2001 From: John Mulligan Date: Fri, 14 Feb 2020 14:49:37 -0500 Subject: [PATCH] cephfs: add Directory type and funcs to open and close it Add the Directory type and the OpenDir function to get an open Directory and a Close function to close/free it. Signed-off-by: John Mulligan --- cephfs/directory.go | 49 ++++++++++++++++++++++++++++++++++++++++ cephfs/directory_test.go | 38 +++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 cephfs/directory.go create mode 100644 cephfs/directory_test.go diff --git a/cephfs/directory.go b/cephfs/directory.go new file mode 100644 index 0000000..774c983 --- /dev/null +++ b/cephfs/directory.go @@ -0,0 +1,49 @@ +package cephfs + +/* +#cgo LDFLAGS: -lcephfs +#cgo CPPFLAGS: -D_FILE_OFFSET_BITS=64 +#include +#include +#include +*/ +import "C" + +import ( + "unsafe" +) + +// Directory represents an open directory handle. +type Directory struct { + mount *MountInfo + dir *C.struct_ceph_dir_result +} + +// OpenDir returns a new Directory handle open for I/O. +// +// Implements: +// int ceph_opendir(struct ceph_mount_info *cmount, const char *name, struct ceph_dir_result **dirpp); +func (mount *MountInfo) OpenDir(path string) (*Directory, error) { + var dir *C.struct_ceph_dir_result + + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + ret := C.ceph_opendir(mount.mount, cPath, &dir) + if ret != 0 { + return nil, getError(ret) + } + + return &Directory{ + mount: mount, + dir: dir, + }, nil +} + +// Close the open directory handle. +// +// Implements: +// int ceph_closedir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp); +func (dir *Directory) Close() error { + return getError(C.ceph_closedir(dir.mount.mount, dir.dir)) +} diff --git a/cephfs/directory_test.go b/cephfs/directory_test.go new file mode 100644 index 0000000..e3d3f06 --- /dev/null +++ b/cephfs/directory_test.go @@ -0,0 +1,38 @@ +package cephfs + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestOpenCloseDir(t *testing.T) { + mount := fsConnect(t) + defer fsDisconnect(t, mount) + + dir1 := "/base" + err := mount.MakeDir(dir1, 0755) + assert.NoError(t, err) + defer func() { assert.NoError(t, mount.RemoveDir(dir1)) }() + + dir2 := dir1 + "/a" + err = mount.MakeDir(dir2, 0755) + assert.NoError(t, err) + defer func() { assert.NoError(t, mount.RemoveDir(dir2)) }() + + dir, err := mount.OpenDir(dir1) + assert.NoError(t, err) + assert.NotNil(t, dir) + err = dir.Close() + assert.NoError(t, err) + + dir, err = mount.OpenDir(dir2) + assert.NoError(t, err) + assert.NotNil(t, dir) + err = dir.Close() + assert.NoError(t, err) + + dir, err = mount.OpenDir("/no.such.dir") + assert.Error(t, err) + assert.Nil(t, dir) +}