aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl D Hamann <carl.hamann@gmail.com>2020-03-07 03:26:35 -0600
committerGitHub <noreply@github.com>2020-03-07 09:26:35 +0000
commitc03dcfcdfb9eed37bfb1f0b14d6e4038fff19f60 (patch)
tree74b403108728859f9cbbc0f9f4f82921201c3b47
parentaa125f511d1407176933d0b447dacb4125382b9d (diff)
downloadinotify-tools-c03dcfcdfb9eed37bfb1f0b14d6e4038fff19f60.zip
inotify-tools-c03dcfcdfb9eed37bfb1f0b14d6e4038fff19f60.tar.gz
inotify-tools-c03dcfcdfb9eed37bfb1f0b14d6e4038fff19f60.tar.bz2
Added -P/--no-dereference to watch a symlink (#46)
Allows watching symlinks by ORing IN_DONT_FOLLOW into the set of events This should silently no-op on kernels prior to 2.6.15. Including integration tests and print_help.
-rw-r--r--man/inotifywait.1.in5
-rw-r--r--man/inotifywatch.1.in6
-rw-r--r--src/inotifywait.c35
-rw-r--r--src/inotifywatch.c24
-rwxr-xr-xt/inotifywait-no-dereference-ignore-symlinked-file.t19
-rwxr-xr-xt/inotifywait-no-dereference-respond-to-symlink-event.t19
6 files changed, 89 insertions, 19 deletions
diff --git a/man/inotifywait.1.in b/man/inotifywait.1.in
index f5e0758..786a25a 100644
--- a/man/inotifywait.1.in
+++ b/man/inotifywait.1.in
@@ -5,7 +5,7 @@ inotifywait \- wait for changes to files using inotify
.SH SYNOPSIS
.B inotifywait
-.RB [ \-hcmrq ]
+.RB [ \-hcmrPq ]
.RB [ \-e
<event> ]
.RB [ \-t
@@ -90,6 +90,9 @@ Output errors to
.BR syslog(3)
system log module rather than stderr.
.TP
+.B \-P, \-\-no\-dereference
+Do not follow symlinks.
+.TP
.B \-r, \-\-recursive
Watch all subdirectories of any directories passed as arguments. Watches
will be set up recursively to an unlimited depth. Symbolic links are not
diff --git a/man/inotifywatch.1.in b/man/inotifywatch.1.in
index 5805bab..075330e 100644
--- a/man/inotifywatch.1.in
+++ b/man/inotifywatch.1.in
@@ -5,7 +5,7 @@ inotifywatch \- gather filesystem access statistics using inotify
.SH SYNOPSIS
.B inotifywatch
-.RB [ \-hvzrqf ]
+.RB [ \-hvzrPqf ]
.RB [ \-e
<event> ]
.RB [ \-t
@@ -97,6 +97,10 @@ maximum is 8192; it can be increased by writing to
.BR /proc/sys/fs/inotify/max_user_watches .
.TP
+.B \-P, \-\-no\-dereference
+Do not follow symlinks.
+
+.TP
.B \-t <seconds>, \-\-timeout <seconds>
Listen only for the specified amount of seconds. If not specified, inotifywatch
will gather statistics until receiving an interrupt signal by (for example)
diff --git a/src/inotifywait.c b/src/inotifywait.c
index f32436f..73471f4 100644
--- a/src/inotifywait.c
+++ b/src/inotifywait.c
@@ -34,9 +34,10 @@ extern int optind, opterr, optopt;
// METHODS
bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet,
long int *timeout, int *recursive, bool *csv, bool *daemon,
- bool *syslog, char **format, char **timefmt, char **fromfile,
- char **outfile, char **exc_regex, char **exc_iregex,
- char **inc_regex, char **inc_iregex);
+ bool *syslog, bool *no_dereference, char **format,
+ char **timefmt, char **fromfile, char **outfile,
+ char **exc_regex, char **exc_iregex, char **inc_regex,
+ char **inc_iregex);
void print_help();
@@ -136,6 +137,7 @@ int main(int argc, char **argv) {
bool csv = false;
bool dodaemon = false;
bool syslog = false;
+ bool no_dereference = false;
char *format = NULL;
char *timefmt = NULL;
char *fromfile = NULL;
@@ -148,9 +150,9 @@ int main(int argc, char **argv) {
// Parse commandline options, aborting if something goes wrong
if (!parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout,
- &recursive, &csv, &dodaemon, &syslog, &format, &timefmt,
- &fromfile, &outfile, &exc_regex, &exc_iregex, &inc_regex,
- &inc_iregex)) {
+ &recursive, &csv, &dodaemon, &syslog, &no_dereference,
+ &format, &timefmt, &fromfile, &outfile, &exc_regex,
+ &exc_iregex, &inc_regex, &inc_iregex)) {
return EXIT_FAILURE;
}
@@ -190,6 +192,9 @@ int main(int argc, char **argv) {
if (monitor && recursive) {
events = events | IN_CREATE | IN_MOVED_TO | IN_MOVED_FROM;
}
+ if (no_dereference) {
+ events = events | IN_DONT_FOLLOW;
+ }
FileList list = construct_path_list(argc, argv, fromfile);
@@ -412,9 +417,10 @@ int main(int argc, char **argv) {
bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet,
long int *timeout, int *recursive, bool *csv, bool *daemon,
- bool *syslog, char **format, char **timefmt, char **fromfile,
- char **outfile, char **exc_regex, char **exc_iregex,
- char **inc_regex, char **inc_iregex) {
+ bool *syslog, bool *no_dereference, char **format,
+ char **timefmt, char **fromfile, char **outfile,
+ char **exc_regex, char **exc_iregex, char **inc_regex,
+ char **inc_iregex) {
assert(argc);
assert(argv);
assert(events);
@@ -424,6 +430,7 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet,
assert(csv);
assert(daemon);
assert(syslog);
+ assert(no_dereference);
assert(format);
assert(timefmt);
assert(fromfile);
@@ -449,7 +456,7 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet,
static char *newlineformat;
// Short options
- static const char opt_string[] = "mrhcdsqt:fo:e:";
+ static const char opt_string[] = "mrhcdsPqt:fo:e:";
// Long options
static const struct option long_opts[] = {
@@ -463,6 +470,7 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet,
{"csv", no_argument, NULL, 'c'},
{"daemon", no_argument, NULL, 'd'},
{"syslog", no_argument, NULL, 's'},
+ {"no-dereference", no_argument, NULL, 'P'},
{"format", required_argument, NULL, 'n'},
{"timefmt", required_argument, NULL, 'i'},
{"fromfile", required_argument, NULL, 'z'},
@@ -519,6 +527,11 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet,
(*syslog) = true;
break;
+ // --no-dereference or -P
+ case 'P':
+ (*no_dereference) = true;
+ break;
+
// --filename or -f
case 'f':
fprintf(stderr, "The '--filename' option no longer exists. "
@@ -693,6 +706,8 @@ void print_help() {
"\t-d|--daemon \tSame as --monitor, except run in the background\n"
"\t \tlogging events to a file specified by --outfile.\n"
"\t \tImplies --syslog.\n");
+ printf("\t-P|--no-dereference\n"
+ "\t \tDo not follow symlinks.\n");
printf("\t-r|--recursive\tWatch directories recursively.\n");
printf("\t--fromfile <file>\n"
"\t \tRead files to watch from <file> or `-' for "
diff --git a/src/inotifywatch.c b/src/inotifywatch.c
index 8993554..652ba90 100644
--- a/src/inotifywatch.c
+++ b/src/inotifywatch.c
@@ -30,8 +30,8 @@ extern int optind, opterr, optopt;
// METHODS
bool parse_opts(int *argc, char ***argv, int *events, long int *timeout,
int *verbose, int *zero, int *sort, int *recursive,
- char **fromfile, char **exc_regex, char **exc_iregex,
- char **inc_regex, char **inc_iregex);
+ int *no_dereference, char **fromfile, char **exc_regex,
+ char **exc_iregex, char **inc_regex, char **inc_iregex);
void print_help();
@@ -73,6 +73,7 @@ int main(int argc, char **argv) {
int verbose = 0;
zero = 0;
int recursive = 0;
+ int no_dereference = 0;
char *fromfile = 0;
sort = -1;
done = false;
@@ -85,8 +86,8 @@ int main(int argc, char **argv) {
// Parse commandline options, aborting if something goes wrong
if (!parse_opts(&argc, &argv, &events, &timeout, &verbose, &zero, &sort,
- &recursive, &fromfile, &exc_regex, &exc_iregex, &inc_regex,
- &inc_iregex)) {
+ &recursive, &no_dereference, &fromfile, &exc_regex,
+ &exc_iregex, &inc_regex, &inc_iregex)) {
return EXIT_FAILURE;
}
@@ -118,6 +119,8 @@ int main(int argc, char **argv) {
// If events is still 0, make it all events.
if (!events)
events = IN_ALL_EVENTS;
+ if (no_dereference)
+ events = events | IN_DONT_FOLLOW;
FileList list = construct_path_list(argc, argv, fromfile);
@@ -363,8 +366,8 @@ int print_info() {
bool parse_opts(int *argc, char ***argv, int *e, long int *timeout,
int *verbose, int *z, int *s, int *recursive,
- char **fromfile, char **exc_regex, char **exc_iregex,
- char **inc_regex, char **inc_iregex) {
+ int *no_dereference, char **fromfile, char **exc_regex,
+ char **exc_iregex, char **inc_regex, char **inc_iregex) {
assert(argc);
assert(argv);
assert(e);
@@ -373,6 +376,7 @@ bool parse_opts(int *argc, char ***argv, int *e, long int *timeout,
assert(z);
assert(s);
assert(recursive);
+ assert(no_dereference);
assert(fromfile);
assert(exc_regex);
assert(exc_iregex);
@@ -384,7 +388,7 @@ bool parse_opts(int *argc, char ***argv, int *e, long int *timeout,
bool sort_set = false;
// Short options
- static const char opt_string[] = "hra:d:zve:t:";
+ static const char opt_string[] = "hrPa:d:zve:t:";
// Construct array
static const struct option long_opts[] = {
@@ -396,6 +400,7 @@ bool parse_opts(int *argc, char ***argv, int *e, long int *timeout,
{"ascending", required_argument, NULL, 'a'},
{"descending", required_argument, NULL, 'd'},
{"recursive", no_argument, NULL, 'r'},
+ {"no-dereference", no_argument, NULL, 'P'},
{"fromfile", required_argument, NULL, 'o'},
{"exclude", required_argument, NULL, 'c'},
{"excludei", required_argument, NULL, 'b'},
@@ -426,6 +431,9 @@ bool parse_opts(int *argc, char ***argv, int *e, long int *timeout,
case 'r':
++(*recursive);
break;
+ case 'P':
+ ++(*no_dereference);
+ break;
// --zero or -z
case 'z':
@@ -602,6 +610,8 @@ void print_help() {
"\t\tif they consist only of zeros (the default is to not output\n"
"\t\tthese rows and columns).\n");
printf("\t-r|--recursive\tWatch directories recursively.\n");
+ printf("\t-P|--no-dereference\n"
+ "\t\tDo not follow symlinks.\n");
printf("\t-t|--timeout <seconds>\n"
"\t\tListen only for specified amount of time in seconds; if\n"
"\t\tomitted or negative, inotifywatch will execute until receiving "
diff --git a/t/inotifywait-no-dereference-ignore-symlinked-file.t b/t/inotifywait-no-dereference-ignore-symlinked-file.t
new file mode 100755
index 0000000..1faa7ff
--- /dev/null
+++ b/t/inotifywait-no-dereference-ignore-symlinked-file.t
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+test_description='--no-dereference causes inotifywait to ignore events on symlink target'
+
+. ./sharness.sh
+
+run_() {
+ export LD_LIBRARY_PATH="../../libinotifytools/src/.libs/"
+ touch test &&
+ ln -s test test-symlink &&
+ {(sleep 1 && touch test)&} &&
+ ../../src/.libs/inotifywait --quiet --no-dereference --timeout 2 test-symlink
+}
+
+test_expect_success 'Exit code 2 is returned' '
+ test_expect_code 2 run_
+'
+
+test_done
diff --git a/t/inotifywait-no-dereference-respond-to-symlink-event.t b/t/inotifywait-no-dereference-respond-to-symlink-event.t
new file mode 100755
index 0000000..b78047d
--- /dev/null
+++ b/t/inotifywait-no-dereference-respond-to-symlink-event.t
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+test_description='--no-dereference causes inotifywait to respond to events on symlink'
+
+. ./sharness.sh
+
+run_() {
+ export LD_LIBRARY_PATH="../../libinotifytools/src/.libs/"
+ touch test &&
+ ln -s test test-symlink &&
+ {(sleep 1 && touch -h test-symlink)&} &&
+ ../../src/.libs/inotifywait --quiet --no-dereference --timeout 2 test-symlink
+}
+
+test_expect_success 'Exit code 0 is returned' '
+ run_
+'
+
+test_done