Esempio n. 1
0
int64_t
do_inotify_add_watch (const char *path, int mask)
{
#ifdef HAVE_SYS_INOTIFY_H
  int64_t r;
  char *buf;

  NEED_INOTIFY (-1);

  buf = sysroot_path (path);
  if (!buf) {
    reply_with_perror ("malloc");
    return -1;
  }

  r = inotify_add_watch (inotify_fd, buf, mask);
  free (buf);
  if (r == -1) {
    reply_with_perror ("%s", path);
    return -1;
  }

  return r;
#else
  NOT_AVAILABLE (-1);
#endif
}
Esempio n. 2
0
int
do_inotify_rm_watch (int wd)
{
  NEED_INOTIFY (-1);

  if (inotify_rm_watch (inotify_fd, wd) == -1) {
    reply_with_perror ("%d", wd);
    return -1;
  }

  return 0;
}
Esempio n. 3
0
int
do_inotify_rm_watch (int wd)
{
#ifdef HAVE_SYS_INOTIFY_H
  NEED_INOTIFY (-1);

  if (inotify_rm_watch (inotify_fd, wd) == -1) {
    reply_with_perror ("%d", wd);
    return -1;
  }

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
Esempio n. 4
0
int
do_inotify_close (void)
{
  NEED_INOTIFY (-1);

  if (inotify_fd == -1) {
    reply_with_error ("handle is not open");
    return -1;
  }

  if (close (inotify_fd) == -1) {
    reply_with_perror ("close");
    return -1;
  }

  inotify_fd = -1;
  inotify_posn = 0;

  return 0;
}
Esempio n. 5
0
int64_t
do_inotify_add_watch (const char *path, int mask)
{
  int64_t r;
  CLEANUP_FREE char *buf = NULL;

  NEED_INOTIFY (-1);

  buf = sysroot_path (path);
  if (!buf) {
    reply_with_perror ("malloc");
    return -1;
  }

  r = inotify_add_watch (inotify_fd, buf, mask);
  if (r == -1) {
    reply_with_perror ("%s", path);
    return -1;
  }

  return r;
}
Esempio n. 6
0
int
do_inotify_close (void)
{
#ifdef HAVE_SYS_INOTIFY_H
  NEED_INOTIFY (-1);

  if (inotify_fd == -1) {
    reply_with_error ("handle is not open");
    return -1;
  }

  if (close (inotify_fd) == -1) {
    reply_with_perror ("close");
    return -1;
  }

  inotify_fd = -1;
  inotify_posn = 0;

  return 0;
#else
  NOT_AVAILABLE (-1);
#endif
}
Esempio n. 7
0
guestfs_int_inotify_event_list *
do_inotify_read (void)
{
  int space;
  guestfs_int_inotify_event_list *ret;

  NEED_INOTIFY (NULL);

  ret = malloc (sizeof *ret);
  if (ret == NULL) {
    reply_with_perror ("malloc");
    return NULL;
  }
  ret->guestfs_int_inotify_event_list_len = 0;
  ret->guestfs_int_inotify_event_list_val = NULL;

  /* Read events that are available, but make sure we won't exceed
   * maximum message size.  In order to achieve this we have to
   * guesstimate the remaining space available.
   */
  space = GUESTFS_MESSAGE_MAX / 2;

  while (space > 0) {
    struct inotify_event *event;
    int r;
    size_t n;

    r = read (inotify_fd, inotify_buf + inotify_posn,
              sizeof (inotify_buf) - inotify_posn);
    if (r == -1) {
      if (errno == EWOULDBLOCK || errno == EAGAIN) /* End of list. */
        break;
      reply_with_perror ("read");
      goto error;
    }
    if (r == 0) {		/* End of file - we're not expecting it. */
      reply_with_error ("unexpected end of file");
      goto error;
    }

    inotify_posn += r;

    /* Read complete events from the buffer and add them to the result. */
    n = 0;
    while (n < inotify_posn) {
      guestfs_int_inotify_event *np;
      guestfs_int_inotify_event *in;

      event = (struct inotify_event *) &inotify_buf[n];

      /* Have we got a complete event in the buffer? */
#ifdef __GNUC__
      if (n + sizeof (struct inotify_event) > inotify_posn ||
          n + sizeof (struct inotify_event) + event->len > inotify_posn)
        break;
#else
#error "this code needs fixing so it works on non-GCC compilers"
#endif

      /* Check event->len is reasonable (note the field is uint32_t). */
      if (event->len > PATH_MAX) {
        reply_with_error ("event->len = %" PRIu32 " > PATH_MAX", event->len);
        goto error;
      }

      np = realloc (ret->guestfs_int_inotify_event_list_val,
                    (ret->guestfs_int_inotify_event_list_len + 1) *
                    sizeof (guestfs_int_inotify_event));
      if (np == NULL) {
        reply_with_perror ("realloc");
        goto error;
      }
      ret->guestfs_int_inotify_event_list_val = np;
      in = &ret->guestfs_int_inotify_event_list_val[ret->guestfs_int_inotify_event_list_len];
      ret->guestfs_int_inotify_event_list_len++;

      in->in_wd = event->wd;
      in->in_mask = event->mask;
      in->in_cookie = event->cookie;

      if (event->len > 0)
        in->in_name = strdup (event->name);
      else
        in->in_name = strdup (""); /* Should have optional string fields XXX. */
      if (in->in_name == NULL) {
        reply_with_perror ("strdup");
        goto error;
      }

      /* Estimate space used by this event in the message. */
      space -= 16 + 4 + strlen (in->in_name) + 4;

      /* Move pointer to next event. */
#ifdef __GNUC__
      n += sizeof (struct inotify_event) + event->len;
#else
#error "this code needs fixing so it works on non-GCC compilers"
#endif
    }

    /* 'n' now points to the first unprocessed/incomplete
     * message in the buffer. Copy that to offset 0 in the buffer.
     */
    memmove (inotify_buf, &inotify_buf[n], inotify_posn - n);
    inotify_posn -= n;
  }

  /* Return the messages. */
  return ret;

 error:
  xdr_free ((xdrproc_t) xdr_guestfs_int_inotify_event_list, (char *) ret);
  free (ret);
  return NULL;
}