summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/afb-config.c59
-rw-r--r--src/jobs.c13
-rw-r--r--src/main-afb-daemon.c26
-rw-r--r--src/sig-monitor.c37
-rw-r--r--src/sig-monitor.h4
5 files changed, 110 insertions, 29 deletions
diff --git a/src/afb-config.c b/src/afb-config.c
index 38dd9b71..669bbc57 100644
--- a/src/afb-config.c
+++ b/src/afb-config.c
@@ -108,12 +108,13 @@
#define SET_TRACESVC 26
#endif
+#define SET_TRAP_FAULTS 27
+
#if defined(WITH_DBUS_TRANSPARENCY)
# define ADD_DBUS_CLIENT 30
# define ADD_DBUS_SERVICE 31
#endif
-
#define ADD_AUTO_API 'A'
#define ADD_BINDING 'b'
#define SET_CONFIG 'C'
@@ -220,6 +221,8 @@ static struct option_desc optdefs[] = {
{ADD_SET, 1, "set", "Set parameters ([API]/[KEY]:JSON or {\"API\":{\"KEY\":JSON}}" },
{SET_OUTPUT, 1, "output", "Redirect stdout and stderr to output file (when --daemon)"},
+ {SET_TRAP_FAULTS, 1, "trap-faults", "Trap faults: on, off, yes, no, true, false, 1, 0 (default: true)"},
+
{0, 0, NULL, NULL}
/* *INDENT-ON* */
};
@@ -453,6 +456,29 @@ static struct json_object *to_jbool(int value)
* arguments helpers
***********************************/
+static int string_to_bool(const char *value)
+{
+ static const char true_names[] = "1\0yes\0true\0on";
+ static const char false_names[] = "0\0no\0false\0off";
+ size_t pos;
+
+ pos = 0;
+ while (pos < sizeof true_names)
+ if (strcasecmp(value, &true_names[pos]))
+ pos += 1 + strlen(&true_names[pos]);
+ else
+ return 1;
+
+ pos = 0;
+ while (pos < sizeof false_names)
+ if (strcasecmp(value, &false_names[pos]))
+ pos += 1 + strlen(&false_names[pos]);
+ else
+ return 0;
+
+ return -1;
+}
+
static void noarg(int optid)
{
if (optarg) {
@@ -471,6 +497,17 @@ static const char *get_arg(int optid)
return optarg;
}
+static int get_arg_bool(int optid)
+{
+ int value = string_to_bool(get_arg(optid));
+ if (value < 0) {
+ ERROR("option [--%s] needs a boolean value: yes/no, true/false, on/off, 1/0",
+ name_of_optid(optid));
+ exit(1);
+ }
+ return value;
+}
+
static void config_del(struct json_object *config, int optid)
{
return json_object_object_del(config, name_of_optid(optid));
@@ -789,6 +826,11 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
config_set_bool(config, SET_DAEMON, optid != SET_FOREGROUND);
break;
+ case SET_TRAP_FAULTS:
+ config_set_bool(config, optid, get_arg_bool(optid));
+ break;
+
+
case SET_TRACEREQ:
config_set_optenum(config, optid, afb_hook_flags_xreq_from_text);
break;
@@ -941,6 +983,20 @@ static void on_environment_enum(struct json_object *config, int optid, const cha
}
}
+static void on_environment_bool(struct json_object *config, int optid, const char *name)
+{
+ char *value = getenv(name);
+ int asbool;
+
+ if (value) {
+ asbool = string_to_bool(value);
+ if (asbool < 0)
+ WARNING("Unknown value %s for environment variable %s, ignored", value, name);
+ else
+ config_set_bool(config, optid, asbool);
+ }
+}
+
static void parse_environment(struct json_object *config)
{
on_environment_enum(config, SET_TRACEREQ, "AFB_TRACEREQ", afb_hook_flags_xreq_from_text);
@@ -954,6 +1010,7 @@ static void parse_environment(struct json_object *config)
on_environment_enum(config, SET_TRACEDITF, "AFB_TRACEDITF", afb_hook_flags_legacy_ditf_from_text);
on_environment_enum(config, SET_TRACESVC, "AFB_TRACESVC", afb_hook_flags_legacy_svc_from_text);
#endif
+ on_environment_bool(config, SET_TRAP_FAULTS, "AFB_TRAP_FAULTS");
}
struct json_object *afb_config_parse_arguments(int argc, char **argv)
diff --git a/src/jobs.c b/src/jobs.c
index 27b7dfbf..a6357c87 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -49,13 +49,6 @@
#include "fdev-epoll.h"
#endif
-#if 0
-#define _alert_ "do you really want to remove signal monitoring?"
-#define sig_monitor_init_timeouts() ((void)0)
-#define sig_monitor_clean_timeouts() ((void)0)
-#define sig_monitor(to,cb,arg) (cb(0,arg))
-#endif
-
#define EVENT_TIMEOUT_TOP ((uint64_t)-1)
#define EVENT_TIMEOUT_CHILD ((uint64_t)10000)
@@ -875,12 +868,6 @@ int jobs_start(int allowed_count, int start_count, int waiter_count, void (*star
goto error;
}
- /* start */
- if (sig_monitor_init() < 0) {
- ERROR("failed to initialise signal handlers");
- goto error;
- }
-
/* records the allowed count */
allowed = allowed_count;
started = 0;
diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c
index 0db84bc1..06aeb58d 100644
--- a/src/main-afb-daemon.c
+++ b/src/main-afb-daemon.c
@@ -50,7 +50,6 @@
#include "afb-hsrv.h"
#include "afb-hreq.h"
#include "afb-xreq.h"
-#include "jobs.h"
#include "afb-session.h"
#include "verbose.h"
#include "afb-common.h"
@@ -59,12 +58,15 @@
#include "afb-hook.h"
#include "afb-hook-flags.h"
#include "afb-debug.h"
-#include "process-name.h"
-#include "wrap-json.h"
#if defined(WITH_SUPERVISION)
# include "afb-supervision.h"
#endif
+#include "process-name.h"
+#include "wrap-json.h"
+#include "jobs.h"
+#include "sig-monitor.h"
+
/*
if SELF_PGROUP == 0 the launched command is the group leader
if SELF_PGROUP != 0 afb-daemon is the group leader
@@ -823,15 +825,23 @@ error:
int main(int argc, char *argv[])
{
- struct json_object *name;
+ struct json_object *obj;
afb_debug("main-entry");
// ------------- Build session handler & init config -------
main_config = afb_config_parse_arguments(argc, argv);
- if (json_object_object_get_ex(main_config, "name", &name)) {
- verbose_set_name(json_object_get_string(name), 0);
- process_name_set_name(json_object_get_string(name));
- process_name_replace_cmdline(argv, json_object_get_string(name));
+ if (sig_monitor_init(
+ !json_object_object_get_ex(main_config, "trap-faults", &obj)
+ || json_object_get_boolean(obj)) < 0) {
+ ERROR("failed to initialise signal handlers");
+ return 1;
+ }
+
+
+ if (json_object_object_get_ex(main_config, "name", &obj)) {
+ verbose_set_name(json_object_get_string(obj), 0);
+ process_name_set_name(json_object_get_string(obj));
+ process_name_replace_cmdline(argv, json_object_get_string(obj));
}
afb_debug("main-args");
diff --git a/src/sig-monitor.c b/src/sig-monitor.c
index e15c32de..15fe260d 100644
--- a/src/sig-monitor.c
+++ b/src/sig-monitor.c
@@ -44,6 +44,7 @@ static _Thread_local timer_t thread_timerid;
static int sigerr[] = { SIG_FOR_TIMER, SIGSEGV, SIGFPE, SIGILL, SIGBUS, 0 };
static int sigterm[] = { SIGINT, SIGABRT, SIGTERM, 0 };
static int exiting = 0;
+static int enabled = 0;
/*
* Dumps the current stack
@@ -236,9 +237,25 @@ static void on_signal_error(int signum)
safe_exit(2);
}
-int sig_monitor_init()
+void sig_monitor_disable()
{
- return (install(on_signal_error, sigerr) & install(on_signal_terminate, sigterm)) - 1;
+ enabled = 0;
+ install(SIG_DFL, sigerr);
+ install(SIG_DFL, sigterm);
+}
+
+int sig_monitor_enable()
+{
+ enabled = install(on_signal_error, sigerr) && install(on_signal_terminate, sigterm);
+ if (enabled)
+ return 0;
+ sig_monitor_disable();
+ return -1;
+}
+
+int sig_monitor_init(int enable)
+{
+ return enable ? sig_monitor_enable() : (sig_monitor_disable(), 0);
}
int sig_monitor_init_timeouts()
@@ -251,7 +268,7 @@ void sig_monitor_clean_timeouts()
timeout_delete();
}
-void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg)
+static void monitor(int timeout, void (*function)(int sig, void*), void *arg)
{
volatile int signum, signum2;
sigjmp_buf jmpbuf, *older;
@@ -260,17 +277,25 @@ void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg)
signum = setjmp(jmpbuf);
if (signum == 0) {
error_handler = &jmpbuf;
- if (timeout)
+ if (timeout) {
+ timeout_create();
timeout_arm(timeout);
+ }
function(0, arg);
} else {
signum2 = setjmp(jmpbuf);
if (signum2 == 0)
function(signum, arg);
}
- error_handler = older;
if (timeout)
timeout_disarm();
+ error_handler = older;
}
-
+void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg)
+{
+ if (enabled)
+ monitor(timeout, function, arg);
+ else
+ function(0, arg);
+}
diff --git a/src/sig-monitor.h b/src/sig-monitor.h
index 9121ac8f..5fdac167 100644
--- a/src/sig-monitor.h
+++ b/src/sig-monitor.h
@@ -17,9 +17,11 @@
#pragma once
-extern int sig_monitor_init();
+extern int sig_monitor_init(int enable);
extern void sig_monitor_clean_timeouts();
extern int sig_monitor_init_timeouts();
+extern void sig_monitor_disable();
+extern int sig_monitor_enable();
extern void sig_monitor(int timeout, void (*function)(int sig, void*), void *arg);