XS-libuv

 view release on metacpan or  search on metacpan

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


  memcpy(buffer, pwd.homedir, len + 1);
  *size = len;
  uv_os_free_passwd(&pwd);

  return 0;
}


int uv_os_tmpdir(char* buffer, size_t* size) {
  const char* buf;
  size_t len;

  if (buffer == NULL || size == NULL || *size == 0)
    return UV_EINVAL;

#define CHECK_ENV_VAR(name)                                                   \
  do {                                                                        \
    buf = getenv(name);                                                       \
    if (buf != NULL)                                                          \
      goto return_buffer;                                                     \
  }                                                                           \
  while (0)

  /* Check the TMPDIR, TMP, TEMP, and TEMPDIR environment variables in order */
  CHECK_ENV_VAR("TMPDIR");
  CHECK_ENV_VAR("TMP");
  CHECK_ENV_VAR("TEMP");
  CHECK_ENV_VAR("TEMPDIR");

#undef CHECK_ENV_VAR

  /* No temp environment variables defined */
  #if defined(__ANDROID__)
    buf = "/data/local/tmp";
  #else
    buf = "/tmp";
  #endif

return_buffer:
  len = strlen(buf);

  if (len >= *size) {
    *size = len + 1;
    return UV_ENOBUFS;
  }

  /* The returned directory should not have a trailing slash. */
  if (len > 1 && buf[len - 1] == '/') {
    len--;
  }

  memcpy(buffer, buf, len + 1);
  buffer[len] = '\0';
  *size = len;

  return 0;
}


static int uv__getpwuid_r(uv_passwd_t *pwd, uid_t uid) {
  struct passwd pw;
  struct passwd* result;
  char* buf;
  size_t bufsize;
  size_t name_size;
  size_t homedir_size;
  size_t shell_size;
  int r;

  if (pwd == NULL)
    return UV_EINVAL;

  /* Calling sysconf(_SC_GETPW_R_SIZE_MAX) would get the suggested size, but it
   * is frequently 1024 or 4096, so we can just use that directly. The pwent
   * will not usually be large. */
  for (bufsize = 2000;; bufsize *= 2) {
    buf = uv__malloc(bufsize);

    if (buf == NULL)
      return UV_ENOMEM;

    do
      r = getpwuid_r(uid, &pw, buf, bufsize, &result);
    while (r == EINTR);

    if (r != 0 || result == NULL)
      uv__free(buf);

    if (r != ERANGE)
      break;
  }

  if (r != 0)
    return UV__ERR(r);

  if (result == NULL)
    return UV_ENOENT;

  /* Allocate memory for the username, shell, and home directory */
  name_size = strlen(pw.pw_name) + 1;
  homedir_size = strlen(pw.pw_dir) + 1;
  shell_size = strlen(pw.pw_shell) + 1;
  pwd->username = uv__malloc(name_size + homedir_size + shell_size);

  if (pwd->username == NULL) {
    uv__free(buf);
    return UV_ENOMEM;
  }

  /* Copy the username */
  memcpy(pwd->username, pw.pw_name, name_size);

  /* Copy the home directory */
  pwd->homedir = pwd->username + name_size;
  memcpy(pwd->homedir, pw.pw_dir, homedir_size);

  /* Copy the shell */
  pwd->shell = pwd->homedir + homedir_size;
  memcpy(pwd->shell, pw.pw_shell, shell_size);

  /* Copy the uid and gid */
  pwd->uid = pw.pw_uid;
  pwd->gid = pw.pw_gid;

  uv__free(buf);

  return 0;
}


int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) {
#if defined(__ANDROID__) && __ANDROID_API__ < 24
  /* This function getgrgid_r() was added in Android N (level 24) */
  return UV_ENOSYS;
#else
  struct group gp;
  struct group* result;
  char* buf;
  char* gr_mem;
  size_t bufsize;
  size_t name_size;
  long members;
  size_t mem_size;

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


    do
      r = getgrgid_r(gid, &gp, buf, bufsize, &result);
    while (r == EINTR);

    if (r != 0 || result == NULL)
      uv__free(buf);

    if (r != ERANGE)
      break;
  }

  if (r != 0)
    return UV__ERR(r);

  if (result == NULL)
    return UV_ENOENT;

  /* Allocate memory for the groupname and members. */
  name_size = strlen(gp.gr_name) + 1;
  members = 0;
  mem_size = sizeof(char*);
  for (r = 0; gp.gr_mem[r] != NULL; r++) {
    mem_size += strlen(gp.gr_mem[r]) + 1 + sizeof(char*);
    members++;
  }

  gr_mem = uv__malloc(name_size + mem_size);
  if (gr_mem == NULL) {
    uv__free(buf);
    return UV_ENOMEM;
  }

  /* Copy the members */
  grp->members = (char**) gr_mem;
  grp->members[members] = NULL;
  gr_mem = (char*) &grp->members[members + 1];
  for (r = 0; r < members; r++) {
    grp->members[r] = gr_mem;
    strcpy(gr_mem, gp.gr_mem[r]);
    gr_mem += strlen(gr_mem) + 1;
  }
  assert(gr_mem == (char*)grp->members + mem_size);

  /* Copy the groupname */
  grp->groupname = gr_mem;
  memcpy(grp->groupname, gp.gr_name, name_size);
  gr_mem += name_size;

  /* Copy the gid */
  grp->gid = gp.gr_gid;

  uv__free(buf);

  return 0;
#endif
}


int uv_os_get_passwd(uv_passwd_t* pwd) {
  return uv__getpwuid_r(pwd, geteuid());
}


int uv_os_get_passwd2(uv_passwd_t* pwd, uv_uid_t uid) {
  return uv__getpwuid_r(pwd, uid);
}


int uv_translate_sys_error(int sys_errno) {
  /* If < 0 then it's already a libuv error. */
  return sys_errno <= 0 ? sys_errno : -sys_errno;
}


int uv_os_environ(uv_env_item_t** envitems, int* count) {
  int i, j, cnt;
  uv_env_item_t* envitem;

  *envitems = NULL;
  *count = 0;

  for (i = 0; environ[i] != NULL; i++);

  *envitems = uv__calloc(i, sizeof(**envitems));

  if (*envitems == NULL)
    return UV_ENOMEM;

  for (j = 0, cnt = 0; j < i; j++) {
    char* buf;
    char* ptr;

    if (environ[j] == NULL)
      break;

    buf = uv__strdup(environ[j]);
    if (buf == NULL)
      goto fail;

    ptr = strchr(buf, '=');
    if (ptr == NULL) {
      uv__free(buf);
      continue;
    }

    *ptr = '\0';

    envitem = &(*envitems)[cnt];
    envitem->name = buf;
    envitem->value = ptr + 1;

    cnt++;
  }

  *count = cnt;
  return 0;

fail:
  for (i = 0; i < cnt; i++) {
    envitem = &(*envitems)[cnt];
    uv__free(envitem->name);
  }
  uv__free(*envitems);

  *envitems = NULL;



( run in 1.653 second using v1.01-cache-2.11-cpan-39bf76dae61 )