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,22 +673,47 @@ void process_options()
} }
} }
void start_monitoring(int ifd)
void wait_for_children()
{ {
while(1) while(1)
{ {
int status; int len;
pid_t p = waitpid(-1, &status, WNOHANG); int offset = 0;
if(p == 0 || (p == -1 && errno == ECHILD)) // No more children to reap char buf[BUF_SIZE];
len = read(ifd, buf, BUF_SIZE);
if(len == -1)
{
if(errno == EINTR)
continue;
perror("read");
exit(EXIT_FAILURE);
}
while(offset < len)
{
struct inotify_event *event = (struct inotify_event *)&buf[offset];
handle_event(event);
offset += sizeof(struct inotify_event) + event->len;
}
}
}
void child_handler(int signum, siginfo_t *info, void *context)
{
if(signum != SIGCHLD)
{ {
return; return;
} }
int status;
pid_t p = waitpid(-1, &status, WNOHANG);
if(p == -1) if(p == -1)
{ {
logerror("waitpid failed when handling child exit\n"); logerror("waitpid failed when handling child exit\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int adhocify_exit_code = 0; int adhocify_exit_code = 0;
if(WIFEXITED(status)) if(WIFEXITED(status))
{ {
@ -700,9 +723,9 @@ void wait_for_children()
logwrite("command not found, exiting\n"); logwrite("command not found, exiting\n");
exit(adhocify_exit_code); exit(adhocify_exit_code);
} }
if(exit_with_child) if(exit_with_child && awaited_child_exit_code > -1)
{ {
bool must_exit = adhocify_exit_code == awaited_child_exit_code || awaited_child_exit_code == -1; bool must_exit = adhocify_exit_code == awaited_child_exit_code;
if(negate_child_exit_code) if(negate_child_exit_code)
{ {
must_exit = !must_exit; must_exit = !must_exit;
@ -719,47 +742,6 @@ void wait_for_children()
adhocify_exit_code = 128 + WTERMSIG(status); // copy bash's behaviour adhocify_exit_code = 128 + WTERMSIG(status); // copy bash's behaviour
exit(adhocify_exit_code); 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];
len = read(ifd, buf, BUF_SIZE);
if(len == -1)
{
if(errno == EINTR)
continue;
perror("read");
exit(EXIT_FAILURE);
}
while(offset < len)
{
struct inotify_event *event = (struct inotify_event *)&buf[offset];
handle_event(event);
offset += sizeof(struct inotify_event) + event->len;
}
}
}
void child_handler(int signum, siginfo_t *info, void *context)
{
if(signum != SIGCHLD)
{
return;
}
handle_child_exits = 1;
} }
void set_signals() void set_signals()