inotifyd: exit if x event happened for all files fix FIONREAD parameter type fix default mask code shrink help text
No binary (build failed)
—
(log yok)
| @@ -1838,16 +1838,11 @@ | |
| " ::shutdown:/sbin/swapoff -a\n" | |
| #define inotifyd_trivial_usage \ | |
| - | "/user/space/agent dir/or/file/being/watched[:mask] ..." |
| + | "PROG FILE1[:MASK] ..." |
| #define inotifyd_full_usage "\n\n" \ | |
| - | "Run userspace agent on filesystem changes." \ |
| - | "\nWhen a filesystem event matching the mask occurs" \ |
| - | "\non specified file /user/space/agent is run" \ |
| - | "\nwith the parameters:" \ |
| - | "\n1. actual event(s)" \ |
| - | "\n2. file name" \ |
| - | "\n3. name of subfile (if any)" \ |
| - | "\ninotifyd waits for agent to exit." \ |
| + | "Run PROG on filesystem changes." \ |
| + | "\nWhen a filesystem event matching MASK occurs on FILEn," \ |
| + | "\nPROG <actual_event(s)> <FILEn> [<subfile_name>] is run." \ |
| "\nEvents:" \ | |
| "\n a File is accessed" \ | |
| "\n c File is modified" \ | |
| @@ -1865,6 +1860,9 @@ | |
| "\n y Subfile is moved out of dir" \ | |
| "\n n Subfile is created" \ | |
| "\n d Subfile is deleted" \ | |
| + | "\n" \ |
| + | "\ninotifyd waits for PROG to exit." \ |
| + | "\nWhen x event happens for all FILEs, inotifyd exits" \ |
| #define insmod_trivial_usage \ | |
| USE_FEATURE_2_4_MODULES("[OPTION]... ") "MODULE [symbol=value]..." | |
| @@ -44,6 +44,7 @@ static const char mask_names[] ALIGN1 = | |
| "D" // 0x00000400 Self was deleted | |
| "M" // 0x00000800 Self was moved | |
| "\0" // 0x00001000 (unused) | |
| + | // Kernel events, always reported: |
| "u" // 0x00002000 Backing fs was unmounted | |
| "o" // 0x00004000 Event queued overflowed | |
| "x" // 0x00008000 File is no longer watched (usually deleted) | |
| @@ -56,27 +57,38 @@ extern int inotify_init(void); | |
| extern int inotify_add_watch(int fd, const char *path, uint32_t mask); | |
| int inotifyd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| - | int inotifyd_main(int argc UNUSED_PARAM, char **argv) |
| + | int inotifyd_main(int argc, char **argv) |
| { | |
| int n; | |
| - | unsigned mask = IN_ALL_EVENTS; // assume we want all events |
| + | unsigned mask; |
| struct pollfd pfd; | |
| - | char **watched = ++argv; // watched name list |
| - | const char *args[] = { *argv, NULL, NULL, NULL, NULL }; |
| + | char **watches; // names of files being watched |
| + | const char *args[5]; |
| // sanity check: agent and at least one watch must be given | |
| - | if (!argv[0] || !argv[1]) |
| + | if (!argv[1] || !argv[2]) |
| bb_show_usage(); | |
| + | argv++; |
| + | // inotify_add_watch will number watched files |
| + | // starting from 1, thus watches[0] is unimportant, |
| + | // and 1st file name is watches[1]. |
| + | watches = argv; |
| + | args[0] = *argv; |
| + | args[4] = NULL; |
| + | argc -= 2; // number of files we watch |
| + | |
| // open inotify | |
| pfd.fd = inotify_init(); | |
| if (pfd.fd < 0) | |
| bb_perror_msg_and_die("no kernel support"); | |
| - | // setup watched |
| + | // setup watches |
| while (*++argv) { | |
| char *path = *argv; | |
| char *masks = strchr(path, ':'); | |
| + | |
| + | mask = 0x0fff; // assuming we want all non-kernel events |
| // if mask is specified -> | |
| if (masks) { | |
| *masks = '\0'; // split path and mask | |
| @@ -102,10 +114,9 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv) | |
| // do watch | |
| pfd.events = POLLIN; | |
| while (1) { | |
| - | ssize_t len; |
| + | int len; |
| void *buf; | |
| struct inotify_event *ie; | |
| - | |
| again: | |
| if (bb_got_signal) | |
| break; | |
| @@ -124,6 +135,7 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv) | |
| break; | |
| // read out all pending events | |
| + | // (NB: len must be int, not ssize_t or long!) |
| xioctl(pfd.fd, FIONREAD, &len); | |
| #define eventbuf bb_common_bufsiz1 | |
| ie = buf = (len <= sizeof(eventbuf)) ? eventbuf : xmalloc(len); | |
| @@ -142,11 +154,15 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| *s = '\0'; | |
| // bb_error_msg("exec %s %08X\t%s\t%s\t%s", args[0], | |
| - | // ie->mask, events, watched[ie->wd], ie->len ? ie->name : ""); |
| + | // ie->mask, events, watches[ie->wd], ie->len ? ie->name : ""); |
| args[1] = events; | |
| - | args[2] = watched[ie->wd]; |
| + | args[2] = watches[ie->wd]; |
| args[3] = ie->len ? ie->name : NULL; | |
| wait4pid(xspawn((char **)args)); | |
| + | // we are done if all files got final x event |
| + | if (ie->mask & 0x8000) |
| + | if (--argc <= 0) |
| + | goto done; |
| } | |
| // next event | |
| i = sizeof(struct inotify_event) + ie->len; | |
| @@ -155,7 +171,7 @@ int inotifyd_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| if (eventbuf != buf) | |
| free(buf); | |
| - | } |
| - | |
| - | return EXIT_SUCCESS; |
| + | } // while (1) |
| + | done: |
| + | return bb_got_signal; |
| } | |