/**
 * Detect and notify about the changes in the watched directory.
 *
 * This function is top-level and it operates with other specific routines
 * to notify about different sets of events in a different conditions.
 *
 * @param[in] wrk   A pointer to #worker.
 * @param[in] w     A pointer to #watch.
 * @param[in] event A pointer to the received kqueue event.
 **/
void
produce_directory_diff (worker *wrk, watch *w, struct kevent *event)
{
    assert (wrk != NULL);
    assert (w != NULL);
    assert (event != NULL);

    assert (w->type == WATCH_USER);
    assert (w->is_directory);

    dep_list *was = NULL, *now = NULL;
    was = dl_shallow_copy (w->deps);
    now = dl_listing (w->filename);
    if (now == NULL && errno != ENOENT) {
        /* Why do I skip ENOENT? Because the directory could be deleted at this
         * point */
        perror_msg ("Failed to create a listing for directory %s",
                    w->filename);
        dl_shallow_free (was);
        return;
    }

    dl_shallow_free (w->deps);
    w->deps = now;

    bulk_events be;
    memset (&be, 0, sizeof (be));

    handle_context ctx;
    memset (&ctx, 0, sizeof (ctx));
    ctx.wrk = wrk;
    ctx.w = w;
    ctx.be = &be;
    
    dl_calculate (was, now, &cbs, &ctx);
    
    if (be.memory) {
        safe_write (wrk->io[KQUEUE_FD], be.memory, be.size);
        free (be.memory);
    }

    dl_free (was);
}
Example #2
0
void
_kh_dir_diff (kqueue_sub *sub, GFileMonitorSource *source)
{
  dep_list *was;
  handle_ctx ctx;

  g_assert (sub != NULL);
  g_assert (source != NULL);

  memset (&ctx, 0, sizeof (handle_ctx));
  ctx.sub = sub;
  ctx.source = source;

  was = sub->deps;
  sub->deps = dl_listing (sub->filename);
 
  dl_calculate (was, sub->deps, &cbs, &ctx);

  dl_free (was);
}