mirror of
https://github.com/fuse-friends/fuse-native
synced 2024-10-27 18:34:01 +00:00
removed unmountSync and regular unmount stops fuse now
This commit is contained in:
parent
22b23a217a
commit
4da0b89217
@ -89,10 +89,6 @@ Pass the FUSE operations you want to support as the `ops` argument.
|
|||||||
|
|
||||||
Unmount a filesystem
|
Unmount a filesystem
|
||||||
|
|
||||||
#### `fuse.unmountSync(mnt)`
|
|
||||||
|
|
||||||
Unmount a filesystem synchroniously
|
|
||||||
|
|
||||||
## FUSE operations
|
## FUSE operations
|
||||||
|
|
||||||
Most of the [FUSE api](http://fuse.sourceforge.net/doxygen/structfuse__operations.html) is supported.
|
Most of the [FUSE api](http://fuse.sourceforge.net/doxygen/structfuse__operations.html) is supported.
|
||||||
|
101
fuse-bindings.cc
101
fuse-bindings.cc
@ -3,6 +3,8 @@
|
|||||||
#define FUSE_USE_VERSION 29
|
#define FUSE_USE_VERSION 29
|
||||||
|
|
||||||
#include <fuse.h>
|
#include <fuse.h>
|
||||||
|
#include <fuse_opt.h>
|
||||||
|
#include <fuse_lowlevel.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -62,6 +64,8 @@ static struct {
|
|||||||
// fuse data
|
// fuse data
|
||||||
char mnt[1024];
|
char mnt[1024];
|
||||||
char mntopts[1024];
|
char mntopts[1024];
|
||||||
|
struct fuse *fuse;
|
||||||
|
struct fuse_chan *fuse_channel;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
dispatch_semaphore_t semaphore;
|
dispatch_semaphore_t semaphore;
|
||||||
@ -121,10 +125,6 @@ static struct {
|
|||||||
} bindings;
|
} bindings;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static void bindings_unmount (char *path) {
|
|
||||||
unmount(path, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
NAN_INLINE static int semaphore_init (dispatch_semaphore_t *sem) {
|
NAN_INLINE static int semaphore_init (dispatch_semaphore_t *sem) {
|
||||||
*sem = dispatch_semaphore_create(0);
|
*sem = dispatch_semaphore_create(0);
|
||||||
return *sem == NULL ? -1 : 0;
|
return *sem == NULL ? -1 : 0;
|
||||||
@ -138,14 +138,6 @@ NAN_INLINE static void semaphore_signal (dispatch_semaphore_t *sem) {
|
|||||||
dispatch_semaphore_signal(*sem);
|
dispatch_semaphore_signal(*sem);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void bindings_unmount (char *path) {
|
|
||||||
// TODO: if someone knows a better way to get this working on linux let me know
|
|
||||||
char *argv[] = {"fusermount", "-q", "-u", path, NULL};
|
|
||||||
pid_t cpid = vfork();
|
|
||||||
if (cpid > 0) waitpid(cpid, NULL, 0);
|
|
||||||
else execvp(argv[0], argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
NAN_INLINE static int semaphore_init (sem_t *sem) {
|
NAN_INLINE static int semaphore_init (sem_t *sem) {
|
||||||
return sem_init(sem, 0, 0);
|
return sem_init(sem, 0, 0);
|
||||||
}
|
}
|
||||||
@ -159,6 +151,25 @@ NAN_INLINE static void semaphore_signal (sem_t *sem) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void bindings_unmount (char *path) {
|
||||||
|
if (!strcmp(bindings.mnt, path) && bindings.fuse != NULL) {
|
||||||
|
fuse_unmount(bindings.mnt, bindings.fuse_channel);
|
||||||
|
pthread_join(bindings.thread, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
unmount(path, 0);
|
||||||
|
#else
|
||||||
|
// TODO: if someone knows a better way to get this working on linux let me know
|
||||||
|
char *argv[] = {"fusermount", "-q", "-u", path, NULL};
|
||||||
|
pid_t cpid = vfork();
|
||||||
|
if (cpid > 0) waitpid(cpid, NULL, 0);
|
||||||
|
else execvp(argv[0], argv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
|
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
|
||||||
NAN_INLINE v8::Local<v8::Object> bindings_buffer (char *data, size_t length) {
|
NAN_INLINE v8::Local<v8::Object> bindings_buffer (char *data, size_t length) {
|
||||||
Local<Object> buf = NanNew(buffer_constructor)->NewInstance(0, NULL);
|
Local<Object> buf = NanNew(buffer_constructor)->NewInstance(0, NULL);
|
||||||
@ -472,18 +483,59 @@ static void *bindings_thread (void *) {
|
|||||||
if (bindings.ops_init != NULL) ops.init = bindings_init;
|
if (bindings.ops_init != NULL) ops.init = bindings_init;
|
||||||
if (bindings.ops_destroy != NULL) ops.destroy = bindings_destroy;
|
if (bindings.ops_destroy != NULL) ops.destroy = bindings_destroy;
|
||||||
|
|
||||||
|
int argc = !strcmp(bindings.mntopts, "-o") ? 1 : 2;
|
||||||
char *argv[] = {
|
char *argv[] = {
|
||||||
(char *) "fuse_bindings_dummy",
|
(char *) "fuse_bindings_dummy",
|
||||||
(char *) "-s",
|
|
||||||
(char *) "-f",
|
|
||||||
(char *) bindings.mnt,
|
|
||||||
(char *) bindings.mntopts
|
(char *) bindings.mntopts
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fuse_main(!strcmp(bindings.mntopts, "-o") ? 4 : 5, argv, &ops, NULL)) {
|
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
||||||
bindings.op = OP_ERROR;
|
struct fuse_chan *ch = bindings.fuse_channel = fuse_mount(bindings.mnt, &args);
|
||||||
bindings_call();
|
|
||||||
}
|
int ops_size = sizeof(struct fuse_operations);
|
||||||
|
bindings.fuse = fuse_new(ch, &args, &ops, ops_size, NULL);
|
||||||
|
bindings.fuse_channel = ch;
|
||||||
|
|
||||||
|
fuse_loop(bindings.fuse);
|
||||||
|
fuse_session_remove_chan(ch);
|
||||||
|
fuse_destroy(bindings.fuse);
|
||||||
|
|
||||||
|
uv_close((uv_handle_t*) &bindings.async, NULL);
|
||||||
|
|
||||||
|
if (bindings.ops_access != NULL) delete bindings.ops_access;
|
||||||
|
if (bindings.ops_truncate != NULL) delete bindings.ops_truncate;
|
||||||
|
if (bindings.ops_ftruncate != NULL) delete bindings.ops_ftruncate;
|
||||||
|
if (bindings.ops_getattr != NULL) delete bindings.ops_getattr;
|
||||||
|
if (bindings.ops_fgetattr != NULL) delete bindings.ops_fgetattr;
|
||||||
|
if (bindings.ops_flush != NULL) delete bindings.ops_flush;
|
||||||
|
if (bindings.ops_fsync != NULL) delete bindings.ops_fsync;
|
||||||
|
if (bindings.ops_fsyncdir != NULL) delete bindings.ops_fsyncdir;
|
||||||
|
if (bindings.ops_readdir != NULL) delete bindings.ops_readdir;
|
||||||
|
if (bindings.ops_readlink != NULL) delete bindings.ops_readlink;
|
||||||
|
if (bindings.ops_chown != NULL) delete bindings.ops_chown;
|
||||||
|
if (bindings.ops_chmod != NULL) delete bindings.ops_chmod;
|
||||||
|
if (bindings.ops_setxattr != NULL) delete bindings.ops_setxattr;
|
||||||
|
if (bindings.ops_getxattr != NULL) delete bindings.ops_getxattr;
|
||||||
|
if (bindings.ops_statfs != NULL) delete bindings.ops_statfs;
|
||||||
|
if (bindings.ops_open != NULL) delete bindings.ops_open;
|
||||||
|
if (bindings.ops_opendir != NULL) delete bindings.ops_opendir;
|
||||||
|
if (bindings.ops_read != NULL) delete bindings.ops_read;
|
||||||
|
if (bindings.ops_write != NULL) delete bindings.ops_write;
|
||||||
|
if (bindings.ops_release != NULL) delete bindings.ops_release;
|
||||||
|
if (bindings.ops_releasedir != NULL) delete bindings.ops_releasedir;
|
||||||
|
if (bindings.ops_create != NULL) delete bindings.ops_create;
|
||||||
|
if (bindings.ops_utimens != NULL) delete bindings.ops_utimens;
|
||||||
|
if (bindings.ops_unlink != NULL) delete bindings.ops_unlink;
|
||||||
|
if (bindings.ops_rename != NULL) delete bindings.ops_rename;
|
||||||
|
if (bindings.ops_link != NULL) delete bindings.ops_link;
|
||||||
|
if (bindings.ops_symlink != NULL) delete bindings.ops_symlink;
|
||||||
|
if (bindings.ops_mkdir != NULL) delete bindings.ops_mkdir;
|
||||||
|
if (bindings.ops_rmdir != NULL) delete bindings.ops_rmdir;
|
||||||
|
if (bindings.ops_init != NULL) delete bindings.ops_init;
|
||||||
|
if (bindings.ops_destroy != NULL) delete bindings.ops_destroy;
|
||||||
|
|
||||||
|
bindings.fuse = NULL;
|
||||||
|
bindings_in_use = 0;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -867,7 +919,8 @@ NAN_METHOD(Mount) {
|
|||||||
if (bindings_in_use) return NanThrowError("Currently only a single filesystem can be mounted at the time");
|
if (bindings_in_use) return NanThrowError("Currently only a single filesystem can be mounted at the time");
|
||||||
bindings_in_use = 1;
|
bindings_in_use = 1;
|
||||||
|
|
||||||
memset(&empty_stat, 0, sizeof(empty_stat)); // zero empty stat
|
memset(&empty_stat, 0, sizeof(empty_stat));
|
||||||
|
memset(&bindings, 0, sizeof(bindings));
|
||||||
|
|
||||||
NanUtf8String path(args[0]);
|
NanUtf8String path(args[0]);
|
||||||
Local<Object> ops = args[1].As<Object>();
|
Local<Object> ops = args[1].As<Object>();
|
||||||
@ -928,13 +981,6 @@ NAN_METHOD(Mount) {
|
|||||||
NanReturnUndefined();
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
NAN_METHOD(UnmountSync) {
|
|
||||||
NanScope();
|
|
||||||
NanUtf8String path(args[0]);
|
|
||||||
bindings_unmount(*path);
|
|
||||||
NanReturnUndefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
class UnmountWorker : public NanAsyncWorker {
|
class UnmountWorker : public NanAsyncWorker {
|
||||||
public:
|
public:
|
||||||
UnmountWorker(NanCallback *callback, char *path)
|
UnmountWorker(NanCallback *callback, char *path)
|
||||||
@ -979,7 +1025,6 @@ void Init(Handle<Object> exports) {
|
|||||||
exports->Set(NanNew("setBuffer"), NanNew<FunctionTemplate>(SetBuffer)->GetFunction());
|
exports->Set(NanNew("setBuffer"), NanNew<FunctionTemplate>(SetBuffer)->GetFunction());
|
||||||
exports->Set(NanNew("mount"), NanNew<FunctionTemplate>(Mount)->GetFunction());
|
exports->Set(NanNew("mount"), NanNew<FunctionTemplate>(Mount)->GetFunction());
|
||||||
exports->Set(NanNew("unmount"), NanNew<FunctionTemplate>(Unmount)->GetFunction());
|
exports->Set(NanNew("unmount"), NanNew<FunctionTemplate>(Unmount)->GetFunction());
|
||||||
exports->Set(NanNew("unmountSync"), NanNew<FunctionTemplate>(UnmountSync)->GetFunction());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NODE_MODULE(fuse_bindings, Init)
|
NODE_MODULE(fuse_bindings, Init)
|
20
index.js
20
index.js
@ -22,18 +22,26 @@ exports.mount = function (mnt, ops, cb) {
|
|||||||
if (/\*|(^,)fuse-bindings(,$)/.test(process.env.DEBUG)) ops.options = ['debug'].concat(ops.options || [])
|
if (/\*|(^,)fuse-bindings(,$)/.test(process.env.DEBUG)) ops.options = ['debug'].concat(ops.options || [])
|
||||||
mnt = path.resolve(mnt)
|
mnt = path.resolve(mnt)
|
||||||
|
|
||||||
|
var callback = function (err) {
|
||||||
|
callback = noop
|
||||||
|
ops.init = init
|
||||||
|
ops.error = error
|
||||||
|
process.nextTick(cb.bind(null, err))
|
||||||
|
}
|
||||||
|
|
||||||
var init = ops.init || call
|
var init = ops.init || call
|
||||||
ops.init = function (next) {
|
ops.init = function (next) {
|
||||||
cb()
|
callback()
|
||||||
init(next)
|
init(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
var error = ops.error || call
|
var error = ops.error || call
|
||||||
ops.error = function (next) {
|
ops.error = function (next) {
|
||||||
cb(new Error('Mount failed'))
|
callback(new Error('Mount failed'))
|
||||||
error(next)
|
error(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mount = function () {
|
||||||
fs.stat(mnt, function (err, stat) {
|
fs.stat(mnt, function (err, stat) {
|
||||||
if (err) return cb(new Error('Mountpoint does not exist'))
|
if (err) return cb(new Error('Mountpoint does not exist'))
|
||||||
if (!stat.isDirectory()) return cb(new Error('Mountpoint is not a directory'))
|
if (!stat.isDirectory()) return cb(new Error('Mountpoint is not a directory'))
|
||||||
@ -42,16 +50,16 @@ exports.mount = function (mnt, ops, cb) {
|
|||||||
fuse.mount(mnt, ops)
|
fuse.mount(mnt, ops)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ops.force) return mount()
|
||||||
|
exports.unmount(mnt, mount)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.unmount = function (mnt, cb) {
|
exports.unmount = function (mnt, cb) {
|
||||||
fuse.unmount(path.resolve(mnt), cb || noop)
|
fuse.unmount(path.resolve(mnt), cb || noop)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.unmountSync = function (mnt) {
|
|
||||||
return fuse.unmountSync(path.resolve(mnt))
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.EPERM = -1
|
exports.EPERM = -1
|
||||||
exports.ENOENT = -2
|
exports.ENOENT = -2
|
||||||
exports.ESRCH = -3
|
exports.ESRCH = -3
|
||||||
|
Loading…
Reference in New Issue
Block a user