static bool register_roots(array* new_roots, array* unwatchable) { for (int i=0; i<array_size(new_roots); i++) { char* new_root = array_get(new_roots, i); userlog(LOG_INFO, "registering root: %s", new_root); int id = watch(new_root, unwatchable); if (id == ERR_ABORT) { return false; } else if (id >= 0) { watch_root* root = malloc(sizeof(watch_root)); CHECK_NULL(root, false); root->id = id; root->name = new_root; CHECK_NULL(array_push(roots, root), false); } else { if (show_warning && watch_limit_reached()) { int limit = get_watch_count(); userlog(LOG_WARNING, "watch limit (%d) reached", limit); output("MESSAGE\n" INOTIFY_LIMIT_MSG, limit); show_warning = false; // warn only once } CHECK_NULL(array_push(unwatchable, new_root), false); } } return true; }
static bool register_roots(array* new_roots, array* unwatchable, array* mounts) { for (int i=0; i<array_size(new_roots); i++) { char* new_root = array_get(new_roots, i); char* unflattened = new_root; if (unflattened[0] == '|') ++unflattened; userlog(LOG_INFO, "registering root: %s", new_root); if (unflattened[0] != '/') { userlog(LOG_WARNING, " ... not valid, skipped"); continue; } array* inner_mounts = array_create(5); CHECK_NULL(inner_mounts, false); bool skip = false; for (int j=0; j<array_size(mounts); j++) { char* mount = array_get(mounts, j); if (is_parent_path(mount, unflattened)) { userlog(LOG_DEBUG, "watch root '%s' is under mount point '%s' - skipping", unflattened, mount); CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false); skip = true; break; } else if (is_parent_path(unflattened, mount)) { userlog(LOG_DEBUG, "watch root '%s' contains mount point '%s' - partial watch", unflattened, mount); char* copy = strdup(mount); CHECK_NULL(array_push(unwatchable, copy), false); CHECK_NULL(array_push(inner_mounts, copy), false); } } if (skip) { continue; } int id = watch(new_root, inner_mounts); array_delete(inner_mounts); if (id >= 0) { watch_root* root = malloc(sizeof(watch_root)); CHECK_NULL(root, false); root->id = id; root->name = strdup(new_root); CHECK_NULL(root->name, false); CHECK_NULL(array_push(roots, root), false); } else if (id == ERR_ABORT) { return false; } else if (id != ERR_IGNORE) { if (show_warning && watch_limit_reached()) { int limit = get_watch_count(); userlog(LOG_WARNING, "watch limit (%d) reached", limit); output("MESSAGE\n" INOTIFY_LIMIT_MSG, limit); show_warning = false; // warn only once } CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false); } } return true; }