summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-04-11 18:56:47 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-04-11 18:56:47 +0200
commit7cac6770e0b380d6e5f37b9fad71c9f7f15952ba (patch)
tree8d2c695f27361aa8b3b6d91038f4c78182f64a16
parenta45a313422efa33f261cb1b53a08646a6b3ab947 (diff)
downloadfastd-7cac6770e0b380d6e5f37b9fad71c9f7f15952ba.tar
fastd-7cac6770e0b380d6e5f37b9fad71c9f7f15952ba.zip
Add support for async commands
-rw-r--r--src/config.y44
-rw-r--r--src/lex.c2
-rw-r--r--src/options.c14
-rw-r--r--src/peer.c5
-rw-r--r--src/shell.c37
-rw-r--r--src/shell.h4
6 files changed, 72 insertions, 34 deletions
diff --git a/src/config.y b/src/config.y
index 70ee4a2..2bdd5d3 100644
--- a/src/config.y
+++ b/src/config.y
@@ -69,6 +69,7 @@
%token TOK_ADDRESSES
%token TOK_ANY
%token TOK_AS
+%token TOK_ASYNC
%token TOK_AUTO
%token TOK_BIND
%token TOK_CAPABILITIES
@@ -118,6 +119,7 @@
%token TOK_SECRET
%token TOK_SECURE
%token TOK_STDERR
+%token TOK_SYNC
%token TOK_SYSLOG
%token TOK_TAP
%token TOK_TO
@@ -155,6 +157,9 @@
%type <uint64> bind_default
%type <uint64> drop_capabilities_enabled
%type <tristate> autobool
+%type <boolean> sync
+%type <boolean> sync_def_sync
+%type <boolean> sync_def_async
%%
start: START_CONFIG config
@@ -373,38 +378,38 @@ method: TOK_STRING {
secret: TOK_STRING { free(conf->secret); conf->secret = strdup($1->str); }
;
-on_pre_up: TOK_STRING {
- fastd_shell_command_set(&conf->on_pre_up, $1->str);
+on_pre_up: sync_def_sync TOK_STRING {
+ fastd_shell_command_set(&conf->on_pre_up, $2->str, $1);
}
;
-on_up: TOK_STRING {
- fastd_shell_command_set(&conf->on_up, $1->str);
+on_up: sync_def_sync TOK_STRING {
+ fastd_shell_command_set(&conf->on_up, $2->str, $1);
}
;
-on_down: TOK_STRING {
- fastd_shell_command_set(&conf->on_down, $1->str);
+on_down: sync_def_sync TOK_STRING {
+ fastd_shell_command_set(&conf->on_down, $2->str, $1);
}
;
-on_post_down: TOK_STRING {
- fastd_shell_command_set(&conf->on_post_down, $1->str);
+on_post_down: sync_def_sync TOK_STRING {
+ fastd_shell_command_set(&conf->on_post_down, $2->str, $1);
}
;
-on_establish: TOK_STRING {
- fastd_shell_command_set(&conf->on_establish, $1->str);
+on_establish: sync_def_async TOK_STRING {
+ fastd_shell_command_set(&conf->on_establish, $2->str, $1);
}
;
-on_disestablish: TOK_STRING {
- fastd_shell_command_set(&conf->on_disestablish, $1->str);
+on_disestablish: sync_def_async TOK_STRING {
+ fastd_shell_command_set(&conf->on_disestablish, $2->str, $1);
}
;
-on_verify: TOK_STRING {
- fastd_shell_command_set(&conf->on_verify, $1->str);
+on_verify: sync_def_async TOK_STRING {
+ fastd_shell_command_set(&conf->on_verify, $2->str, $1);
}
;
@@ -565,6 +570,17 @@ maybe_float: TOK_FLOAT { $$ = true; }
| { $$ = false; }
;
+sync_def_sync: sync { $$ = $1; }
+ | { $$ = true; }
+ ;
+
+sync_def_async: sync { $$ = $1; }
+ | { $$ = false; }
+ ;
+
+sync: TOK_SYNC { $$ = true; }
+ | TOK_ASYNC { $$ = false; }
+
boolean: TOK_YES { $$ = true; }
| TOK_NO { $$ = false; }
;
diff --git a/src/lex.c b/src/lex.c
index 991a136..d5f4c4f 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -51,6 +51,7 @@ static const keyword_t keywords[] = {
{ "addresses", TOK_ADDRESSES },
{ "any", TOK_ANY },
{ "as", TOK_AS },
+ { "async", TOK_ASYNC },
{ "auto", TOK_AUTO },
{ "bind", TOK_BIND },
{ "capabilities", TOK_CAPABILITIES },
@@ -100,6 +101,7 @@ static const keyword_t keywords[] = {
{ "secret", TOK_SECRET },
{ "secure", TOK_SECURE },
{ "stderr", TOK_STDERR },
+ { "sync", TOK_SYNC },
{ "syslog", TOK_SYSLOG },
{ "tap", TOK_TAP },
{ "to", TOK_TO },
diff --git a/src/options.c b/src/options.c
index 03f50ae..a4c334f 100644
--- a/src/options.c
+++ b/src/options.c
@@ -270,31 +270,31 @@ static void option_forward(fastd_context_t *ctx UNUSED, fastd_config_t *conf) {
#ifdef WITH_CMDLINE_COMMANDS
static void option_on_pre_up(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_pre_up, arg);
+ fastd_shell_command_set(&conf->on_pre_up, arg, true);
}
static void option_on_up(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_up, arg);
+ fastd_shell_command_set(&conf->on_up, arg, true);
}
static void option_on_down(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_down, arg);
+ fastd_shell_command_set(&conf->on_down, arg, true);
}
static void option_on_post_down(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_post_down, arg);
+ fastd_shell_command_set(&conf->on_post_down, arg, true);
}
static void option_on_establish(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_establish, arg);
+ fastd_shell_command_set(&conf->on_establish, arg, false);
}
static void option_on_disestablish(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_disestablish, arg);
+ fastd_shell_command_set(&conf->on_disestablish, arg, false);
}
static void option_on_verify(fastd_context_t *ctx UNUSED, fastd_config_t *conf, const char *arg) {
- fastd_shell_command_set(&conf->on_verify, arg);
+ fastd_shell_command_set(&conf->on_verify, arg, false);
}
#endif
diff --git a/src/peer.c b/src/peer.c
index 07354df..9aeb81e 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -574,8 +574,11 @@ bool fastd_peer_verify_temporary(fastd_context_t *ctx, fastd_peer_t *peer, const
if (!fastd_shell_command_isset(&ctx->conf->on_verify))
exit_bug(ctx, "tried to verify temporary peer without on-verify command");
+ fastd_shell_command_t cmd = ctx->conf->on_verify;
+ cmd.sync = true; /* TODO: async not supported yet */
+
int ret;
- if (!fastd_shell_command_exec(ctx, &ctx->conf->on_verify, peer, local_addr, peer_addr, &ret))
+ if (!fastd_shell_command_exec(ctx, &cmd, peer, local_addr, peer_addr, &ret))
return false;
if (WIFSIGNALED(ret)) {
diff --git a/src/shell.c b/src/shell.c
index 6d60a07..e1161d4 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -36,12 +36,11 @@ bool fastd_shell_command_exec(fastd_context_t *ctx, const fastd_shell_command_t
if (!fastd_shell_command_isset(command))
return true;
- int result = -1;
bool ok = false;
char *cwd = get_current_dir_name();
- if(!chdir(command->dir)) {
+ if (!chdir(command->dir)) {
/* both INET6_ADDRSTRLEN and IFNAMESIZE already include space for the zero termination, so there is no need to add space for the '%' here. */
char buf[INET6_ADDRSTRLEN+IF_NAMESIZE];
@@ -133,19 +132,35 @@ bool fastd_shell_command_exec(fastd_context_t *ctx, const fastd_shell_command_t
ctx->conf->protocol->set_shell_env(ctx, peer);
- result = system(command->command);
+ if (command->sync) {
+ int result = system(command->command);
+
+ if (ret) {
+ *ret = result;
+ ok = true;
+ }
+ else {
+ if (WIFSIGNALED(result))
+ pr_error(ctx, "command exited with signal %i", WTERMSIG(result));
+ else if (WEXITSTATUS(result))
+ pr_warn(ctx, "command exited with status %i", WEXITSTATUS(result));
+ else
+ ok = true;
+ }
- if (ret) {
- *ret = result;
- ok = true;
}
else {
- if (WIFSIGNALED(result))
- pr_error(ctx, "command exited with signal %i", WTERMSIG(result));
- else if (WEXITSTATUS(result))
- pr_warn(ctx, "command exited with status %i", WEXITSTATUS(result));
- else
+ pid_t pid = fork();
+ if (pid == 0) {
+ execl("/bin/sh", "sh", "-c", command->command, (char*)NULL);
+ _exit(127);
+ }
+ else if (pid > 0) {
ok = true;
+ }
+ else {
+ pr_error_errno(ctx, "fastd_shell_exec_command: fork");
+ }
}
if(chdir(cwd))
diff --git a/src/shell.h b/src/shell.h
index 18ceb2a..e6c3618 100644
--- a/src/shell.h
+++ b/src/shell.h
@@ -35,6 +35,7 @@
struct fastd_shell_command {
char *command;
char *dir;
+ bool sync;
};
static inline void fastd_shell_command_unset(fastd_shell_command_t *command) {
@@ -45,11 +46,12 @@ static inline void fastd_shell_command_unset(fastd_shell_command_t *command) {
command->dir = NULL;
}
-static inline void fastd_shell_command_set(fastd_shell_command_t *command, const char *val) {
+static inline void fastd_shell_command_set(fastd_shell_command_t *command, const char *val, bool sync) {
fastd_shell_command_unset(command);
command->command = strdup(val);
command->dir = get_current_dir_name();
+ command->sync = sync;
}
static inline bool fastd_shell_command_isset(const fastd_shell_command_t *command) {