Compare commits

...

6 Commits

Author SHA1 Message Date
cfe2182886 Fix -e without specified exit code and fix help text 2024-07-07 23:50:41 +02:00
350c4affe5 Handle SIGCHLD in main loop
Otherwise, we call printf() etc. in the signal handler...
2024-07-07 23:50:41 +02:00
88063430ce update copyright 2024-07-07 22:20:55 +02:00
Lester Hightower
bf920a533d Fixed waitpid handling 2024-07-02 10:14:50 -04:00
Lester Hightower
5236c8d947 Reap N-number of children per SIGCHLD 2024-07-02 09:33:43 -04:00
250e2ae24f README.md: Update Ubuntu/Debian apt instructions 2022-07-06 20:17:30 +02:00
2 changed files with 68 additions and 42 deletions

View File

@ -103,8 +103,16 @@ Install
## Debian / Ubuntu
Latest release can be installed using apt
```
curl -s https://repo.quitesimple.org/repo.quitesimple.org.asc | sudo apt-key add -
echo "deb https://repo.quitesimple.org/debian/ default main" | sudo tee /etc/apt/sources.list.d/quitesimple.list
# First, obtain key, assume it's trusted.
wget -O- https://repo.quitesimple.org/repo.quitesimple.org.asc | gpg --dearmor > repo.quitesimple.org-keyring.gpg
cat repo.quitesimple.org-keyring.gpg | sudo tee -a /usr/share/keyrings/repo.quitesimple.org.gpg > /dev/null
#For Debian
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/repo.quitesimple.org.gpg] https://repo.quitesimple.org/debian/ default main" | sudo tee /etc/apt/sources.list.d/quitesimple.list
#For Ubuntu >=21.10, prefer these sources
#echo "deb [arch=amd64 signed-by=/usr/share/keyrings/repo.quitesimple.org.gpg] https://repo.quitesimple.org/debian/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/quitesimple.list
sudo apt-get update
sudo apt-get install adhocify
```

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2020 Albert S. <adhocify@quitesimple.org>
* Copyright (c) 2014-2024 Albert S. <adhocify@quitesimple.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -78,6 +78,8 @@ char *path_logfile = NULL;
char **script_arguments = NULL; // options to be passed to script we are calling
size_t n_script_arguments = 0;
volatile sig_atomic_t handle_child_exits = 0;
void *xmalloc(size_t size)
{
void *m = malloc(size);
@ -509,7 +511,7 @@ void print_usage()
printf("--no-forkbomb-check, -b Disable fork bomb detection\n");
printf("--ignore, -i Shell wildcard pattern (see glob(7)) to ignore events on files for which the "
"pattern matches\n");
printf("--exit-with-child, -e Exit when the commands exits. You can also specify a return code (e. g. -e=1 to "
printf("--exit-with-child, -e Exit when the commands exits. You can also specify a return code and negations (e. g. -e'!0' to "
"exit only on errors)\n");
printf("\nIf your command should know the file the event occured on, use the {} placeholder when you specify the "
"arguments (like xargs)\n");
@ -673,10 +675,62 @@ void process_options()
}
}
void wait_for_children()
{
while(1)
{
int status;
pid_t p = waitpid(-1, &status, WNOHANG);
if(p == 0 || (p == -1 && errno == ECHILD)) // No more children to reap
{
return;
}
if(p == -1)
{
logerror("waitpid failed when handling child exit\n");
exit(EXIT_FAILURE);
}
int adhocify_exit_code = 0;
if(WIFEXITED(status))
{
adhocify_exit_code = WEXITSTATUS(status);
if(adhocify_exit_code == 127)
{
logwrite("command not found, exiting\n");
exit(adhocify_exit_code);
}
if(exit_with_child)
{
bool must_exit = adhocify_exit_code == awaited_child_exit_code || awaited_child_exit_code == -1;
if(negate_child_exit_code)
{
must_exit = !must_exit;
}
if(must_exit)
{
logwrite("command exited with specified exit code, exiting too\n");
exit(adhocify_exit_code);
}
}
}
if(exit_with_child && WIFSIGNALED(status))
{
adhocify_exit_code = 128 + WTERMSIG(status); // copy bash's behaviour
exit(adhocify_exit_code);
}
}
}
void start_monitoring(int ifd)
{
while(1)
{
if(handle_child_exits)
{
handle_child_exits = 1;
wait_for_children();
}
int len;
int offset = 0;
char buf[BUF_SIZE];
@ -688,7 +742,6 @@ void start_monitoring(int ifd)
perror("read");
exit(EXIT_FAILURE);
}
while(offset < len)
{
@ -699,49 +752,14 @@ 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);
}
int adhocify_exit_code = 0;
if(WIFEXITED(status))
{
adhocify_exit_code = WEXITSTATUS(status);
if(adhocify_exit_code == 127)
{
logwrite("command not found, exiting\n");
exit(adhocify_exit_code);
}
if(exit_with_child && awaited_child_exit_code > -1)
{
bool must_exit = adhocify_exit_code == awaited_child_exit_code;
if(negate_child_exit_code)
{
must_exit = !must_exit;
}
if(must_exit)
{
logwrite("command exited with specified exit code, exiting too\n");
exit(adhocify_exit_code);
}
}
}
if(exit_with_child && WIFSIGNALED(status))
{
adhocify_exit_code = 128 + WTERMSIG(status); // copy bash's behaviour
exit(adhocify_exit_code);
}
handle_child_exits = 1;
}
void set_signals()