aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac10
-rw-r--r--src/Makefile.am4
-rw-r--r--src/arena.c50
-rw-r--r--src/arena.h15
-rw-r--r--src/bindfs.c150
-rw-r--r--src/misc.c107
-rw-r--r--src/misc.h25
-rw-r--r--src/userinfo.c1
-rw-r--r--tests/internals/Makefile.am2
-rw-r--r--tests/internals/test_internals.c183
-rwxr-xr-xtests/test_bindfs.rb6
-rw-r--r--tests/utimens_nofollow.c5
-rw-r--r--vagrant/debian10/Vagrantfile2
-rw-r--r--vagrant/debian9/Vagrantfile2
-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[])
diff --git a/src/misc.c b/src/misc.c
index dafebed..25fb653 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -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;
diff --git a/src/misc.h b/src/misc.h
index 6bcf865..360ddd1 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -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