Esempio n. 1
0
/* 
 * Creates necessary subdirectories in the AIX Event Infrastructure
 * file system for monitoring the object specified.
 * Returns code from mkdir call
 */
static int uv__make_subdirs_p(const char *filename) {
  char cmd[2048];
  char *p;
  int rc = 0;

  /* Strip off the monitor file name */
  p = strrchr(filename, '/');

  if (p == NULL)
    return 0;

  if (uv__path_is_a_directory((char*)filename) == 0) {
    sprintf(cmd, "/aha/fs/modDir.monFactory");
  } else {
    sprintf(cmd, "/aha/fs/modFile.monFactory");
  }

  strncat(cmd, filename, (p - filename));
  rc = uv__makedir_p(cmd);

  if (rc == -1 && errno != EEXIST){
    return -errno;
  }

  return rc;
}
Esempio n. 2
0
/* This is the internal callback */
static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
  char   result_data[RDWR_BUF_SIZE];
  int bytes, rc = 0;
  uv_fs_event_t* handle;
  int events = 0;
  int  i = 0;
  char fname[PATH_MAX];
  char *p;

  handle = container_of(event_watch, uv_fs_event_t, event_watcher);

  /* Clean all the buffers*/
  for(i = 0; i < PATH_MAX; i++) {
    fname[i] = 0;
  }
  i = 0;

  /* At this point, we assume that polling has been done on the
   * file descriptor, so we can just read the AHAFS event occurrence
   * data and parse its results without having to block anything
   */
  bytes = pread(event_watch->fd, result_data, RDWR_BUF_SIZE, 0);

  assert((bytes <= 0) && "uv__ahafs_event - Error reading monitor file");

  /* Parse the data */
  if(bytes > 0)
    rc = uv__parse_data(result_data, &events, handle);

  /* For directory changes, the name of the files that triggered the change
   * are never absolute pathnames
   */
  if (uv__path_is_a_directory(handle->path) == 0) {
    p = handle->dir_filename;
    while(*p != NULL){
      fname[i]= *p;
      i++;
      p++;
    }
  } else {
    /* For file changes, figure out whether filename is absolute or not */
    if (handle->path[0] == '/') {
      p = strrchr(handle->path, '/');
      p++;

      while(*p != NULL) {
        fname[i]= *p;
        i++;
        p++;
      }
    }
  }

  /* Unrecoverable error */
  if (rc == -1)
    return;
  else /* Call the actual JavaScript callback function */
    handle->cb(handle, (const char*)&fname, events, 0);
}
Esempio n. 3
0
/*
 * Checks if /aha is mounted, then proceeds to set up the monitoring
 * objects for the specified file.
 * Returns 0 on success, or an error code < 0 on failure
 */
static int uv__setup_ahafs(const char* filename, int *fd) {
    int rc = 0;
    char mon_file_write_string[RDWR_BUF_SIZE];
    char mon_file[PATH_MAX];
    int file_is_directory = 0; /* -1 == NO, 0 == YES  */

    /* Create monitor file name for object */
    file_is_directory = uv__path_is_a_directory((char*)filename);

    if (file_is_directory == 0)
        sprintf(mon_file, "/aha/fs/modDir.monFactory");
    else
        sprintf(mon_file, "/aha/fs/modFile.monFactory");

    if ((strlen(mon_file) + strlen(filename) + 5) > PATH_MAX)
        return -ENAMETOOLONG;

    /* Make the necessary subdirectories for the monitor file */
    rc = uv__make_subdirs_p(filename);
    if (rc == -1 && errno != EEXIST)
        return rc;

    strcat(mon_file, filename);
    strcat(mon_file, ".mon");

    *fd = 0;
    errno = 0;

    /* Open the monitor file, creating it if necessary */
    *fd = open(mon_file, O_CREAT|O_RDWR);
    if (*fd < 0)
        return -errno;

    /* Write out the monitoring specifications.
     * In this case, we are monitoring for a state change event type
     *    CHANGED=YES
     * We will be waiting in select call, rather than a read:
     *    WAIT_TYPE=WAIT_IN_SELECT
     * We only want minimal information for files:
     *      INFO_LVL=1
     * For directories, we want more information to track what file
     * caused the change
     *      INFO_LVL=2
     */

    if (file_is_directory == 0)
        sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=2");
    else
        sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1");

    rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1);
    if (rc < 0)
        return -errno;

    return 0;
}
Esempio n. 4
0
/* This is the internal callback */
static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
  char   result_data[RDWR_BUF_SIZE];
  int bytes, rc = 0;
  uv_fs_event_t* handle;
  int events = 0;
  char fname[PATH_MAX];
  char *p;

  handle = container_of(event_watch, uv_fs_event_t, event_watcher);

  /* At this point, we assume that polling has been done on the
   * file descriptor, so we can just read the AHAFS event occurrence
   * data and parse its results without having to block anything
   */
  bytes = pread(event_watch->fd, result_data, RDWR_BUF_SIZE, 0);

  assert((bytes >= 0) && "uv__ahafs_event - Error reading monitor file");

  /* In file / directory move cases, AIX Event infrastructure
   * produces a second event with no data.
   * Ignore it and return gracefully.
   */
  if(bytes == 0)
    return;

  /* Parse the data */
  if(bytes > 0)
    rc = uv__parse_data(result_data, &events, handle);

  /* Unrecoverable error */
  if (rc == -1)
    return;

  /* For directory changes, the name of the files that triggered the change
   * are never absolute pathnames
   */
  if (uv__path_is_a_directory(handle->path) == 0) {
    p = handle->dir_filename;
  } else {
    p = strrchr(handle->path, '/');
    if (p == NULL)
      p = handle->path;
    else
      p++;
  }

  /* TODO(bnoordhuis) Check uv__strscpy() return value. */
  uv__strscpy(fname, p, sizeof(fname));

  handle->cb(handle, fname, events, 0);
}
Esempio n. 5
0
int uv_fs_event_stop(uv_fs_event_t* handle) {

    if (!uv__is_active(handle))
        return 0;

    uv__io_close(handle->loop, &handle->event_watcher);
    uv__handle_stop(handle);

    if (uv__path_is_a_directory(handle->path) == 0) {
        uv__free(handle->dir_filename);
        handle->dir_filename = NULL;
    }

    uv__free(handle->path);
    handle->path = NULL;
    uv__close(handle->event_watcher.fd);
    handle->event_watcher.fd = -1;

    return 0;
}
Esempio n. 6
0
int uv_fs_event_stop(uv_fs_event_t* handle) {
#ifdef HAVE_SYS_AHAFS_EVPRODS_H
  if (!uv__is_active(handle))
    return 0;

  uv__io_close(handle->loop, &handle->event_watcher);
  uv__handle_stop(handle);

  if (uv__path_is_a_directory(handle->path) == 0) {
    uv__free(handle->dir_filename);
    handle->dir_filename = NULL;
  }

  uv__free(handle->path);
  handle->path = NULL;
  uv__close(handle->event_watcher.fd);
  handle->event_watcher.fd = -1;

  return 0;
#else
  return -ENOSYS;
#endif
}
Esempio n. 7
0
/*
 * Parse the event occurrence data to figure out what event just occurred
 * and take proper action.
 * 
 * The buf is a pointer to the buffer containing the event occurrence data
 * Returns 0 on success, -1 if unrecoverable error in parsing
 *
 */
static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) {
  int    evp_rc, i;
  char   *p;
  char   filename[PATH_MAX]; /* To be used when handling directories */

  p = buf;
  *events = 0;

  /* Clean the filename buffer*/
  for(i = 0; i < PATH_MAX; i++) {
    filename[i] = 0;
  }
  i = 0;

  /* Check for BUF_WRAP */
  if (strncmp(buf, "BUF_WRAP", strlen("BUF_WRAP")) == 0) {
    assert(0 && "Buffer wrap detected, Some event occurrences lost!");
    return 0;
  }

  /* Since we are using the default buffer size (4K), and have specified
   * INFO_LVL=1, we won't see any EVENT_OVERFLOW conditions.  Applications
   * should check for this keyword if they are using an INFO_LVL of 2 or
   * higher, and have a buffer size of <= 4K
   */

  /* Skip to RC_FROM_EVPROD */
  if (uv__skip_lines(&p, 9) != 9)
    return -1;

  if (sscanf(p, "RC_FROM_EVPROD=%d\nEND_EVENT_DATA", &evp_rc) == 1) {
    if (uv__path_is_a_directory(handle->path) == 0) { /* Directory */
      if (evp_rc == AHAFS_MODDIR_UNMOUNT || evp_rc == AHAFS_MODDIR_REMOVE_SELF) {
        /* The directory is no longer available for monitoring */
        *events = UV_RENAME;
        handle->dir_filename = NULL;
      } else {
        /* A file was added/removed inside the directory */
        *events = UV_CHANGE;

        /* Get the EVPROD_INFO */
        if (uv__skip_lines(&p, 1) != 1)
          return -1;

        /* Scan out the name of the file that triggered the event*/
        if (sscanf(p, "BEGIN_EVPROD_INFO\n%sEND_EVPROD_INFO", filename) == 1) {
          handle->dir_filename = uv__strdup((const char*)&filename);
        } else
          return -1;
        }
    } else { /* Regular File */
      if (evp_rc == AHAFS_MODFILE_RENAME)
        *events = UV_RENAME;
      else
        *events = UV_CHANGE;
    }
  }
  else
    return -1;

  return 0;
}