XS-libuv

 view release on metacpan or  search on metacpan

libuv-1.49.2/src/win/util.c  view on Meta::CPAN


   *utf8 = NULL;
   return uv_utf16_to_wtf8(utf16, utf16len, utf8, &utf8_len);
}


/*
 * Converts a UTF-8 string into a UTF-16 one. The resulting string is
 * null-terminated.
 */
int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16) {
  int bufsize;

  if (utf8 == NULL)
    return UV_EINVAL;

  /* Check how much space we need (including NUL). */
  bufsize = uv_wtf8_length_as_utf16(utf8);
  if (bufsize < 0)
    return UV__EINVAL;

  /* Allocate the destination buffer. */
  *utf16 = uv__malloc(sizeof(WCHAR) * bufsize);

  if (*utf16 == NULL)
    return UV_ENOMEM;

  /* Convert to UTF-16 */
  uv_wtf8_to_utf16(utf8, *utf16, bufsize);

  return 0;
}


/*
 * Converts a UTF-16 string into a UTF-8 one in an existing buffer. The
 * resulting string is null-terminated.
 *
 * If utf16 is null terminated, utf16len can be set to -1, otherwise it must
 * be specified.
 */
int uv__copy_utf16_to_utf8(const WCHAR* utf16buffer, size_t utf16len, char* utf8, size_t *size) {
  int r;

  if (utf8 == NULL || size == NULL)
    return UV_EINVAL;

  if (*size == 0) {
    *size = uv_utf16_length_as_wtf8(utf16buffer, utf16len);
    r = UV_ENOBUFS;
  } else {
    *size -= 1; /* Reserve space for NUL. */
    r = uv_utf16_to_wtf8(utf16buffer, utf16len, &utf8, size);
  }
  if (r == UV_ENOBUFS)
    *size += 1; /* Add space for NUL. */
  return r;
}


static int uv__getpwuid_r(uv_passwd_t* pwd) {
  HANDLE token;
  wchar_t username[UNLEN + 1];
  wchar_t *path;
  DWORD bufsize;
  int r;

  if (pwd == NULL)
    return UV_EINVAL;

  /* Get the home directory using GetUserProfileDirectoryW() */
  if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
    return uv_translate_sys_error(GetLastError());

  bufsize = 0;
  GetUserProfileDirectoryW(token, NULL, &bufsize);
  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
    r = GetLastError();
    CloseHandle(token);
    return uv_translate_sys_error(r);
  }

  path = uv__malloc(bufsize * sizeof(wchar_t));
  if (path == NULL) {
    CloseHandle(token);
    return UV_ENOMEM;
  }

  if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
    r = GetLastError();
    CloseHandle(token);
    uv__free(path);
    return uv_translate_sys_error(r);
  }

  CloseHandle(token);

  /* Get the username using GetUserNameW() */
  bufsize = ARRAY_SIZE(username);
  if (!GetUserNameW(username, &bufsize)) {
    r = GetLastError();
    uv__free(path);

    /* This should not be possible */
    if (r == ERROR_INSUFFICIENT_BUFFER)
      return UV_ENOMEM;

    return uv_translate_sys_error(r);
  }

  pwd->homedir = NULL;
  r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
  uv__free(path);

  if (r != 0)
    return r;

  pwd->username = NULL;
  r = uv__convert_utf16_to_utf8(username, -1, &pwd->username);

  if (r != 0) {
    uv__free(pwd->homedir);
    return r;
  }

  pwd->shell = NULL;
  pwd->uid = -1;
  pwd->gid = -1;

  return 0;
}


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


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


int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) {
  return UV_ENOTSUP;
}


int uv_os_environ(uv_env_item_t** envitems, int* count) {
  wchar_t* env;
  wchar_t* penv;
  int i, cnt;
  uv_env_item_t* envitem;

  *envitems = NULL;
  *count = 0;

  env = GetEnvironmentStringsW();
  if (env == NULL)
    return 0;

  for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);

  *envitems = uv__calloc(i, sizeof(**envitems));
  if (*envitems == NULL) {
    FreeEnvironmentStringsW(env);
    return UV_ENOMEM;
  }

  penv = env;
  cnt = 0;

  while (*penv != L'\0' && cnt < i) {
    char* buf;
    char* ptr;

    if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0)
      goto fail;

    /* Using buf + 1 here because we know that `buf` has length at least 1,
     * and some special environment variables on Windows start with a = sign. */
    ptr = strchr(buf + 1, '=');
    if (ptr == NULL) {
      uv__free(buf);
      goto do_continue;
    }

    *ptr = '\0';

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

    cnt++;



( run in 2.732 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )