diff options
author | Sergey Nazaryev <sergey@nazaryev.ru> | 2020-07-09 16:39:35 +0000 |
---|---|---|
committer | Sergey Nazaryev <sergey@nazaryev.ru> | 2020-07-11 21:05:18 +0000 |
commit | e8f8a5617079e24b87bacb136ad0c2ab1b93ceb3 (patch) | |
tree | 8fbc14bd87351934400fcb0ba9e4e7af0fd6507d | |
parent | c598851c60aade135285339c7e9126d74d7cf59b (diff) | |
download | inotify-tools-null-terminated.zip inotify-tools-null-terminated.tar.gz inotify-tools-null-terminated.tar.bz2 |
inotify-tools: Add --no-newline optionnull-terminated
It allows to not to put '\n' after user-specified format in the --format
option
-rw-r--r-- | man/inotifywait.1.in | 15 | ||||
-rw-r--r-- | src/inotifywait.c | 37 | ||||
-rwxr-xr-x | t/inotifywait-format-option-null.t | 48 |
3 files changed, 91 insertions, 9 deletions
diff --git a/man/inotifywait.1.in b/man/inotifywait.1.in index 3c9a0a9..2292a58 100644 --- a/man/inotifywait.1.in +++ b/man/inotifywait.1.in @@ -150,6 +150,10 @@ Set a time format string as accepted by strftime(3) for use with the `%T' conver in the \-\-format option. .TP +.B \-\-no-newline +Don't print newline symbol after user-specified format in the \-\-format option. + +.TP .B \-\-format <fmt> Output in a user-specified format, using printf-like syntax. The event strings output are limited to around 4000 characters and will be truncated to this length. @@ -343,6 +347,17 @@ CLOSE_WRITE:CLOSE goodfile DELETE badfile .fi +.SS Example 4 +Enforce file permissions in directory `~/test' + +.nf +inotifywait -qmr -e 'moved_to,create' --format '%w%f%0' --no-newline ~/test |\\ + while IFS= read -r -d '' file + do + chmod -v a+rX "$file" + done +.fi + .SH BUGS There are race conditions in the recursive directory watching code diff --git a/src/inotifywait.c b/src/inotifywait.c index 73471f4..e346fb9 100644 --- a/src/inotifywait.c +++ b/src/inotifywait.c @@ -37,7 +37,7 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, 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); + char **inc_iregex, bool *no_newline); void print_help(); @@ -146,13 +146,14 @@ int main(int argc, char **argv) { char *exc_iregex = NULL; char *inc_regex = NULL; char *inc_iregex = NULL; + bool no_newline = false; int fd; // Parse commandline options, aborting if something goes wrong if (!parse_opts(&argc, &argv, &events, &monitor, &quiet, &timeout, &recursive, &csv, &dodaemon, &syslog, &no_dereference, &format, &timefmt, &fromfile, &outfile, &exc_regex, - &exc_iregex, &inc_regex, &inc_iregex)) { + &exc_iregex, &inc_regex, &inc_iregex, &no_newline)) { return EXIT_FAILURE; } @@ -420,7 +421,7 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, 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) { + char **inc_iregex, bool *no_newline) { assert(argc); assert(argv); assert(events); @@ -452,8 +453,8 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, const char *regex_warning = "only the last option will be taken into consideration.\n"; - // format with trailing newline - static char *newlineformat; + // format provided by the user + static char *customformat = NULL; // Short options static const char opt_string[] = "mrhcdsPqt:fo:e:"; @@ -472,6 +473,7 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, {"syslog", no_argument, NULL, 's'}, {"no-dereference", no_argument, NULL, 'P'}, {"format", required_argument, NULL, 'n'}, + {"no-newline", no_argument, NULL, '0'}, {"timefmt", required_argument, NULL, 'i'}, {"fromfile", required_argument, NULL, 'z'}, {"outfile", required_argument, NULL, 'o'}, @@ -542,10 +544,13 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, // --format case 'n': - newlineformat = (char *)malloc(strlen(optarg) + 2); - strcpy(newlineformat, optarg); - strcat(newlineformat, "\n"); - (*format) = newlineformat; + customformat = (char *)malloc(strlen(optarg) + 2); + strcpy(customformat, optarg); + break; + + // --no-newline + case '0': + (*no_newline) = true; break; // --timefmt @@ -623,6 +628,13 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, curr_opt = getopt_long(*argc, *argv, opt_string, long_opts, NULL); } + if (customformat) { + if(!(*no_newline)) { + strcat(customformat, "\n"); + } + (*format) = customformat; + } + if (*exc_regex && *exc_iregex) { fprintf(stderr, "--exclude and --excludei cannot both be specified.\n"); return false; @@ -645,6 +657,11 @@ bool parse_opts(int *argc, char ***argv, int *events, bool *monitor, int *quiet, return false; } + if (!*format && *no_newline) { + fprintf(stderr, "--no-newline cannot be specified without --format.\n"); + return false; + } + if (!*format && *timefmt) { fprintf(stderr, "--timefmt cannot be specified without --format.\n"); return false; @@ -719,6 +736,8 @@ void print_help() { printf("\t-qq \tPrint nothing (not even events).\n"); printf("\t--format <fmt>\tPrint using a specified printf-like format\n" "\t \tstring; read the man page for more details.\n"); + printf("\t--no-newline \tDon't print newline symbol after\n" + "\t \t--format string.\n"); printf("\t--timefmt <fmt>\tstrftime-compatible format string for use with\n" "\t \t%%T in --format string.\n"); printf("\t-c|--csv \tPrint events in CSV format.\n"); diff --git a/t/inotifywait-format-option-null.t b/t/inotifywait-format-option-null.t new file mode 100755 index 0000000..ce29147 --- /dev/null +++ b/t/inotifywait-format-option-null.t @@ -0,0 +1,48 @@ +#!/bin/bash + +test_description='Check producing NUL-delimited output' + +. ./sharness.sh + +logfile="log" + +run_() { + touch $logfile + + export LD_LIBRARY_PATH="../../libinotifytools/src/.libs/" + + ../../src/.libs/inotifywait \ + --monitor \ + --quiet \ + --outfile $logfile \ + --format '%w%f%0' \ + --no-newline \ + --event create \ + --event moved_to \ + --event moved_from \ + $(realpath ./) & + + PID="$!" + sleep 1 + + touch test-file-src + + mv test-file-src test-file-dst + + sleep 1 + + kill ${PID} +} + +test_expect_success 'the output is delimited by NUL' \ + ' + set -e + trap "set +e" RETURN + run_ + srcfile="${PWD}/test-file-src" + dstfile="${PWD}/test-file-dst" + + return $(printf "${srcfile}\0${srcfile}\0${dstfile}\0" | cmp -s "${logfile}") + ' + +test_done |