Added command execution support

This commit is contained in:
2024-08-20 16:09:42 +02:00
parent 4e25735cd9
commit 77f6db18a5
3 changed files with 162 additions and 16 deletions

View File

@@ -2,8 +2,11 @@
**Wolf** is a configurable file watchdog for Linux platform written in C. **Wolf** monitors
a set of files or directories and prints out a log event each time the watched resources changes. The watchdog
can be configured to watch for any kind of event, that includes file creation and deletion, file moving, I/O and
permission changing. **Wolf** relies on the `inotify(7)` system call, therefore it is only compatible with Linux-based systems.
can be configured to monitor any kind of event, that includes file creation and deletion, file moving, I/O and
permission changes. Additionally, **Wolf** can execute an user-defined command every time a watchdog detects a
change, thus allowing you to easily build complex pipelines without the need to employ any additional tool.
**Wolf** relies on the `inotify(7)` system call, therefore it is only compatible with Linux-based systems.
## Building
The single source file(`wolf.c`) of the watchdog can be compiled using any C99 compiler. To build it, issue the following command:
@@ -98,16 +101,57 @@ R '/home/marco/wolf' (dir)
P '/home/marco/wolf/a.out' (file)
W '/home/marco/wolf/a.out' (file)
```
Additionally, if you want to execute a custom command every time a watchdog detects a change, you can do so by
using the `-e,--exec` option. For instance, suppose that you have a Python file(`foo.py`) with the following content:
## Caveats
**Wolf** relies on the Linux `inotify(7)` system call to implement the file tracking mechanism. Before using this
tool you should be aware of the following idiosyncrasies related to the way this system interface works:
```py
def square(x):
return x ** 2
1. `inotify` is **NOT** recursive. Meaning that you cannot monitor subdirectories of a watched directory;
2. `inotify` can only work within files for which you already have reading and writing permissions;
3. `inotify` removes deleted files from the `inotify_add_watch(2)`, meaning that a watchdog is automatically
removed from a deleted file. To add it again, the program have to be restarted;
4. `inotify` is quite verbose by design. For instance if you try to write to a **non-empty** watched file
print(f"10^2 = {square(10)}")
```
and you want to continously evaluate it as soon as you save it to the disk. To do this, you can use **Wolf** as described
below:
```sh
$> ./wolf -w --exec 'python foo.py'
```
Each time a write event is detected by the watchdog, the supplied command will be issued, causing the program
to be automatically evaluated, that is:
```sh
$> ./wolf -w --exec 'python foo.py'
[2024-08-20 16:24:43] W 'foo.py' (file)
10^2 = 100
[2024-08-20 16:24:55] W 'foo.py' (file)
10^2 = 100
5^2 = 25
[2024-08-20 16:25:10] W 'foo.py' (file)
10^2 = 100
5^2 = 25
4^2 = 16
```
Be sure to read the _caveats_ section to learn more about the concurrent aspects of this feature and how **Wolf**
spawns a new process.
## Technical details
Below there is a brief list of the things you should be aware of when using **Wolf**.
- `inotify` is **NOT** recursive. Meaning that you cannot monitor subdirectories of a watched directory;
- `inotify` can only work within files for which you already have reading and writing permissions;
- The `-e,--exec` option works by spawning a child process using the `fork(2)` system call; thus, the command is being executed
in a new process;
- The `-e,--exec` option is a **NON-BLOCKING** feature, meaning that the parent process will continue to log new changes while the
child process execute the supplied command; therefore the parent process will **NOT** wait for the child(s) process to terminate;
- Since the parent process does not await for the child process to complete it will also not handle its return code, thus the exit
status of any supplied command is ignored.
- Any `SIGCHLD` signal generated by a child process is ignored, therefore the process reaping of any child is delegated to the kernel;
- `inotify` removes deleted files from the `inotify_add_watch(2)`, meaning that, after a file is being deleted, the watchdog associated with it
is automatically removed as well. To add it again, the program has to be restarted;
- `inotify` is quite verbose by design. For instance if you try to write to a **non-empty** watched file
using the `echo(1)` command along with a _redirection_(i.e., `echo 'hello world' > foo`), the watchdog will
log two events:
@@ -136,7 +180,7 @@ exit_group(0) = ?
+++ exited with 0 +++
```
Since `inotify(1)` intercepts both, **wolf** will also log twice the same operation.
Since `inotify(1)` intercepts both, **wolf** will also log the same operation twice.
## License
[GPLv3](https://choosealicense.com/licenses/gpl-3.0/)