diff options
author | Martin Pärtel <martin.partel@gmail.com> | 2021-02-13 15:56:57 +0200 |
---|---|---|
committer | Martin Pärtel <martin.partel@gmail.com> | 2021-02-13 15:56:57 +0200 |
commit | bc5313dc583cad9a3949bd798995ab1ee398ecf6 (patch) | |
tree | 3eef96d1b7cbb7a4e05a3ea954b1bc75231c1fd8 | |
parent | 2cf41a75c11472bd6737b48c61f0a3d30cd6f242 (diff) | |
download | bindfs-bc5313dc583cad9a3949bd798995ab1ee398ecf6.tar.gz |
Refactored and unit-tested filter_special_opts. Shaved a bunch of yaks on the way.
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/arena.c | 50 | ||||
-rw-r--r-- | src/arena.h | 15 | ||||
-rw-r--r-- | src/bindfs.c | 150 | ||||
-rw-r--r-- | src/misc.c | 107 | ||||
-rw-r--r-- | src/misc.h | 25 | ||||
-rw-r--r-- | src/userinfo.c | 1 | ||||
-rw-r--r-- | tests/internals/Makefile.am | 2 | ||||
-rw-r--r-- | tests/internals/test_internals.c | 183 | ||||
-rwxr-xr-x | tests/test_bindfs.rb | 6 | ||||
-rw-r--r-- | tests/utimens_nofollow.c | 5 | ||||
-rw-r--r-- | vagrant/debian10/Vagrantfile | 2 | ||||
-rw-r--r-- | vagrant/debian9/Vagrantfile | 2 | ||||
-rw-r--r-- | vagrant/freebsd12/Vagrantfile (renamed from vagrant/freebsd10_3/Vagrantfile) | 7 |
15 files changed, 413 insertions, 156 deletions
diff --git a/configure.ac b/configure.ac index d0d101a..0ecee3e 100644 --- a/configure.ac +++ b/configure.ac @@ -28,8 +28,14 @@ fi AM_CONDITIONAL(BUILD_OS_IS_DARWIN, [test x"$build_os" = darwin]) -my_CPPFLAGS="-D_REENTRANT -D_FILE_OFFSET_BITS=64" -my_CFLAGS="-Wall -fno-common" +# _XOPEN_SOURCE is >= 500 for pread/pwrite; >= 700 for utimensat. +# __BSD_VISIBLE is for flock() on FreeBSD. It otherwise gets hidden by _XOPEN_SOURCE. +# _BSD_SOURCE is for stat() nanosecond precision and lutimes(). +# _DEFAULT_SOURCE is the new non-deprecated version of _BSD_SOURCE. +# _DARWIN_BETTER_REALPATH fixes MacOS realpath() broken around Catalina (#83). +my_CPPFLAGS="-D_REENTRANT -D_FILE_OFFSET_BITS=64 -D_XOPEN_SOURCE=700 -D__BSD_VISIBLE=1 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_DARWIN_BETTER_REALPATH" + +my_CFLAGS="-Wall -fno-common -std=c99" my_LDFLAGS="-pthread" AC_SUBST([my_CPPFLAGS]) AC_SUBST([my_CFLAGS]) diff --git a/src/Makefile.am b/src/Makefile.am index 904943a..7e25193 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,8 +2,8 @@ bin_PROGRAMS = bindfs -noinst_HEADERS = debug.h permchain.h userinfo.h misc.h usermap.h rate_limiter.h -bindfs_SOURCES = bindfs.c debug.c permchain.c userinfo.c misc.c usermap.c rate_limiter.c +noinst_HEADERS = debug.h permchain.h userinfo.h arena.h misc.h usermap.h rate_limiter.h +bindfs_SOURCES = bindfs.c debug.c permchain.c userinfo.c arena.c misc.c usermap.c rate_limiter.c AM_CPPFLAGS = ${my_CPPFLAGS} ${fuse_CFLAGS} ${fuse3_CFLAGS} AM_CFLAGS = ${my_CFLAGS} diff --git a/src/arena.c b/src/arena.c new file mode 100644 index 0000000..2221616 --- /dev/null +++ b/src/arena.c @@ -0,0 +1,50 @@ +#include "arena.h" + +struct block { + size_t size; + size_t used; + struct block *next; + char data_start[]; +}; + +static const size_t min_block_room = 16 * 1024 - sizeof(struct block); + +static void add_block(struct arena* a, size_t room_wanted) +{ + if (room_wanted < min_block_room) { + room_wanted = min_block_room; + } + struct block *new_block = malloc(sizeof(struct block) + room_wanted); + new_block->size = room_wanted; + new_block->used = 0; + new_block->next = a->cur_block; + a->cur_block = new_block; +} + +void arena_init(struct arena *a) +{ + a->cur_block = NULL; +} + +void* arena_malloc(struct arena *a, size_t amount) +{ + struct block* b = a->cur_block; + if (b == NULL || b->size - b->used < amount) { + add_block(a, amount); + b = a->cur_block; + } + void* result = &b->data_start[b->used]; + b->used += amount; + return result; +} + +void arena_free(struct arena *a) +{ + struct block* b = a->cur_block; + while (b != NULL) { + struct block* next = b->next; + free(b); + b = next; + } + a->cur_block = NULL; +} diff --git a/src/arena.h b/src/arena.h new file mode 100644 index 0000000..f862dbf --- /dev/null +++ b/src/arena.h @@ -0,0 +1,15 @@ +#ifndef INC_BINDFS_ARENA_H +#define INC_BINDFS_ARENA_H + +#include <stdlib.h> + +struct block; +struct arena { + struct block *cur_block; +}; + +void arena_init(struct arena *a); +void* arena_malloc(struct arena *a, size_t amount); +void arena_free(struct arena *a); + +#endif diff --git a/src/bindfs.c b/src/bindfs.c index 57d0a8e..96f909b 100644 --- a/src/bindfs.c +++ b/src/bindfs.c @@ -31,20 +31,6 @@ #include <config.h> -/* For >= 500 for pread/pwrite; >= 700 for utimensat */ -#define _XOPEN_SOURCE 700 - -/* For flock() on FreeBSD. It otherwise gets hidden by _XOPEN_SOURCE */ -#define __BSD_VISIBLE 1 - -/* For stat() nanosecond precision and lutimes() */ -#define _BSD_SOURCE -/* The new non-deprecated version of _BSD_SOURCE */ -#define _DEFAULT_SOURCE - -/* Fix MacOS realpath() broken around Catalina (#83) */ -#define _DARWIN_BETTER_REALPATH - #include <stdlib.h> #include <stddef.h> #include <stdio.h> @@ -97,6 +83,7 @@ #include <fuse.h> #include <fuse_opt.h> +#include "arena.h" #include "debug.h" #include "misc.h" #include "permchain.h" @@ -367,6 +354,7 @@ Why? Because some of those options like "nofail" are special ones interpreted by systemd in /etc/fstab */ struct fuse_args filter_special_opts(struct fuse_args *args); +static bool keep_option(const char* opt); static int is_mirroring_enabled() { @@ -2085,8 +2073,8 @@ static int parse_map_file(UserMap *map, UserMap *reverse_map, char *file, int as UsermapStatus status; // Toggle between UID (passwd) and GID (group) - const int (*value_to_id)(const char *username, uid_t *ret); - const UsermapStatus (*usermap_add)(UserMap *map, uid_t from, uid_t to); + int (*value_to_id)(const char *username, uid_t *ret); + UsermapStatus (*usermap_add)(UserMap *map, uid_t from, uid_t to); const char *label_name, *label_id; if (as_gid) { value_to_id = &group_gid; @@ -2336,11 +2324,27 @@ static void atexit_func() struct fuse_args filter_special_opts(struct fuse_args *args) { - bool ignore; + struct arena arena; + arena_init(&arena); + int tmp_argc = args->argc; + char **tmp_argv; + + filter_o_opts(&keep_option, args->argc, (const char * const *)args->argv, &tmp_argc, &tmp_argv, &arena); + struct fuse_args new_args = FUSE_ARGS_INIT(0, (void*)0); + for (int i = 0; i < tmp_argc; i++) { + fuse_opt_add_arg(&new_args, tmp_argv[i]); + } + + arena_free(&arena); + fuse_opt_free_args(args); + return new_args; +} +static bool keep_option(const char* opt) +{ // Copied from "libfuse/util/mount.fuse.c" (fuse-3.10.1) - const char *ignore_opts[] = { + static const char * const ignored_opts[] = { "", "user", "nofail", @@ -2352,114 +2356,12 @@ struct fuse_args filter_special_opts(struct fuse_args *args) NULL }; - for (int i = 0; i < args->argc; i++) { - ignore = false; - - /* If current element is exactly "-o" modify/check the following element */ - if (strcmp(args->argv[i], "-o") == 0 && (i+1) < args->argc) { - - /* remove ignored option from a comma separated list */ - if (strchr(args->argv[i+1], ',') != NULL) { - char *tmpStr = (char*) calloc(strlen(args->argv[i+1]) + 1, sizeof(char)); - char *ptr = strtok(args->argv[i+1], ","); - while (ptr != NULL) { - ignore = false; - for (int j = 0; ignore_opts[j]; j++) { - if (strcmp(ptr, ignore_opts[j]) == 0) { - ignore = true; - break; - } - } - if (!ignore) { - if (strlen(tmpStr) > 0) strcat(tmpStr, ","); - strcat(tmpStr, ptr); - } - ptr = strtok(NULL, ","); - } - if (strlen(tmpStr) > 0) { - args->argv[i+1] = (char*) calloc(strlen(tmpStr) + 1, sizeof(char)); - strcpy(args->argv[i+1], tmpStr); - free(tmpStr); - ignore = false; - } - else { - ignore = true; - ++i; - } - } - - /* ignore this and the following element if it has exactly the ignored option */ - else { - for (int j = 0; ignore_opts[j]; j++) { - if (strcmp(args->argv[i+1], ignore_opts[j]) == 0) { - ignore = true; - ++i; - break; - } - } - } - } - - /* else if element starts with "-o" */ - else if (strncmp(args->argv[i], "-o", 2) == 0) { - - /* remove ignored option from a comma seperated list */ - if (strchr(args->argv[i], ',') != NULL) { - char *tmpStr = (char*) calloc(strlen(args->argv[i]) + 1, sizeof(char)); - char *tmpStr2 = (char*) calloc(strlen(args->argv[i]) + 1 - 2, sizeof(char)); - // remove first 2 chars from args->argv[i] and save this to tmpStr2 - memcpy(tmpStr2, args->argv[i] + 2, strlen(args->argv[i]) - 2); - char *ptr = strtok(tmpStr2, ","); - while (ptr != NULL) { - ignore = false; - for (int j = 0; ignore_opts[j]; j++) { - if (strcmp(ptr, ignore_opts[j]) == 0) { - ignore = true; - break; - } - } - if (!ignore) { - if (strlen(tmpStr) > 0) strcat(tmpStr, ","); - strcat(tmpStr, ptr); - } - ptr = strtok(NULL, ","); - } - if (strlen(tmpStr) > 0) { - args->argv[i] = (char*) calloc(2 + strlen(tmpStr) + 1, sizeof(char)); - strcat(args->argv[i], "-o"); - strcat(args->argv[i], tmpStr); - free(tmpStr); - free(tmpStr2); - ignore = false; - } - else { - ignore = true; - } - } - - /* ignore this element if it has exactly the ignored option */ - else { - for (int j = 0; ignore_opts[j]; j++) { - char* tmpStr = (char*) calloc(2 + strlen(ignore_opts[j]) + 1, sizeof(char)); - strcat(tmpStr, "-o"); - strcat(tmpStr, ignore_opts[j]); - if (strcmp(args->argv[i], tmpStr) == 0) { - ignore = true; - free(tmpStr); - break; - } - free(tmpStr); - } - } - } - if (!ignore) { - fuse_opt_add_arg(&new_args, strdup(args->argv[i])); + for (int i = 0; ignored_opts[i] != NULL; ++i) { + if (strcmp(ignored_opts[i], opt) == 0) { + return false; } } - - fuse_opt_free_args(args); - - return new_args; + return true; } int main(int argc, char *argv[]) @@ -135,6 +135,102 @@ const char *my_dirname(char *path) } } +static char **dup_argv(int argc, const char * const *argv, struct arena *arena) +{ + char **pointer_list = arena_malloc(arena, (argc + 1) * sizeof(char*)); + char **next_ptr = pointer_list; + + for (int i = 0; i < argc; ++i) { + int len = strlen(argv[i]); + char *str = arena_malloc(arena, len + 1); + memcpy(str, argv[i], len + 1); + *next_ptr = str; + ++next_ptr; + } + *next_ptr = NULL; + + return pointer_list; +} + +/* Converts all ("-o", "...") into ("-o..."). */ +static void merge_o_args( + int *argc, + char **argv, + struct arena *arena +) +{ + int i = 0; + while (i < *argc) { + char *arg = argv[i]; + if (strcmp(arg, "-o") == 0) { + if (i + 1 < *argc) { + char *merged = arena_malloc(arena, 2 + strlen(argv[i + 1]) + 1); + merged[0] = '-'; + merged[1] = 'o'; + strcpy(&merged[2], argv[i + 1]); + argv[i] = merged; + + for (int j = i + 1; j < *argc - 1; ++j) { + argv[j] = argv[j + 1]; + } + } + --*argc; + } + ++i; + } +} + +void filter_o_opts( + bool (*keep)(const char* opt), + int orig_argc, + const char * const *orig_argv, + int *new_argc, + char ***new_argv, + struct arena* arena +) +{ + int argc = orig_argc; + char **argv = dup_argv(argc, orig_argv, arena); + + merge_o_args(&argc, argv, arena); + + for (int i = 0; i < argc; i++) { + char *arg = argv[i]; + if (strncmp(arg, "-o", 2) == 0) { + char *filtered = arena_malloc(arena, strlen(arg) + 1); + char *filtered_end = filtered; + + const char *tok = strtok(arg + 2, ","); + while (tok != NULL) { + size_t tok_len = strlen(tok); + if ((*keep)(tok)) { + if (filtered_end == filtered) { + *(filtered_end++) = '-'; + *(filtered_end++) = 'o'; + } else { + *(filtered_end++) = ','; + } + memcpy(filtered_end, tok, tok_len + 1); + filtered_end += tok_len; // We'll overwrite the null terminator if we append more. + } + tok = strtok(NULL, ","); + } + + if (filtered != filtered_end) { + argv[i] = filtered; + } else { + for (int j = i; j < argc - 1; ++j) { + argv[j] = argv[j + 1]; + } + --argc; + } + } + } + + *new_argc = argc; + *new_argv = argv; +} + void grow_array_impl(void **array, int *capacity, int member_size) { int new_cap = *capacity; @@ -170,7 +266,8 @@ int parse_byte_count(const char *str, double *result) return 1; } -void init_memory_block(struct memory_block *a, int initial_capacity) + +void init_memory_block(struct memory_block *a, size_t initial_capacity) { a->size = 0; a->capacity = initial_capacity; @@ -181,9 +278,9 @@ void init_memory_block(struct memory_block *a, int initial_capacity) } } -void grow_memory_block(struct memory_block *a, int amount) +void grow_memory_block(struct memory_block *a, size_t amount) { - int new_cap; + size_t new_cap; a->size += amount; if (a->size >= a->capacity) { @@ -204,9 +301,9 @@ void grow_memory_block(struct memory_block *a, int amount) } } -int append_to_memory_block(struct memory_block *a, void *src, int src_size) +int append_to_memory_block(struct memory_block *a, const void *src, size_t src_size) { - int dest = a->size; + size_t dest = a->size; grow_memory_block(a, src_size); memcpy(&a->ptr[dest], src, src_size); return dest; @@ -20,6 +20,10 @@ #ifndef INC_BINDFS_MISC_H #define INC_BINDFS_MISC_H +#include <stdbool.h> +#include <stdlib.h> + +#include "arena.h" /* Counts the number of times ch occurs in s. */ int count_chars(const char *s, char ch); @@ -49,6 +53,17 @@ const char *my_basename(const char *path); Otherwise, returns ".". */ const char *my_dirname(char *path); +/* Filters arguments in comma-separated lists prefixed by '-o'. + * Allocates 'new_argv' and its strings, as well as some temporary data, into 'arena'. */ +void filter_o_opts( + bool (*keep)(const char* opt), + int argc, + const char * const *argv, + int *new_argc, + char ***new_argv, + struct arena *arena +); + /* Reallocs `*array` (may be NULL) to be at least one larger than `*capacity` (may be 0) and stores the new capacity in `*capacity`. */ @@ -62,15 +77,15 @@ int parse_byte_count(const char *str, double *result); growing it and appending to it. */ struct memory_block { char *ptr; - int size; - int capacity; + size_t size; + size_t capacity; }; #define MEMORY_BLOCK_INITIALIZER { NULL, 0, 0 } -void init_memory_block(struct memory_block *a, int initial_capacity); -void grow_memory_block(struct memory_block *a, int amount); -int append_to_memory_block(struct memory_block *a, void *src, int src_size); +void init_memory_block(struct memory_block *a, size_t initial_capacity); +void grow_memory_block(struct memory_block *a, size_t amount); +int append_to_memory_block(struct memory_block *a, const void *src, size_t src_size); void free_memory_block(struct memory_block *a); #define MEMORY_BLOCK_GET(a, offset) (&(a).ptr[(offset)]) diff --git a/src/userinfo.c b/src/userinfo.c index 3adadea..2a72bf3 100644 --- a/src/userinfo.c +++ b/src/userinfo.c @@ -20,6 +20,7 @@ #include "userinfo.h" #include "misc.h" #include "debug.h" + #include <stdlib.h> #include <string.h> #include <errno.h> diff --git a/tests/internals/Makefile.am b/tests/internals/Makefile.am index 3e59f02..f0b86e6 100644 --- a/tests/internals/Makefile.am +++ b/tests/internals/Makefile.am @@ -1,7 +1,7 @@ noinst_HEADERS = test_common.h noinst_PROGRAMS = test_internals test_rate_limiter -test_internals_SOURCES = test_internals.c test_common.c $(top_srcdir)/src/misc.c +test_internals_SOURCES = test_internals.c test_common.c $(top_srcdir)/src/misc.c $(top_srcdir)/src/arena.c test_rate_limiter_SOURCES = test_rate_limiter.c test_common.c $(top_srcdir)/src/rate_limiter.c test_internals_CPPFLAGS = ${my_CPPFLAGS} ${fuse_CFLAGS} ${fuse3_CFLAGS} -I. -I$(top_srcdir)/src diff --git a/tests/internals/test_internals.c b/tests/internals/test_internals.c index f5dbed5..a16b392 100644 --- a/tests/internals/test_internals.c +++ b/tests/internals/test_internals.c @@ -1,10 +1,40 @@ +#define _XOPEN_SOURCE 700 + #include "test_common.h" #include "misc.h" #include <string.h> #include <stdlib.h> -void test_my_dirname(char *arg, const char *expected) +static void arena_suite() +{ + const int iterations = 1000; + struct arena arena; + int** pointers = calloc(iterations, sizeof(int*)); + + arena_init(&arena); + for (int i = 0; i < iterations; ++i) { + int count = 17 * i; + int* p = arena_malloc(&arena, count * sizeof(int)); + pointers[i] = p; + for (int j = 0; j < count; ++j) { + p[j] = j; + } + } + + for (int i = 0; i < iterations; ++i) { + int count = 17 * i; + int* p = pointers[i]; + for (int j = 0; j < count; ++j) { + TEST_ASSERT(p[j] == j); + } + } + + arena_free(&arena); + free(pointers); +} + +static void test_my_dirname(char *arg, const char *expected) { char *orig = strdup(arg); @@ -17,7 +47,7 @@ void test_my_dirname(char *arg, const char *expected) free(orig); } -void my_dirname_suite() +static void my_dirname_suite() { char buf[256]; @@ -52,7 +82,7 @@ void my_dirname_suite() test_my_dirname(buf, ".."); } -void sprintf_new_suite() { +static void sprintf_new_suite() { char *result; result = sprintf_new("Hello %d %s", 123, "World"); @@ -64,9 +94,154 @@ void sprintf_new_suite() { free(result); } -void test_internal_suite() { +static int arg_count(const char **argv) +{ + int i = 0; + while (argv[i] != NULL) { + ++i; + } + return i; +} + +static bool keep_opt(const char *opt) { + return *opt != '\0' && strncmp(opt, "bad", 3) != 0; +} + +static char *join_args(int argc, const char** argv) { + struct memory_block block = MEMORY_BLOCK_INITIALIZER; + for (int i = 0; i < argc; ++i) { + int len = strlen(argv[i]); + append_to_memory_block(&block, argv[i], len); + if (i + 1 < argc) { + append_to_memory_block(&block, " ", 1); + } else { + append_to_memory_block(&block, "\0", 1); + } + } + return block.ptr; +} + +static void filter_o_opts_test(const char **init, const char **expected) { + int argc = arg_count(init); + char *joined_input = join_args(argc, init); + + struct arena arena; + arena_init(&arena); + char **argv; + filter_o_opts(keep_opt, argc, init, &argc, &argv, &arena); + + for (int i = 0; i < argc; ++i) { + if (argv[i] == NULL) { + printf("Expected %s but got end of argv at index %d with input %s\n", expected[i], i, joined_input); + failures++; + break; + } + if (expected[i] == NULL) { + printf("Expected end of args but got %s at index %d with input %s\n", argv[i], i, joined_input); + failures++; + break; + } + if (strcmp(argv[i], expected[i]) != 0) { + printf("Expected %s but got %s at index %d with input %s\n", expected[i], argv[i], i, joined_input); + failures++; + break; + } + } + + arena_free(&arena); + free(joined_input); +} + +static void filter_o_opts_suite() { + { + const char *in[] = {"-obad1", NULL}; + const char *exp[] = {NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-ogood1", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + { + const char *in[] = {"-obad1,good1", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-ogood1,bad", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-obad1,good1,bad2", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-obad1,good1,bad2,good2", NULL}; + const char *exp[] = {"-ogood1,good2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-ogood1,bad1,good2", NULL}; + const char *exp[] = {"-ogood1,good2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "bad1", NULL}; + const char *exp[] = {NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "good1", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "good1,bad1,good2", NULL}; + const char *exp[] = {"-ogood1,good2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "bad1,good1,bad2", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"unrelated1", "-o", "bad1,good1,bad2", "unrelated2", NULL}; + const char *exp[] = {"unrelated1", "-ogood1", "unrelated2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"unrelated1", "-o", ",,,bad1,,good1,,bad2,,,", "unrelated2", NULL}; + const char *exp[] = {"unrelated1", "-ogood1", "unrelated2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", NULL}; + const char *exp[] = {NULL}; + filter_o_opts_test(in, exp); + } +} + +static void test_internal_suite() { + arena_suite(); my_dirname_suite(); sprintf_new_suite(); + filter_o_opts_suite(); } TEST_MAIN(test_internal_suite); diff --git a/tests/test_bindfs.rb b/tests/test_bindfs.rb index 49f2332..29210b7 100755 --- a/tests/test_bindfs.rb +++ b/tests/test_bindfs.rb @@ -296,7 +296,9 @@ testenv("--chmod-deny --chmod-allow-x") do assert_exception(EPERM) { chmod(0777, 'mnt/file') } assert_exception(EPERM) { chmod(0000, 'mnt/file') } - assert_exception(EPERM) { chmod(01700, 'mnt/file') } # sticky bit + if `uname`.strip != 'FreeBSD' # FreeBSD doesn't let us set the sticky bit on files + assert_exception(EPERM) { chmod(01700, 'mnt/file') } # sticky bit + end chmod(0611, 'mnt/file') # chmod that only changes x-bits should work assert { File.stat('src/file').mode & 07777 == 00611 } @@ -895,7 +897,7 @@ if `uname`.strip != 'FreeBSD' # -o dev is not supported on FreeBSD end # PR #95 -testenv("-ouser -onofail,nouser,delete-deny -o users -o auto,rename-deny,noauto -o chmod-deny,_netdev", :title => "filtering special options") do +testenv("-ouser -onofail,nouser,,,delete-deny -o users -o auto,rename-deny,noauto -o chmod-deny,_netdev,,", :title => "filtering special options") do touch('src/file') assert_exception(EPERM) { rm('mnt/file') } assert_exception(EPERM) { File.rename('mnt/file', 'mnt/file2') } diff --git a/tests/utimens_nofollow.c b/tests/utimens_nofollow.c index 1941c56..668cec4 100644 --- a/tests/utimens_nofollow.c +++ b/tests/utimens_nofollow.c @@ -1,9 +1,4 @@ -/* For atoll and lutimes */ -#define _BSD_SOURCE -/* The new non-deprecated version of _BSD_SOURCE */ -#define _DEFAULT_SOURCE - #include <config.h> #include <stdlib.h> #include <stdio.h> diff --git a/vagrant/debian10/Vagrantfile b/vagrant/debian10/Vagrantfile index 3a76651..d56a8f2 100644 --- a/vagrant/debian10/Vagrantfile +++ b/vagrant/debian10/Vagrantfile @@ -16,8 +16,8 @@ Vagrant.configure("2") do |config| end config.vm.provision "shell", reboot: true, inline: <<-SHELL + export DEBIAN_FRONTEND='noninteractive' apt-get update - DEBIAN_FRONTEND='noninteractive' apt-get dist-upgrade -y -o Dpkg::Options::="--force-confdef" apt-get install -y fuse3 libfuse3-dev build-essential pkg-config ruby valgrind apt-get clean echo user_allow_other > /etc/fuse.conf diff --git a/vagrant/debian9/Vagrantfile b/vagrant/debian9/Vagrantfile index 7f681dc..3ba1138 100644 --- a/vagrant/debian9/Vagrantfile +++ b/vagrant/debian9/Vagrantfile @@ -16,8 +16,8 @@ Vagrant.configure("2") do |config| end config.vm.provision "shell", reboot: true, inline: <<-SHELL + export DEBIAN_FRONTEND='noninteractive' apt-get update - DEBIAN_FRONTEND='noninteractive' apt-get dist-upgrade -y -o Dpkg::Options::="--force-confdef" apt-get install -y fuse libfuse-dev build-essential pkg-config ruby valgrind apt-get clean echo user_allow_other > /etc/fuse.conf diff --git a/vagrant/freebsd10_3/Vagrantfile b/vagrant/freebsd12/Vagrantfile index 87ba424..213c18c 100644 --- a/vagrant/freebsd10_3/Vagrantfile +++ b/vagrant/freebsd12/Vagrantfile @@ -2,8 +2,7 @@ # vi: set ft=ruby : Vagrant.configure("2") do |config| - #config.vm.box = "freebsd/FreeBSD-11.0-STABLE" # doesn't set base_mac so can't use NAT networking :( - config.vm.box = "bento/freebsd-10.3" + config.vm.box = "roboxes/freebsd12" config.vm.synced_folder ".", "/vagrant", disabled: true config.vm.synced_folder "../../", "/bindfs", @@ -13,12 +12,12 @@ Vagrant.configure("2") do |config| rsync__args: ["-av", "--delete-after"] config.vm.provider "virtualbox" do |v| - v.name = "bindfs-freebsd10_3" + v.name = "bindfs-freebsd12" end config.vm.provision "shell", inline: <<-SHELL pkg update - pkg install -y fusefs-libs pkgconf ruby valgrind + pkg install -y fusefs-libs pkgconf ruby kldload fuse.ko echo 'fuse_load="YES"' >> /boot/loader.conf |