mirror of
https://github.com/falk-werner/webfuse-provider
synced 2024-10-27 20:44:10 +00:00
used libuv to loop fuse
This commit is contained in:
parent
5d9c972ee7
commit
84aa5daf32
@ -1,42 +1,142 @@
|
|||||||
#include "wsfs/operations.h"
|
#include "wsfs/operations.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <uv.h>
|
||||||
|
|
||||||
|
#include "wsfs/util.h"
|
||||||
|
|
||||||
|
struct wsfs_fuse_context
|
||||||
|
{
|
||||||
|
struct fuse_args args;
|
||||||
|
struct fuse_session * session;
|
||||||
|
struct fuse_buf buffer;
|
||||||
|
struct wsfs_operations_context user_data;
|
||||||
|
int fd;
|
||||||
|
bool mounted;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct fuse_lowlevel_ops const wsfs_operations =
|
||||||
|
{
|
||||||
|
.lookup = &wsfs_operation_lookup,
|
||||||
|
.getattr = &wsfs_operation_getattr,
|
||||||
|
.readdir = &wsfs_operation_readdir,
|
||||||
|
.open = &wsfs_operation_open,
|
||||||
|
.release = &wsfs_operation_close,
|
||||||
|
.read = &wsfs_operation_read
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static bool wsfs_fuse_init(
|
||||||
|
struct wsfs_fuse_context * context,
|
||||||
|
char * mount_point,
|
||||||
|
struct wsfs_jsonrpc * rpc)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
char * argv[] = {"", NULL};
|
||||||
|
context->args.argc = 1;
|
||||||
|
context->args.argv = argv;
|
||||||
|
context->args.allocated = 0;
|
||||||
|
|
||||||
|
context->user_data.rpc = rpc;
|
||||||
|
context->user_data.timeout = 1.0;
|
||||||
|
memset(&context->buffer, 0, sizeof(struct fuse_buf));
|
||||||
|
|
||||||
|
context->session = fuse_session_new(&context->args, &wsfs_operations, sizeof(wsfs_operations), &context->user_data);
|
||||||
|
if (NULL != context->session)
|
||||||
|
{
|
||||||
|
result = (0 == fuse_session_mount(context->session, mount_point));
|
||||||
|
context->fd = fuse_session_fd(context->session);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup on error
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
if (NULL != context->session)
|
||||||
|
{
|
||||||
|
fuse_session_destroy(context->session);
|
||||||
|
context->session = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(context->buffer.mem);
|
||||||
|
fuse_opt_free_args(&context->args);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wsfs_fuse_cleanup(
|
||||||
|
struct wsfs_fuse_context * context)
|
||||||
|
{
|
||||||
|
if (NULL != context->session)
|
||||||
|
{
|
||||||
|
fuse_session_reset(context->session);
|
||||||
|
fuse_session_unmount(context->session);
|
||||||
|
fuse_session_destroy(context->session);
|
||||||
|
context->session = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(context->buffer.mem);
|
||||||
|
fuse_opt_free_args(&context->args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wsfs_fuse_onreadable(
|
||||||
|
uv_poll_t* handle,
|
||||||
|
int WSFS_UNUSED_PARAM(status),
|
||||||
|
int WSFS_UNUSED_PARAM(events))
|
||||||
|
{
|
||||||
|
struct wsfs_fuse_context * context = handle->data;
|
||||||
|
int const result = fuse_session_receive_buf(context->session, &context->buffer);
|
||||||
|
if (0 < result)
|
||||||
|
{
|
||||||
|
fuse_session_process_buf(context->session, &context->buffer);
|
||||||
|
}
|
||||||
|
else if (-EINTR != result)
|
||||||
|
{
|
||||||
|
uv_poll_stop(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wsfs_fuse_oninterrupt(uv_signal_t* handle, int WSFS_UNUSED_PARAM(signum))
|
||||||
|
{
|
||||||
|
uv_poll_t * poll_handle = handle->data;
|
||||||
|
uv_poll_stop(poll_handle);
|
||||||
|
}
|
||||||
|
|
||||||
int wsfs_operations_loop(
|
int wsfs_operations_loop(
|
||||||
char * mount_point,
|
char * mount_point,
|
||||||
struct wsfs_jsonrpc * rpc)
|
struct wsfs_jsonrpc * rpc)
|
||||||
{
|
{
|
||||||
struct fuse_lowlevel_ops operations;
|
uv_loop_t * loop = malloc(sizeof(uv_loop_t));
|
||||||
memset(&operations, 0, sizeof(struct fuse_lowlevel_ops));
|
uv_loop_init(loop);
|
||||||
operations.lookup = &wsfs_operation_lookup;
|
|
||||||
operations.getattr = &wsfs_operation_getattr;
|
|
||||||
operations.readdir = &wsfs_operation_readdir;
|
|
||||||
operations.open = &wsfs_operation_open;
|
|
||||||
operations.release = &wsfs_operation_close;
|
|
||||||
operations.read = &wsfs_operation_read;
|
|
||||||
|
|
||||||
int result = 1;
|
struct wsfs_fuse_context context;
|
||||||
const int argc = 1;
|
if (wsfs_fuse_init(&context, mount_point, rpc))
|
||||||
char * argv[] = {"", NULL};
|
|
||||||
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
|
||||||
struct wsfs_operations_context context = {
|
|
||||||
.rpc = rpc,
|
|
||||||
.timeout = 1.0
|
|
||||||
};
|
|
||||||
struct fuse_session * session = fuse_session_new(&args, &operations, sizeof(operations), &context);
|
|
||||||
if (NULL != session)
|
|
||||||
{
|
{
|
||||||
fuse_set_signal_handlers(session);
|
uv_poll_t handle;
|
||||||
result = fuse_session_mount(session, mount_point);
|
uv_poll_init(loop, &handle, context.fd);
|
||||||
if (0 == result)
|
handle.data = &context;
|
||||||
{
|
uv_poll_start(&handle, UV_READABLE, &wsfs_fuse_onreadable);
|
||||||
result = fuse_session_loop(session);
|
|
||||||
fuse_session_unmount(session);
|
uv_signal_t signal_interrupt;
|
||||||
}
|
uv_signal_init(loop, &signal_interrupt);
|
||||||
fuse_remove_signal_handlers(session);
|
signal_interrupt.data = &handle;
|
||||||
fuse_session_destroy(session);
|
uv_signal_start_oneshot(&signal_interrupt, &wsfs_fuse_oninterrupt, SIGINT);
|
||||||
|
|
||||||
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
uv_close((uv_handle_t*) &signal_interrupt, NULL);
|
||||||
|
uv_close((uv_handle_t*) &handle, NULL);
|
||||||
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
wsfs_fuse_cleanup(&context);
|
||||||
}
|
}
|
||||||
|
|
||||||
fuse_opt_free_args(&args);
|
uv_loop_close(loop);
|
||||||
|
free(loop);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user