Compare commits

..

No commits in common. "cfe21828865e3a3b11f9e008e6df9a7e334f7f81" and "0a32cc92e859c6f4453afd996769e654e7687460" have entirely different histories.

2 changed files with 42 additions and 68 deletions

View File

@ -103,16 +103,8 @@ Install
## Debian / Ubuntu ## Debian / Ubuntu
Latest release can be installed using apt Latest release can be installed using apt
``` ```
# First, obtain key, assume it's trusted. curl -s https://repo.quitesimple.org/repo.quitesimple.org.asc | sudo apt-key add -
wget -O- https://repo.quitesimple.org/repo.quitesimple.org.asc | gpg --dearmor > repo.quitesimple.org-keyring.gpg echo "deb https://repo.quitesimple.org/debian/ default main" | sudo tee /etc/apt/sources.list.d/quitesimple.list
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 update
sudo apt-get install adhocify sudo apt-get install adhocify
``` ```

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2024 Albert S. <adhocify@quitesimple.org> * Copyright (c) 2014-2020 Albert S. <adhocify@quitesimple.org>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -78,8 +78,6 @@ char *path_logfile = NULL;
char **script_arguments = NULL; // options to be passed to script we are calling char **script_arguments = NULL; // options to be passed to script we are calling
size_t n_script_arguments = 0; size_t n_script_arguments = 0;
volatile sig_atomic_t handle_child_exits = 0;
void *xmalloc(size_t size) void *xmalloc(size_t size)
{ {
void *m = malloc(size); void *m = malloc(size);
@ -511,7 +509,7 @@ void print_usage()
printf("--no-forkbomb-check, -b Disable fork bomb detection\n"); 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 " printf("--ignore, -i Shell wildcard pattern (see glob(7)) to ignore events on files for which the "
"pattern matches\n"); "pattern matches\n");
printf("--exit-with-child, -e Exit when the commands exits. You can also specify a return code and negations (e. g. -e'!0' to " printf("--exit-with-child, -e Exit when the commands exits. You can also specify a return code (e. g. -e=1 to "
"exit only on errors)\n"); "exit only on errors)\n");
printf("\nIf your command should know the file the event occured on, use the {} placeholder when you specify the " printf("\nIf your command should know the file the event occured on, use the {} placeholder when you specify the "
"arguments (like xargs)\n"); "arguments (like xargs)\n");
@ -675,62 +673,10 @@ 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) void start_monitoring(int ifd)
{ {
while(1) while(1)
{ {
if(handle_child_exits)
{
handle_child_exits = 1;
wait_for_children();
}
int len; int len;
int offset = 0; int offset = 0;
char buf[BUF_SIZE]; char buf[BUF_SIZE];
@ -742,6 +688,7 @@ void start_monitoring(int ifd)
perror("read"); perror("read");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
while(offset < len) while(offset < len)
{ {
@ -752,14 +699,49 @@ void start_monitoring(int ifd)
} }
} }
void child_handler(int signum, siginfo_t *info, void *context) void child_handler(int signum, siginfo_t *info, void *context)
{ {
if(signum != SIGCHLD) if(signum != SIGCHLD)
{ {
return; return;
} }
handle_child_exits = 1;
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);
}
} }
void set_signals() void set_signals()