diff --git a/README b/README index bdae64e..69cc205 100644 --- a/README +++ b/README @@ -48,4 +48,6 @@ Watches for IN_OPEN events in /tmp/, launches script /home/core/myscript.sh ... ignores *.txt files .... - +Further options +=============== +-e, --exit-with-child: Instructs adhocify to exit once a child does. You can also specify an exit code, e. g. -e 1, to exit on errors. Default is 0. diff --git a/adhocify.c b/adhocify.c index 0788155..5a1a38e 100644 --- a/adhocify.c +++ b/adhocify.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,9 @@ bool noenv = false; bool fromstdin = false; bool forkbombcheck = true; bool daemonize = false; +bool exit_with_child = false; +int exitcode = 0; + uint32_t mask = 0; char *prog = NULL; char *path_logfile = NULL; @@ -426,7 +430,8 @@ static struct option long_options[] = { "no-forkbomb-check", no_argument, 0, 'b' }, { "ignore", required_argument, 0, 'i' }, { "silent", no_argument, 0, 'q' }, - { "help", no_argument, 0, 'h' } + { "help", no_argument, 0, 'h' }, + { "exit-with-child", optional_argument, 0, 'e' } }; //fills global n_script_arguments and script_arguments var @@ -458,7 +463,7 @@ void parse_options(int argc, char **argv) int option; int option_index; uint32_t optmask = 0; - while((option = getopt_long(argc, argv, "absdo:w:m:l:i:", long_options, &option_index)) != -1) + while((option = getopt_long(argc, argv, "absdo:w:m:l:i:e::", long_options, &option_index)) != -1) { switch(option) { @@ -498,6 +503,13 @@ void parse_options(int argc, char **argv) case 'h': print_usage(); exit(EXIT_SUCCESS); + case 'e': + exit_with_child = true; + if(optarg) + { + exitcode = atoi(optarg); + + } break; } } @@ -578,6 +590,42 @@ void start_monitoring(int ifd) } } } + +void child_handler(int signum, siginfo_t *info, void *context) +{ + if(signum != SIGCHLD) + return; + + int status; + pid_t p = waitpid(-1, &status, WNOHANG); + if(p == -1) + { + logerror("waitpid failed when handling child exit\n"); + exit(EXIT_FAILURE); + } + if(exit_with_child) + { + if(status == exitcode) + { + logwrite("child exited with specified exit code, exiting too"); + exit(exitcode); + } + } + +} +void set_signals() +{ + struct sigaction action; + action.sa_flags = SA_NOCLDSTOP | SA_SIGINFO; + action.sa_sigaction = &child_handler; + if(sigaction(SIGCHLD, &action, NULL) == -1) + { + logerror("Error when setting up the signal handler\n"); + exit(EXIT_FAILURE); + } +} + + int main(int argc, char **argv) { if(argc < 2) @@ -586,7 +634,9 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - signal(SIGCHLD, SIG_IGN); + //signal(SIGCHLD, SIG_IGN); + set_signals(); + parse_options(argc, argv); process_options();