XS-libuv

 view release on metacpan or  search on metacpan

libuv-1.49.2/src/unix/aix.c  view on Meta::CPAN



int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
  uv_cpu_info_t* cpu_info;
  perfstat_cpu_total_t ps_total;
  perfstat_cpu_t* ps_cpus;
  perfstat_id_t cpu_id;
  int result, ncpus, idx = 0;

  result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
  if (result == -1) {
    return UV_ENOSYS;
  }

  ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
  if (result == -1) {
    return UV_ENOSYS;
  }

  ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t));
  if (!ps_cpus) {
    return UV_ENOMEM;
  }

  /* TODO(bnoordhuis) Check uv__strscpy() return value. */
  uv__strscpy(cpu_id.name, FIRST_CPU, sizeof(cpu_id.name));
  result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
  if (result == -1) {
    uv__free(ps_cpus);
    return UV_ENOSYS;
  }

  *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t));
  if (!*cpu_infos) {
    uv__free(ps_cpus);
    return UV_ENOMEM;
  }

  *count = ncpus;

  cpu_info = *cpu_infos;
  while (idx < ncpus) {
    cpu_info->speed = (int)(ps_total.processorHZ / 1000000);
    cpu_info->model = uv__strdup(ps_total.description);
    cpu_info->cpu_times.user = ps_cpus[idx].user;
    cpu_info->cpu_times.sys = ps_cpus[idx].sys;
    cpu_info->cpu_times.idle = ps_cpus[idx].idle;
    cpu_info->cpu_times.irq = ps_cpus[idx].wait;
    cpu_info->cpu_times.nice = 0;
    cpu_info++;
    idx++;
  }

  uv__free(ps_cpus);
  return 0;
}


int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
  uv_interface_address_t* address;
  int sockfd, sock6fd, inet6, i, r, size = 1;
  struct ifconf ifc;
  struct ifreq *ifr, *p, flg;
  struct in6_ifreq if6;
  struct sockaddr_dl* sa_addr;

  ifc.ifc_req = NULL;
  sock6fd = -1;
  r = 0;
  *count = 0;
  *addresses = NULL;

  if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
    r = UV__ERR(errno);
    goto cleanup;
  }

  if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) {
    r = UV__ERR(errno);
    goto cleanup;
  }

  if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
    r = UV__ERR(errno);
    goto cleanup;
  }

  ifc.ifc_req = (struct ifreq*)uv__malloc(size);
  if (ifc.ifc_req == NULL) {
    r = UV_ENOMEM;
    goto cleanup;
  }
  ifc.ifc_len = size;
  if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
    r = UV__ERR(errno);
    goto cleanup;
  }

#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))

  /* Count all up and running ipv4/ipv6 addresses */
  ifr = ifc.ifc_req;
  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
    p = ifr;
    ifr = (struct ifreq*)
      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));

    if (!(p->ifr_addr.sa_family == AF_INET6 ||
          p->ifr_addr.sa_family == AF_INET))
      continue;

    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
      r = UV__ERR(errno);
      goto cleanup;
    }

    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
      continue;

    (*count)++;
  }

  if (*count == 0)
    goto cleanup;

  /* Alloc the return interface structs */
  *addresses = uv__calloc(*count, sizeof(**addresses));
  if (!(*addresses)) {
    r = UV_ENOMEM;
    goto cleanup;
  }
  address = *addresses;

  ifr = ifc.ifc_req;
  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
    p = ifr;
    ifr = (struct ifreq*)
      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));

    if (!(p->ifr_addr.sa_family == AF_INET6 ||
          p->ifr_addr.sa_family == AF_INET))
      continue;

    inet6 = (p->ifr_addr.sa_family == AF_INET6);

    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1)
      goto syserror;

    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
      continue;

    /* All conditions above must match count loop */

    address->name = uv__strdup(p->ifr_name);

    if (inet6)
      address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
    else
      address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);

    if (inet6) {
      memset(&if6, 0, sizeof(if6));
      r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name));
      if (r == UV_E2BIG)
        goto cleanup;
      r = 0;
      memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr));
      if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1)
        goto syserror;
      address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr);
      /* Explicitly set family as the ioctl call appears to return it as 0. */
      address->netmask.netmask6.sin6_family = AF_INET6;
    } else {
      if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1)
        goto syserror;
      address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
      /* Explicitly set family as the ioctl call appears to return it as 0. */
      address->netmask.netmask4.sin_family = AF_INET;
    }

    address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;

    address++;
  }

  /* Fill in physical addresses. */
  ifr = ifc.ifc_req;
  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
    p = ifr;
    ifr = (struct ifreq*)
      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));

    if (p->ifr_addr.sa_family != AF_LINK)
      continue;

    address = *addresses;
    for (i = 0; i < *count; i++) {
      if (strcmp(address->name, p->ifr_name) == 0) {
        sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
      }
      address++;
    }
  }

#undef ADDR_SIZE
  goto cleanup;

syserror:
  uv_free_interface_addresses(*addresses, *count);
  *addresses = NULL;
  *count = 0;
  r = UV_ENOSYS;

cleanup:
  if (sockfd != -1)
    uv__close(sockfd);
  if (sock6fd != -1)
    uv__close(sock6fd);
  uv__free(ifc.ifc_req);
  return r;



( run in 1.223 second using v1.01-cache-2.11-cpan-437f7b0c052 )