Skip to content

Commit

Permalink
Better command line parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
astrada committed Feb 11, 2024
1 parent c3e7661 commit 36f17d2
Showing 1 changed file with 74 additions and 28 deletions.
102 changes: 74 additions & 28 deletions lib/Fuse_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
#endif

#include <caml/callback.h>
#include <caml/mlvalues.h>

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand All @@ -40,54 +40,100 @@

char **insert_foreground_option(int argc, char **argv);
void free_fuse_argv(int n, char **fuse_argv);
void start_program(int argc, char **argv, char *mountpoint, int foreground);
void parse_fuse_args(int argc, char **argv, struct fuse_args *args);
bool is_fuse_arg(char *arg, char *prev);

/* https://v2.ocaml.org/releases/5.1/htmlman/intfc.html#ss:main-c */
int main(int argc, char **argv) {
int c;
int foreground = 0;
int res;
char **fuse_argv = argv;
struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
char *mountpoint;
int foreground;

opterr = 0;
while ((c = getopt(argc, argv, "f")) != -1) {
switch (c) {
case 'f':
foreground = 1;
break;
default:
break;
parse_fuse_args(argc, argv, &args);
if (fuse_parse_cmdline(&args, &mountpoint, NULL, &foreground) != -1) {
start_program(argc, argv, mountpoint, foreground);

fuse_opt_free_args(&args);
return 0;
}

fuse_opt_free_args(&args);
return 1;
}

void parse_fuse_args(int argc, char **argv, struct fuse_args *args) {
int i = 1;

fuse_opt_add_arg(args, argv[0]);
while (i < argc) {
if (is_fuse_arg(argv[i], argv[i - 1])) {
fuse_opt_add_arg(args, argv[i]);
}
++i;
}
}

/* https://github.com/libfuse/libfuse/blob/d04687923194d906fe5ad82dcd546c9807bf15b6/include/fuse_common.h#L246
*/
if (fuse_daemonize(foreground) == -1) {
perror("fuse_daemonize");
return 1;
bool is_fuse_arg(char *arg, char *prev) {
if (strcmp(arg, "--help") == 0) {
return true;
}
if (strcmp(arg, "--version") == 0) {
return true;
}
if (arg[0] == '-') {
switch (arg[1]) {
case 'o':
case 'h':
case 'V':
case 'd':
case 'f':
case 's':
return true;
}
} else {
if (prev != NULL && strcmp(prev, "-o") == 0) {
return true;
} else {
if (access(arg, F_OK) == 0) {
return true;
}
}
}
return false;
}

void start_program(int argc, char **argv, char *mountpoint, int foreground) {
char **fuse_argv = argv;

if (mountpoint != NULL) {
/* https://github.com/libfuse/libfuse/blob/d04687923194d906fe5ad82dcd546c9807bf15b6/include/fuse_common.h#L246
*/
if (fuse_daemonize(foreground) == -1) {
perror("fuse_daemonize");
exit(1);
}

if (foreground == 0) {
fuse_argv = insert_foreground_option(argc, argv);
if (!foreground) {
fuse_argv = insert_foreground_option(argc, argv);
}
}

caml_main(fuse_argv);

if (foreground == 0) {
if (fuse_argv != argv) {
free_fuse_argv(argc + 1, fuse_argv);
}

return 0;
}

char **insert_foreground_option(int argc, char **argv) {
char *mountpoint = argv[argc - 1];
char **new_argv = malloc((argc + 2) * sizeof(*new_argv));

for (int i = 0; i < argc - 1; ++i) {
new_argv[i] = strdup(argv[i]);
new_argv[0] = strdup(argv[0]);
new_argv[1] = strdup("-f");
for (int i = 1; i < argc; ++i) {
new_argv[i + 1] = strdup(argv[i]);
}
new_argv[argc - 1] = strdup("-f");
new_argv[argc] = strdup(mountpoint);
return new_argv;
}

Expand Down

0 comments on commit 36f17d2

Please sign in to comment.