diff --git a/README.md b/README.md index 8749333..6a9353b 100644 --- a/README.md +++ b/README.md @@ -199,21 +199,30 @@ Called when the mode of a path is being changed Called when the a new device file is being made. -#### `ops.setxattr(path, name, buffer, length, offset, flags, cb)` +#### `ops.setxattr(path, name, value, position, flags, cb)` Called when extended attributes is being set (see the extended docs for your platform). -Currently you can read the attribute value being set in `buffer` at `offset`. -#### `ops.getxattr(path, name, buffer, length, offset, cb)` +Copy the `value` buffer somewhere to store it. + +The position argument is mostly a legacy argument only used on MacOS but see the getxattr docs +on Mac for more on that (you probably don't need to use that). + +#### `ops.getxattr(path, name, position, cb)` Called when extended attributes is being read. -Currently you have to write the result to the provided `buffer` at `offset`. -#### `ops.listxattr(path, buffer, length, cb)` +Return the extended attribute as the second argument to the callback (needs to be a buffer). +If no attribute is stored return `null` as the second argument. + +The position argument is mostly a legacy argument only used on MacOS but see the getxattr docs +on Mac for more on that (you probably don't need to use that). + +#### `ops.listxattr(path, cb)` Called when extended attributes of a path are being listed. -`buffer` should be filled with the extended attribute names as *null-terminated* strings, one after the other, up to a total of `length` in length. (`ERANGE` should be passed to the callback if `length` is insufficient.) -The size of buffer required to hold all the names should be passed to the callback either on success, or if the supplied `length` was zero. + +Return a list of strings of the names of the attributes you have stored as the second argument to the callback. #### `ops.removexattr(path, name, cb)` diff --git a/fuse-native.c b/fuse-native.c index fbbbafa..37c53aa 100644 --- a/fuse-native.c +++ b/fuse-native.c @@ -212,17 +212,17 @@ static void populate_stat (uint32_t *ints, struct stat* stat) { } static void populate_statvfs (uint32_t *ints, struct statvfs* statvfs) { - statvfs->f_bsize = *ints++; - statvfs->f_frsize = *ints++; - statvfs->f_blocks = *ints++; - statvfs->f_bfree = *ints++; - statvfs->f_bavail = *ints++; - statvfs->f_files = *ints++; - statvfs->f_ffree = *ints++; - statvfs->f_favail = *ints++; - statvfs->f_fsid = *ints++; - statvfs->f_flag = *ints++; - statvfs->f_namemax = *ints++; + statvfs->f_bsize = *ints++; + statvfs->f_frsize = *ints++; + statvfs->f_blocks = *ints++; + statvfs->f_bfree = *ints++; + statvfs->f_bavail = *ints++; + statvfs->f_files = *ints++; + statvfs->f_ffree = *ints++; + statvfs->f_favail = *ints++; + statvfs->f_fsid = *ints++; + statvfs->f_flag = *ints++; + statvfs->f_namemax = *ints++; } // Methods @@ -434,7 +434,7 @@ FUSE_METHOD(readdir, 1, 2, (const char *path, void *buf, fuse_fill_dir_t filler, #ifdef __APPLE__ -FUSE_METHOD_VOID(setxattr, 6, 0, (const char *path, const char *name, const char *value, size_t size, int flags, uint32_t position), { +FUSE_METHOD_VOID(setxattr, 5, 0, (const char *path, const char *name, const char *value, size_t size, int flags, uint32_t position), { l->path = path; l->name = name; l->value = value; @@ -444,13 +444,12 @@ FUSE_METHOD_VOID(setxattr, 6, 0, (const char *path, const char *name, const char }, { napi_create_string_utf8(env, l->path, NAPI_AUTO_LENGTH, &(argv[2])); napi_create_string_utf8(env, l->name, NAPI_AUTO_LENGTH, &(argv[3])); - napi_create_string_utf8(env, l->value, NAPI_AUTO_LENGTH, &(argv[4])); - napi_create_uint32(env, l->size, &(argv[5])); + napi_create_external_buffer(env, l->size, (char *) l->value, &fin, NULL, &(argv[4])); + napi_create_uint32(env, l->position, &(argv[5])); napi_create_uint32(env, l->flags, &(argv[6])); - napi_create_uint32(env, l->position, &(argv[7])); }) -FUSE_METHOD_VOID(getxattr, 5, 0, (const char *path, const char *name, char *value, size_t size, uint32_t position), { +FUSE_METHOD_VOID(getxattr, 4, 0, (const char *path, const char *name, char *value, size_t size, uint32_t position), { l->path = path; l->name = name; l->value = value; @@ -459,9 +458,8 @@ FUSE_METHOD_VOID(getxattr, 5, 0, (const char *path, const char *name, char *valu }, { napi_create_string_utf8(env, l->path, NAPI_AUTO_LENGTH, &(argv[2])); napi_create_string_utf8(env, l->name, NAPI_AUTO_LENGTH, &(argv[3])); - napi_create_string_utf8(env, l->value, NAPI_AUTO_LENGTH, &(argv[4])); - napi_create_uint32(env, l->size, &(argv[5])); - napi_create_uint32(env, l->position, &(argv[6])); + napi_create_external_buffer(env, l->size, (char *) l->value, &fin, NULL, &(argv[4])); + napi_create_uint32(env, l->position, &(argv[5])); }) #else @@ -475,8 +473,8 @@ FUSE_METHOD_VOID(setxattr, 5, 0, (const char *path, const char *name, const char }, { napi_create_string_utf8(env, l->path, NAPI_AUTO_LENGTH, &(argv[2])); napi_create_string_utf8(env, l->name, NAPI_AUTO_LENGTH, &(argv[3])); - napi_create_string_utf8(env, l->value, NAPI_AUTO_LENGTH, &(argv[4])); - napi_create_uint32(env, l->size, &(argv[5])); + napi_create_external_buffer(env, l->size, (char *) l->value, &fin, NULL, &(argv[4])); + napi_create_uint32(env, 0, &(argv[5])); // normalize apis between mac and linux napi_create_uint32(env, l->flags, &(argv[6])); }) @@ -488,20 +486,19 @@ FUSE_METHOD_VOID(getxattr, 4, 0, (const char *path, const char *name, char *valu }, { napi_create_string_utf8(env, l->path, NAPI_AUTO_LENGTH, &(argv[2])); napi_create_string_utf8(env, l->name, NAPI_AUTO_LENGTH, &(argv[3])); - napi_create_string_utf8(env, l->value, NAPI_AUTO_LENGTH, &(argv[4])); - napi_create_uint32(env, l->size, &(argv[5])); + napi_create_external_buffer(env, l->size, (char *) l->value, &fin, NULL, &(argv[4])); + napi_create_uint32(env, 0, &(argv[5])); }) #endif -FUSE_METHOD_VOID(listxattr, 3, 0, (const char *path, char *list, size_t size), { +FUSE_METHOD_VOID(listxattr, 2, 0, (const char *path, char *list, size_t size), { l->path = path; l->list = list; l->size = size; }, { napi_create_string_utf8(env, l->path, NAPI_AUTO_LENGTH, &(argv[2])); napi_create_external_buffer(env, l->size, l->list, &fin, NULL, &(argv[3])); - napi_create_uint32(env, l->size, &(argv[4])); }) FUSE_METHOD_VOID(removexattr, 2, 0, (const char *path, const char *name), { diff --git a/index.js b/index.js index bb38356..5476d3c 100644 --- a/index.js +++ b/index.js @@ -396,20 +396,42 @@ class Fuse extends Nanoresource { }) } - _op_setxattr (signal, path, name, value, size, position, flags) { - this.ops.setxattr(path, name, value, size, position, flags, err => { + _op_setxattr (signal, path, name, value, position, flags) { + this.ops.setxattr(path, name, value, position, flags, err => { return signal(err) }) } - _op_getxattr (signal, path, name, value, size, position) { - this.ops.getxattr(path, name, value, size, position, err => { + _op_getxattr (signal, path, name, valueBuf, position) { + this.ops.getxattr(path, name, position, (err, value) => { + if (!err) { + if (!value) return signal(IS_OSX ? -93 : -61) + value.copy(valueBuf) + return signal(value.length) + } return signal(err) }) } - _op_listxattr (signal, path, list, size) { - this.ops.listxattr(path, list, size, err => { + _op_listxattr (signal, path, listBuf) { + this.ops.listxattr(path, (err, list) => { + if (list && !err) { + if (!listBuf.length) { + let size = 0 + for (const name of list) size += Buffer.byteLength(name) + 1 + size += 128 // fuse yells if we do not signal room for some mac stuff also + return signal(size) + } + + let ptr = 0 + for (const name of list) { + listBuf.write(name, ptr) + ptr += Buffer.byteLength(name) + listBuf[ptr++] = 0 + } + + return signal(ptr) + } return signal(err) }) }