mirror of
https://github.com/fuse-friends/fuse-native
synced 2024-10-27 18:34:01 +00:00
0.10 support
This commit is contained in:
parent
51e3fac2b1
commit
eb7c7f1367
@ -50,6 +50,7 @@ enum bindings_ops_t {
|
|||||||
OP_DESTROY
|
OP_DESTROY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Persistent<Function> buffer_constructor;
|
||||||
static struct stat empty_stat;
|
static struct stat empty_stat;
|
||||||
|
|
||||||
// TODO support more than a single mount
|
// TODO support more than a single mount
|
||||||
@ -65,9 +66,6 @@ static struct {
|
|||||||
#endif
|
#endif
|
||||||
uv_async_t async;
|
uv_async_t async;
|
||||||
|
|
||||||
// buffer
|
|
||||||
Persistent<Object> buffer_persistent;
|
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
NanCallback *ops_init;
|
NanCallback *ops_init;
|
||||||
NanCallback *ops_access;
|
NanCallback *ops_access;
|
||||||
@ -140,7 +138,7 @@ static void bindings_unmount (char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int semaphore_init (sem_t *sem) {
|
static int semaphore_init (sem_t *sem) {
|
||||||
return sem_init(sem, 0, 1);
|
return sem_init(sem, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void semaphore_wait (sem_t *sem) {
|
static void semaphore_wait (sem_t *sem) {
|
||||||
@ -152,7 +150,21 @@ static void semaphore_signal (sem_t *sem) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int bindings_call () {
|
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
|
||||||
|
NAN_INLINE v8::Local<v8::Object> bindings_buffer (char *data, size_t length) {
|
||||||
|
Local<Object> buf = NanNew(buffer_constructor)->NewInstance(0, NULL);
|
||||||
|
buf->Set(NanNew<String>("length"), NanNew<Number>(length));
|
||||||
|
buf->SetIndexedPropertiesToExternalArrayData((char *) data, kExternalUnsignedByteArray, length);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void noop (char *data, void *hint) {}
|
||||||
|
NAN_INLINE v8::Local<v8::Object> bindings_buffer (char *data, size_t length) {
|
||||||
|
return NanNewBufferHandle(data, length, noop, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NAN_INLINE static int bindings_call () {
|
||||||
uv_async_send(&bindings.async);
|
uv_async_send(&bindings.async);
|
||||||
semaphore_wait(&bindings.semaphore);
|
semaphore_wait(&bindings.semaphore);
|
||||||
return bindings.result;
|
return bindings.result;
|
||||||
@ -469,7 +481,7 @@ static void *bindings_thread (void *) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_set_date (Local<Date> date, struct timespec *out) {
|
NAN_INLINE static void bindings_set_date (Local<Date> date, struct timespec *out) {
|
||||||
double ms = date->NumberValue();
|
double ms = date->NumberValue();
|
||||||
time_t secs = (time_t)(ms / 1000.0);
|
time_t secs = (time_t)(ms / 1000.0);
|
||||||
time_t rem = ms - (1000.0 * secs);
|
time_t rem = ms - (1000.0 * secs);
|
||||||
@ -478,7 +490,7 @@ static void bindings_set_date (Local<Date> date, struct timespec *out) {
|
|||||||
out->tv_nsec = ns;
|
out->tv_nsec = ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_set_stat (Local<Object> obj, struct stat *stat) {
|
NAN_INLINE static void bindings_set_stat (Local<Object> obj, struct stat *stat) {
|
||||||
if (obj->Has(NanNew<String>("dev"))) stat->st_dev = obj->Get(NanNew<String>("dev"))->NumberValue();
|
if (obj->Has(NanNew<String>("dev"))) stat->st_dev = obj->Get(NanNew<String>("dev"))->NumberValue();
|
||||||
if (obj->Has(NanNew<String>("ino"))) stat->st_ino = obj->Get(NanNew<String>("ino"))->NumberValue();
|
if (obj->Has(NanNew<String>("ino"))) stat->st_ino = obj->Get(NanNew<String>("ino"))->NumberValue();
|
||||||
if (obj->Has(NanNew<String>("mode"))) stat->st_mode = obj->Get(NanNew<String>("mode"))->Uint32Value();
|
if (obj->Has(NanNew<String>("mode"))) stat->st_mode = obj->Get(NanNew<String>("mode"))->Uint32Value();
|
||||||
@ -500,12 +512,12 @@ static void bindings_set_stat (Local<Object> obj, struct stat *stat) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_set_utimens (Local<Object> obj, struct timespec tv[2]) {
|
NAN_INLINE static void bindings_set_utimens (Local<Object> obj, struct timespec tv[2]) {
|
||||||
if (obj->Has(NanNew<String>("atime"))) bindings_set_date(obj->Get(NanNew("atime")).As<Date>(), &tv[0]);
|
if (obj->Has(NanNew<String>("atime"))) bindings_set_date(obj->Get(NanNew("atime")).As<Date>(), &tv[0]);
|
||||||
if (obj->Has(NanNew<String>("mtime"))) bindings_set_date(obj->Get(NanNew("mtime")).As<Date>(), &tv[1]);
|
if (obj->Has(NanNew<String>("mtime"))) bindings_set_date(obj->Get(NanNew("mtime")).As<Date>(), &tv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_set_statfs (Local<Object> obj, struct statvfs *statfs) { // from http://linux.die.net/man/2/stat
|
NAN_INLINE static void bindings_set_statfs (Local<Object> obj, struct statvfs *statfs) { // from http://linux.die.net/man/2/stat
|
||||||
if (obj->Has(NanNew<String>("bsize"))) statfs->f_bsize = obj->Get(NanNew<String>("bsize"))->Uint32Value();
|
if (obj->Has(NanNew<String>("bsize"))) statfs->f_bsize = obj->Get(NanNew<String>("bsize"))->Uint32Value();
|
||||||
if (obj->Has(NanNew<String>("frsize"))) statfs->f_frsize = obj->Get(NanNew<String>("frsize"))->Uint32Value();
|
if (obj->Has(NanNew<String>("frsize"))) statfs->f_frsize = obj->Get(NanNew<String>("frsize"))->Uint32Value();
|
||||||
if (obj->Has(NanNew<String>("blocks"))) statfs->f_blocks = obj->Get(NanNew<String>("blocks"))->Uint32Value();
|
if (obj->Has(NanNew<String>("blocks"))) statfs->f_blocks = obj->Get(NanNew<String>("blocks"))->Uint32Value();
|
||||||
@ -519,14 +531,14 @@ static void bindings_set_statfs (Local<Object> obj, struct statvfs *statfs) { //
|
|||||||
if (obj->Has(NanNew<String>("namemax"))) statfs->f_namemax = obj->Get(NanNew<String>("namemax"))->Uint32Value();
|
if (obj->Has(NanNew<String>("namemax"))) statfs->f_namemax = obj->Get(NanNew<String>("namemax"))->Uint32Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_set_dirs (Local<Array> dirs) {
|
NAN_INLINE static void bindings_set_dirs (Local<Array> dirs) {
|
||||||
for (uint32_t i = 0; i < dirs->Length(); i++) {
|
for (uint32_t i = 0; i < dirs->Length(); i++) {
|
||||||
NanUtf8String dir(dirs->Get(i));
|
NanUtf8String dir(dirs->Get(i));
|
||||||
if (bindings.filler(bindings.data, *dir, &empty_stat, 0)) break;
|
if (bindings.filler(bindings.data, *dir, &empty_stat, 0)) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_set_fd (Local<Number> fd) {
|
NAN_INLINE static void bindings_set_fd (Local<Number> fd) {
|
||||||
bindings.info->fh = fd->Uint32Value();
|
bindings.info->fh = fd->Uint32Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +607,7 @@ NAN_METHOD(OpCallback) {
|
|||||||
NanReturnUndefined();
|
NanReturnUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bindings_call_op (NanCallback *fn, int argc, Local<Value> *argv) {
|
NAN_INLINE static void bindings_call_op (NanCallback *fn, int argc, Local<Value> *argv) {
|
||||||
if (fn == NULL) semaphore_signal(&bindings.semaphore);
|
if (fn == NULL) semaphore_signal(&bindings.semaphore);
|
||||||
else fn->Call(argc, argv);
|
else fn->Call(argc, argv);
|
||||||
}
|
}
|
||||||
@ -672,37 +684,27 @@ static void bindings_dispatch (uv_async_t* handle, int status) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case OP_WRITE: {
|
case OP_WRITE: {
|
||||||
Local<Object> buf = NanNew(bindings.buffer_persistent);
|
|
||||||
buf->Set(NanNew<String>("length"), NanNew<Number>(bindings.length));
|
|
||||||
buf->SetIndexedPropertiesToExternalArrayData((char *) bindings.data, kExternalUnsignedByteArray, bindings.length);
|
|
||||||
|
|
||||||
Local<Value> tmp[] = {
|
Local<Value> tmp[] = {
|
||||||
NanNew<String>(bindings.path),
|
NanNew<String>(bindings.path),
|
||||||
NanNew<Number>(bindings.info->fh),
|
NanNew<Number>(bindings.info->fh),
|
||||||
buf,
|
bindings_buffer((char *) bindings.data, bindings.length),
|
||||||
NanNew<Number>(bindings.length),
|
NanNew<Number>(bindings.length),
|
||||||
NanNew<Number>(bindings.offset),
|
NanNew<Number>(bindings.offset),
|
||||||
callback
|
callback
|
||||||
};
|
};
|
||||||
|
|
||||||
bindings_call_op(bindings.ops_write, 6, tmp);
|
bindings_call_op(bindings.ops_write, 6, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case OP_READ: {
|
case OP_READ: {
|
||||||
Local<Object> buf = NanNew(bindings.buffer_persistent);
|
|
||||||
buf->Set(NanNew<String>("length"), NanNew<Number>(bindings.length));
|
|
||||||
buf->SetIndexedPropertiesToExternalArrayData((char *) bindings.data, kExternalUnsignedByteArray, bindings.length);
|
|
||||||
|
|
||||||
Local<Value> tmp[] = {
|
Local<Value> tmp[] = {
|
||||||
NanNew<String>(bindings.path),
|
NanNew<String>(bindings.path),
|
||||||
NanNew<Number>(bindings.info->fh),
|
NanNew<Number>(bindings.info->fh),
|
||||||
buf,
|
bindings_buffer((char *) bindings.data, bindings.length),
|
||||||
NanNew<Number>(bindings.length),
|
NanNew<Number>(bindings.length),
|
||||||
NanNew<Number>(bindings.offset),
|
NanNew<Number>(bindings.offset),
|
||||||
callback
|
callback
|
||||||
};
|
};
|
||||||
|
|
||||||
bindings_call_op(bindings.ops_read, 6, tmp);
|
bindings_call_op(bindings.ops_read, 6, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -756,48 +758,39 @@ static void bindings_dispatch (uv_async_t* handle, int status) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case OP_READLINK: {
|
case OP_READLINK: {
|
||||||
Local<Object> buf = NanNew(bindings.buffer_persistent);
|
Local<Value> tmp[] = {
|
||||||
buf->Set(NanNew<String>("length"), NanNew<Number>(bindings.length));
|
NanNew<String>(bindings.path),
|
||||||
buf->SetIndexedPropertiesToExternalArrayData((char *) bindings.data, kExternalUnsignedByteArray, bindings.length);
|
bindings_buffer((char *) bindings.data, bindings.length),
|
||||||
|
NanNew<Number>(bindings.length),
|
||||||
Local<Value> tmp[] = {NanNew<String>(bindings.path), buf, NanNew<Number>(bindings.length), callback};
|
callback
|
||||||
|
};
|
||||||
bindings_call_op(bindings.ops_readlink, 4, tmp);
|
bindings_call_op(bindings.ops_readlink, 4, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case OP_SETXATTR: {
|
case OP_SETXATTR: {
|
||||||
Local<Object> buf = NanNew(bindings.buffer_persistent);
|
|
||||||
buf->Set(NanNew<String>("length"), NanNew<Number>(bindings.length));
|
|
||||||
buf->SetIndexedPropertiesToExternalArrayData((char *) bindings.data, kExternalUnsignedByteArray, bindings.length);
|
|
||||||
|
|
||||||
Local<Value> tmp[] = {
|
Local<Value> tmp[] = {
|
||||||
NanNew<String>(bindings.path),
|
NanNew<String>(bindings.path),
|
||||||
NanNew<String>(bindings.name),
|
NanNew<String>(bindings.name),
|
||||||
buf,
|
bindings_buffer((char *) bindings.data, bindings.length),
|
||||||
NanNew<Number>(bindings.length),
|
NanNew<Number>(bindings.length),
|
||||||
NanNew<Number>(bindings.offset),
|
NanNew<Number>(bindings.offset),
|
||||||
NanNew<Number>(bindings.mode),
|
NanNew<Number>(bindings.mode),
|
||||||
callback
|
callback
|
||||||
};
|
};
|
||||||
|
|
||||||
bindings_call_op(bindings.ops_setxattr, 7, tmp);
|
bindings_call_op(bindings.ops_setxattr, 7, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case OP_GETXATTR: {
|
case OP_GETXATTR: {
|
||||||
Local<Object> buf = NanNew(bindings.buffer_persistent);
|
|
||||||
buf->Set(NanNew<String>("length"), NanNew<Number>(bindings.length));
|
|
||||||
buf->SetIndexedPropertiesToExternalArrayData((char *) bindings.data, kExternalUnsignedByteArray, bindings.length);
|
|
||||||
|
|
||||||
Local<Value> tmp[] = {
|
Local<Value> tmp[] = {
|
||||||
NanNew<String>(bindings.path),
|
NanNew<String>(bindings.path),
|
||||||
NanNew<String>(bindings.name),
|
NanNew<String>(bindings.name),
|
||||||
buf,
|
bindings_buffer((char *) bindings.data, bindings.length),
|
||||||
NanNew<Number>(bindings.length),
|
NanNew<Number>(bindings.length),
|
||||||
NanNew<Number>(bindings.offset),
|
NanNew<Number>(bindings.offset),
|
||||||
callback
|
callback
|
||||||
};
|
};
|
||||||
|
|
||||||
bindings_call_op(bindings.ops_getxattr, 6, tmp);
|
bindings_call_op(bindings.ops_getxattr, 6, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -893,8 +886,6 @@ NAN_METHOD(Mount) {
|
|||||||
bindings.ops_rmdir = ops->Has(NanNew<String>("rmdir")) ? new NanCallback(ops->Get(NanNew<String>("rmdir")).As<Function>()) : NULL;
|
bindings.ops_rmdir = ops->Has(NanNew<String>("rmdir")) ? new NanCallback(ops->Get(NanNew<String>("rmdir")).As<Function>()) : NULL;
|
||||||
bindings.ops_destroy = ops->Has(NanNew<String>("destroy")) ? new NanCallback(ops->Get(NanNew<String>("destroy")).As<Function>()) : NULL;
|
bindings.ops_destroy = ops->Has(NanNew<String>("destroy")) ? new NanCallback(ops->Get(NanNew<String>("destroy")).As<Function>()) : NULL;
|
||||||
|
|
||||||
NanAssignPersistent(bindings.buffer_persistent, args[2].As<Object>());
|
|
||||||
|
|
||||||
bindings.callback = new NanCallback(NanNew<FunctionTemplate>(OpCallback)->GetFunction());
|
bindings.callback = new NanCallback(NanNew<FunctionTemplate>(OpCallback)->GetFunction());
|
||||||
stpcpy(bindings.mnt, *path);
|
stpcpy(bindings.mnt, *path);
|
||||||
stpcpy(bindings.mntopts, "-o");
|
stpcpy(bindings.mntopts, "-o");
|
||||||
@ -945,6 +936,12 @@ class UnmountWorker : public NanAsyncWorker {
|
|||||||
char *path;
|
char *path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NAN_METHOD(SetBuffer) {
|
||||||
|
NanScope();
|
||||||
|
NanAssignPersistent(buffer_constructor, args[0].As<Function>());
|
||||||
|
NanReturnUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
NAN_METHOD(Unmount) {
|
NAN_METHOD(Unmount) {
|
||||||
NanScope();
|
NanScope();
|
||||||
NanUtf8String path(args[0]);
|
NanUtf8String path(args[0]);
|
||||||
@ -958,6 +955,7 @@ NAN_METHOD(Unmount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Init(Handle<Object> exports) {
|
void Init(Handle<Object> exports) {
|
||||||
|
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());
|
exports->Set(NanNew("unmountSync"), NanNew<FunctionTemplate>(UnmountSync)->GetFunction());
|
||||||
|
5
index.js
5
index.js
@ -6,14 +6,17 @@ var noop = function () {}
|
|||||||
|
|
||||||
var FuseBuffer = function () {
|
var FuseBuffer = function () {
|
||||||
this.length = 0
|
this.length = 0
|
||||||
|
this.parent = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
FuseBuffer.prototype = Buffer.prototype
|
FuseBuffer.prototype = Buffer.prototype
|
||||||
|
|
||||||
|
fuse.setBuffer(FuseBuffer)
|
||||||
|
|
||||||
exports.mount = function (mnt, ops) {
|
exports.mount = function (mnt, ops) {
|
||||||
if (!ops) ops = {}
|
if (!ops) ops = {}
|
||||||
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 || [])
|
||||||
return fuse.mount(path.resolve(mnt), ops, new FuseBuffer())
|
return fuse.mount(path.resolve(mnt), ops)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.unmount = function (mnt, cb) {
|
exports.unmount = function (mnt, cb) {
|
||||||
|
Loading…
Reference in New Issue
Block a user