diff --git a/CMakeLists.txt b/CMakeLists.txt index f2c0b62..d54cd64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,4 +25,5 @@ target_link_libraries(mediafire-fuse curl ssl fuse jansson mfapi mfutils) add_test(iwyu ${CMAKE_SOURCE_DIR}/tests/iwyu.py ${CMAKE_BINARY_DIR}) add_test(indent ${CMAKE_SOURCE_DIR}/tests/indent.sh ${CMAKE_SOURCE_DIR}) -add_test(valgrind ${CMAKE_SOURCE_DIR}/tests/valgrind.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) +add_test(valgrind_fuse ${CMAKE_SOURCE_DIR}/tests/valgrind_fuse.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) +add_test(valgrind_shell ${CMAKE_SOURCE_DIR}/tests/valgrind_shell.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}) diff --git a/fuse/main.c b/fuse/main.c index 628e16c..ea6fc6f 100644 --- a/fuse/main.c +++ b/fuse/main.c @@ -160,6 +160,8 @@ static void mediafirefs_destroy() fclose(fd); folder_tree_destroy(tree); + + mfconn_destroy(conn); } static int mediafirefs_mkdir(const char *path, mode_t mode) @@ -421,7 +423,7 @@ static void parse_config(int *argc, char ***argv, char *configfile) static void parse_arguments(int *argc, char ***argv, struct mediafirefs_user_options *options) { - char **argv_new; + int i; /* In the first pass, we only search for the help, version and config file * options. @@ -445,11 +447,6 @@ static void parse_arguments(int *argc, char ***argv, FUSE_OPT_END }; - // copy argv into a new area so that we can realloc later - argv_new = malloc(sizeof(char *) * (*argc)); - memcpy(argv_new, *argv, sizeof(char *) * (*argc)); - *argv = argv_new; - struct fuse_args args_fst = FUSE_ARGS_INIT(*argc, *argv); if (fuse_opt_parse @@ -457,6 +454,7 @@ static void parse_arguments(int *argc, char ***argv, mediafirefs_opt_proc) == -1) { exit(1); } + *argc = args_fst.argc; *argv = args_fst.argv; @@ -488,6 +486,13 @@ static void parse_arguments(int *argc, char ***argv, exit(1); } + if (*argv != args_snd.argv) { + for (i = 0; i < *argc; i++) { + free((*argv)[i]); + } + free(*argv); + } + *argc = args_snd.argc; *argv = args_snd.argv; } @@ -543,6 +548,9 @@ static void connect_mf(struct mediafirefs_user_options *options) int main(int argc, char *argv[]) { + int ret, + i; + struct mediafirefs_user_options options = { NULL, NULL, NULL, NULL, -1, NULL }; @@ -551,5 +559,12 @@ int main(int argc, char *argv[]) connect_mf(&options); - return fuse_main(argc, argv, &mediafirefs_oper, NULL); + ret = fuse_main(argc, argv, &mediafirefs_oper, NULL); + + for (i = 0; i < argc; i++) { + free(argv[i]); + } + free(argv); + + return ret; } diff --git a/tests/valgrind_fuse.sh b/tests/valgrind_fuse.sh new file mode 100755 index 0000000..fa055fc --- /dev/null +++ b/tests/valgrind_fuse.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +set -ex + +case $# in + 0) + source_dir="." + binary_dir="." + ;; + 2) + source_dir=$1 + binary_dir=$2 + ;; + *) + echo "usage: $0 [source_dir] [binary_dir]" + exit 1 + ;; +esac + +cmd="valgrind --suppressions="${source_dir}/valgrind.supp" --fullpath-after="$source_dir" --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --track-origins=yes --error-exitcode=1 --quiet" + +if [ ! -f "./.mediafire-tools.conf" -a ! -f "~/.mediafire-tools.conf" ]; then + echo "no configuration file found" >&2 + exit 1 +fi + +if [ `mount -t fuse.mediafire-fuse | wc -l` -ne 0 ]; then + echo "a fuse fs is already mounted" >&2 + exit 1 +fi + +$cmd "${binary_dir}/mediafire-fuse" -s -f -d /mnt & +fusepid="$!" + +# once the file system is found to be mounted, print the tree and unmount +while sleep 1; do + if [ `mount -t fuse.mediafire-fuse | wc -l` -ne 0 ]; then + break; + fi +done + +tree /mnt + +fusermount -u /mnt + +wait "$fusepid" diff --git a/tests/valgrind.sh b/tests/valgrind_shell.sh similarity index 98% rename from tests/valgrind.sh rename to tests/valgrind_shell.sh index 7735e90..04715a1 100755 --- a/tests/valgrind.sh +++ b/tests/valgrind_shell.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e + case $# in 0) source_dir="." diff --git a/valgrind.supp b/valgrind.supp index d2fccd6..dc8f4ef 100644 --- a/valgrind.supp +++ b/valgrind.supp @@ -113,3 +113,15 @@ obj:*/libjansson.so* ... } +{ + fuse_opt_parse + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:strdup + obj:*libfuse.so* + obj:*libfuse.so* + fun:fuse_opt_parse + fun:parse_arguments + fun:main +}