libuv/src/win/util.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include <assert.h>
23 #include <direct.h>
24 #include <limits.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <time.h>
28 #include <wchar.h>
29 
30 #include "uv.h"
31 #include "internal.h"
32 
33 #include <winsock2.h>
34 #include <winperf.h>
35 #include <iphlpapi.h>
36 #include <psapi.h>
37 #include <tlhelp32.h>
38 #include <windows.h>
39 #include <userenv.h>
40 #include <math.h>
41 
42 /*
43  * Max title length; the only thing MSDN tells us about the maximum length
44  * of the console title is that it is smaller than 64K. However in practice
45  * it is much smaller, and there is no way to figure out what the exact length
46  * of the title is or can be, at least not on XP. To make it even more
47  * annoying, GetConsoleTitle fails when the buffer to be read into is bigger
48  * than the actual maximum length. So we make a conservative guess here;
49  * just don't put the novel you're writing in the title, unless the plot
50  * survives truncation.
51  */
52 #define MAX_TITLE_LENGTH 8192
53 
54 /* The number of nanoseconds in one second. */
55 #define UV__NANOSEC 1000000000
56 
57 /* Max user name length, from iphlpapi.h */
58 #ifndef UNLEN
59 # define UNLEN 256
60 #endif
61 
62 
63 /* Maximum environment variable size, including the terminating null */
64 #define MAX_ENV_VAR_LENGTH 32767
65 
66 /* A RtlGenRandom() by any other name... */
67 extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
68 
69 /* Cached copy of the process title, plus a mutex guarding it. */
70 static char *process_title;
71 static CRITICAL_SECTION process_title_lock;
72 
73 /* Interval (in seconds) of the high-resolution clock. */
74 static double hrtime_interval_ = 0;
75 
76 
77 /*
78  * One-time initialization code for functionality defined in util.c.
79  */
80 void uv__util_init(void) {
81  LARGE_INTEGER perf_frequency;
82 
83  /* Initialize process title access mutex. */
84  InitializeCriticalSection(&process_title_lock);
85 
86  /* Retrieve high-resolution timer frequency
87  * and precompute its reciprocal.
88  */
89  if (QueryPerformanceFrequency(&perf_frequency)) {
90  hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
91  } else {
93  }
94 }
95 
96 
97 int uv_exepath(char* buffer, size_t* size_ptr) {
98  int utf8_len, utf16_buffer_len, utf16_len;
99  WCHAR* utf16_buffer;
100  int err;
101 
102  if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
103  return UV_EINVAL;
104  }
105 
106  if (*size_ptr > 32768) {
107  /* Windows paths can never be longer than this. */
108  utf16_buffer_len = 32768;
109  } else {
110  utf16_buffer_len = (int) *size_ptr;
111  }
112 
113  utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len);
114  if (!utf16_buffer) {
115  return UV_ENOMEM;
116  }
117 
118  /* Get the path as UTF-16. */
119  utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
120  if (utf16_len <= 0) {
121  err = GetLastError();
122  goto error;
123  }
124 
125  /* utf16_len contains the length, *not* including the terminating null. */
126  utf16_buffer[utf16_len] = L'\0';
127 
128  /* Convert to UTF-8 */
129  utf8_len = WideCharToMultiByte(CP_UTF8,
130  0,
131  utf16_buffer,
132  -1,
133  buffer,
134  (int) *size_ptr,
135  NULL,
136  NULL);
137  if (utf8_len == 0) {
138  err = GetLastError();
139  goto error;
140  }
141 
142  uv__free(utf16_buffer);
143 
144  /* utf8_len *does* include the terminating null at this point, but the
145  * returned size shouldn't. */
146  *size_ptr = utf8_len - 1;
147  return 0;
148 
149  error:
150  uv__free(utf16_buffer);
151  return uv_translate_sys_error(err);
152 }
153 
154 
155 int uv_cwd(char* buffer, size_t* size) {
156  DWORD utf16_len;
157  WCHAR utf16_buffer[MAX_PATH];
158  int r;
159 
160  if (buffer == NULL || size == NULL) {
161  return UV_EINVAL;
162  }
163 
164  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
165  if (utf16_len == 0) {
166  return uv_translate_sys_error(GetLastError());
167  } else if (utf16_len > MAX_PATH) {
168  /* This should be impossible; however the CRT has a code path to deal with
169  * this scenario, so I added a check anyway. */
170  return UV_EIO;
171  }
172 
173  /* utf16_len contains the length, *not* including the terminating null. */
174  utf16_buffer[utf16_len] = L'\0';
175 
176  /* The returned directory should not have a trailing slash, unless it points
177  * at a drive root, like c:\. Remove it if needed. */
178  if (utf16_buffer[utf16_len - 1] == L'\\' &&
179  !(utf16_len == 3 && utf16_buffer[1] == L':')) {
180  utf16_len--;
181  utf16_buffer[utf16_len] = L'\0';
182  }
183 
184  /* Check how much space we need */
185  r = WideCharToMultiByte(CP_UTF8,
186  0,
187  utf16_buffer,
188  -1,
189  NULL,
190  0,
191  NULL,
192  NULL);
193  if (r == 0) {
194  return uv_translate_sys_error(GetLastError());
195  } else if (r > (int) *size) {
196  *size = r;
197  return UV_ENOBUFS;
198  }
199 
200  /* Convert to UTF-8 */
201  r = WideCharToMultiByte(CP_UTF8,
202  0,
203  utf16_buffer,
204  -1,
205  buffer,
206  *size > INT_MAX ? INT_MAX : (int) *size,
207  NULL,
208  NULL);
209  if (r == 0) {
210  return uv_translate_sys_error(GetLastError());
211  }
212 
213  *size = r - 1;
214  return 0;
215 }
216 
217 
218 int uv_chdir(const char* dir) {
219  WCHAR utf16_buffer[MAX_PATH];
220  size_t utf16_len;
221  WCHAR drive_letter, env_var[4];
222 
223  if (dir == NULL) {
224  return UV_EINVAL;
225  }
226 
227  if (MultiByteToWideChar(CP_UTF8,
228  0,
229  dir,
230  -1,
231  utf16_buffer,
232  MAX_PATH) == 0) {
233  DWORD error = GetLastError();
234  /* The maximum length of the current working directory is 260 chars,
235  * including terminating null. If it doesn't fit, the path name must be too
236  * long. */
237  if (error == ERROR_INSUFFICIENT_BUFFER) {
238  return UV_ENAMETOOLONG;
239  } else {
241  }
242  }
243 
244  if (!SetCurrentDirectoryW(utf16_buffer)) {
245  return uv_translate_sys_error(GetLastError());
246  }
247 
248  /* Windows stores the drive-local path in an "hidden" environment variable,
249  * which has the form "=C:=C:\Windows". SetCurrentDirectory does not update
250  * this, so we'll have to do it. */
251  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
252  if (utf16_len == 0) {
253  return uv_translate_sys_error(GetLastError());
254  } else if (utf16_len > MAX_PATH) {
255  return UV_EIO;
256  }
257 
258  /* The returned directory should not have a trailing slash, unless it points
259  * at a drive root, like c:\. Remove it if needed. */
260  if (utf16_buffer[utf16_len - 1] == L'\\' &&
261  !(utf16_len == 3 && utf16_buffer[1] == L':')) {
262  utf16_len--;
263  utf16_buffer[utf16_len] = L'\0';
264  }
265 
266  if (utf16_len < 2 || utf16_buffer[1] != L':') {
267  /* Doesn't look like a drive letter could be there - probably an UNC path.
268  * TODO: Need to handle win32 namespaces like \\?\C:\ ? */
269  drive_letter = 0;
270  } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') {
271  drive_letter = utf16_buffer[0];
272  } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') {
273  /* Convert to uppercase. */
274  drive_letter = utf16_buffer[0] - L'a' + L'A';
275  } else {
276  /* Not valid. */
277  drive_letter = 0;
278  }
279 
280  if (drive_letter != 0) {
281  /* Construct the environment variable name and set it. */
282  env_var[0] = L'=';
283  env_var[1] = drive_letter;
284  env_var[2] = L':';
285  env_var[3] = L'\0';
286 
287  if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
288  return uv_translate_sys_error(GetLastError());
289  }
290  }
291 
292  return 0;
293 }
294 
295 
296 void uv_loadavg(double avg[3]) {
297  /* Can't be implemented */
298  avg[0] = avg[1] = avg[2] = 0;
299 }
300 
301 
303  MEMORYSTATUSEX memory_status;
304  memory_status.dwLength = sizeof(memory_status);
305 
306  if (!GlobalMemoryStatusEx(&memory_status)) {
307  return -1;
308  }
309 
310  return (uint64_t)memory_status.ullAvailPhys;
311 }
312 
313 
315  MEMORYSTATUSEX memory_status;
316  memory_status.dwLength = sizeof(memory_status);
317 
318  if (!GlobalMemoryStatusEx(&memory_status)) {
319  return -1;
320  }
321 
322  return (uint64_t)memory_status.ullTotalPhys;
323 }
324 
325 
327  return 0; /* Memory constraints are unknown. */
328 }
329 
330 
332  return GetCurrentProcessId();
333 }
334 
335 
337  int parent_pid = -1;
338  HANDLE handle;
339  PROCESSENTRY32 pe;
340  DWORD current_pid = GetCurrentProcessId();
341 
342  pe.dwSize = sizeof(PROCESSENTRY32);
343  handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
344 
345  if (Process32First(handle, &pe)) {
346  do {
347  if (pe.th32ProcessID == current_pid) {
348  parent_pid = pe.th32ParentProcessID;
349  break;
350  }
351  } while( Process32Next(handle, &pe));
352  }
353 
354  CloseHandle(handle);
355  return parent_pid;
356 }
357 
358 
359 char** uv_setup_args(int argc, char** argv) {
360  return argv;
361 }
362 
363 
364 int uv_set_process_title(const char* title) {
365  int err;
366  int length;
367  WCHAR* title_w = NULL;
368 
369  uv__once_init();
370 
371  /* Find out how big the buffer for the wide-char title must be */
372  length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
373  if (!length) {
374  err = GetLastError();
375  goto done;
376  }
377 
378  /* Convert to wide-char string */
379  title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length);
380  if (!title_w) {
381  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
382  }
383 
384  length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length);
385  if (!length) {
386  err = GetLastError();
387  goto done;
388  }
389 
390  /* If the title must be truncated insert a \0 terminator there */
391  if (length > MAX_TITLE_LENGTH) {
392  title_w[MAX_TITLE_LENGTH - 1] = L'\0';
393  }
394 
395  if (!SetConsoleTitleW(title_w)) {
396  err = GetLastError();
397  goto done;
398  }
399 
400  EnterCriticalSection(&process_title_lock);
402  process_title = uv__strdup(title);
403  LeaveCriticalSection(&process_title_lock);
404 
405  err = 0;
406 
407 done:
408  uv__free(title_w);
409  return uv_translate_sys_error(err);
410 }
411 
412 
413 static int uv__get_process_title(void) {
414  WCHAR title_w[MAX_TITLE_LENGTH];
415 
416  if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
417  return -1;
418  }
419 
420  if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0)
421  return -1;
422 
423  return 0;
424 }
425 
426 
427 int uv_get_process_title(char* buffer, size_t size) {
428  size_t len;
429 
430  if (buffer == NULL || size == 0)
431  return UV_EINVAL;
432 
433  uv__once_init();
434 
435  EnterCriticalSection(&process_title_lock);
436  /*
437  * If the process_title was never read before nor explicitly set,
438  * we must query it with getConsoleTitleW
439  */
440  if (!process_title && uv__get_process_title() == -1) {
441  LeaveCriticalSection(&process_title_lock);
442  return uv_translate_sys_error(GetLastError());
443  }
444 
445  assert(process_title);
446  len = strlen(process_title) + 1;
447 
448  if (size < len) {
449  LeaveCriticalSection(&process_title_lock);
450  return UV_ENOBUFS;
451  }
452 
454  LeaveCriticalSection(&process_title_lock);
455 
456  return 0;
457 }
458 
459 
461  uv__once_init();
462  return uv__hrtime(UV__NANOSEC);
463 }
464 
466  LARGE_INTEGER counter;
467 
468  /* If the performance interval is zero, there's no support. */
469  if (hrtime_interval_ == 0) {
470  return 0;
471  }
472 
473  if (!QueryPerformanceCounter(&counter)) {
474  return 0;
475  }
476 
477  /* Because we have no guarantee about the order of magnitude of the
478  * performance counter interval, integer math could cause this computation
479  * to overflow. Therefore we resort to floating point math.
480  */
481  return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
482 }
483 
484 
485 int uv_resident_set_memory(size_t* rss) {
486  HANDLE current_process;
487  PROCESS_MEMORY_COUNTERS pmc;
488 
489  current_process = GetCurrentProcess();
490 
491  if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) {
492  return uv_translate_sys_error(GetLastError());
493  }
494 
495  *rss = pmc.WorkingSetSize;
496 
497  return 0;
498 }
499 
500 
501 int uv_uptime(double* uptime) {
502  BYTE stack_buffer[4096];
503  BYTE* malloced_buffer = NULL;
504  BYTE* buffer = (BYTE*) stack_buffer;
505  size_t buffer_size = sizeof(stack_buffer);
506  DWORD data_size;
507 
508  PERF_DATA_BLOCK* data_block;
509  PERF_OBJECT_TYPE* object_type;
510  PERF_COUNTER_DEFINITION* counter_definition;
511 
512  DWORD i;
513 
514  for (;;) {
515  LONG result;
516 
517  data_size = (DWORD) buffer_size;
518  result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
519  L"2",
520  NULL,
521  NULL,
522  buffer,
523  &data_size);
524  if (result == ERROR_SUCCESS) {
525  break;
526  } else if (result != ERROR_MORE_DATA) {
527  *uptime = 0;
529  }
530 
531  buffer_size *= 2;
532  /* Don't let the buffer grow infinitely. */
533  if (buffer_size > 1 << 20) {
534  goto internalError;
535  }
536 
537  uv__free(malloced_buffer);
538 
539  buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size);
540  if (malloced_buffer == NULL) {
541  *uptime = 0;
542  return UV_ENOMEM;
543  }
544  }
545 
546  if (data_size < sizeof(*data_block))
547  goto internalError;
548 
549  data_block = (PERF_DATA_BLOCK*) buffer;
550 
551  if (wmemcmp(data_block->Signature, L"PERF", 4) != 0)
552  goto internalError;
553 
554  if (data_size < data_block->HeaderLength + sizeof(*object_type))
555  goto internalError;
556 
557  object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength);
558 
559  if (object_type->NumInstances != PERF_NO_INSTANCES)
560  goto internalError;
561 
562  counter_definition = (PERF_COUNTER_DEFINITION*) (buffer +
563  data_block->HeaderLength + object_type->HeaderLength);
564  for (i = 0; i < object_type->NumCounters; i++) {
565  if ((BYTE*) counter_definition + sizeof(*counter_definition) >
566  buffer + data_size) {
567  break;
568  }
569 
570  if (counter_definition->CounterNameTitleIndex == 674 &&
571  counter_definition->CounterSize == sizeof(uint64_t)) {
572  if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size ||
573  !(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
574  goto internalError;
575  } else {
576  BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
577  counter_definition->CounterOffset;
578  uint64_t value = *((uint64_t*) address);
579  *uptime = floor((double) (object_type->PerfTime.QuadPart - value) /
580  (double) object_type->PerfFreq.QuadPart);
581  uv__free(malloced_buffer);
582  return 0;
583  }
584  }
585 
586  counter_definition = (PERF_COUNTER_DEFINITION*)
587  ((BYTE*) counter_definition + counter_definition->ByteLength);
588  }
589 
590  /* If we get here, the uptime value was not found. */
591  uv__free(malloced_buffer);
592  *uptime = 0;
593  return UV_ENOSYS;
594 
595  internalError:
596  uv__free(malloced_buffer);
597  *uptime = 0;
598  return UV_EIO;
599 }
600 
601 
602 int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
603  uv_cpu_info_t* cpu_infos;
605  DWORD sppi_size;
606  SYSTEM_INFO system_info;
607  DWORD cpu_count, i;
609  ULONG result_size;
610  int err;
611  uv_cpu_info_t* cpu_info;
612 
613  cpu_infos = NULL;
614  cpu_count = 0;
615  sppi = NULL;
616 
617  uv__once_init();
618 
619  GetSystemInfo(&system_info);
620  cpu_count = system_info.dwNumberOfProcessors;
621 
622  cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos);
623  if (cpu_infos == NULL) {
624  err = ERROR_OUTOFMEMORY;
625  goto error;
626  }
627 
628  sppi_size = cpu_count * sizeof(*sppi);
629  sppi = uv__malloc(sppi_size);
630  if (sppi == NULL) {
631  err = ERROR_OUTOFMEMORY;
632  goto error;
633  }
634 
636  sppi,
637  sppi_size,
638  &result_size);
639  if (!NT_SUCCESS(status)) {
641  goto error;
642  }
643 
644  assert(result_size == sppi_size);
645 
646  for (i = 0; i < cpu_count; i++) {
647  WCHAR key_name[128];
648  HKEY processor_key;
649  DWORD cpu_speed;
650  DWORD cpu_speed_size = sizeof(cpu_speed);
651  WCHAR cpu_brand[256];
652  DWORD cpu_brand_size = sizeof(cpu_brand);
653  size_t len;
654 
655  len = _snwprintf(key_name,
656  ARRAY_SIZE(key_name),
657  L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
658  i);
659 
660  assert(len > 0 && len < ARRAY_SIZE(key_name));
661 
662  err = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
663  key_name,
664  0,
665  KEY_QUERY_VALUE,
666  &processor_key);
667  if (err != ERROR_SUCCESS) {
668  goto error;
669  }
670 
671  err = RegQueryValueExW(processor_key,
672  L"~MHz",
673  NULL,
674  NULL,
675  (BYTE*)&cpu_speed,
676  &cpu_speed_size);
677  if (err != ERROR_SUCCESS) {
678  RegCloseKey(processor_key);
679  goto error;
680  }
681 
682  err = RegQueryValueExW(processor_key,
683  L"ProcessorNameString",
684  NULL,
685  NULL,
686  (BYTE*)&cpu_brand,
687  &cpu_brand_size);
688  RegCloseKey(processor_key);
689  if (err != ERROR_SUCCESS)
690  goto error;
691 
692  cpu_info = &cpu_infos[i];
693  cpu_info->speed = cpu_speed;
694  cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
695  cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
696  sppi[i].IdleTime.QuadPart) / 10000;
697  cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
698  cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
699  cpu_info->cpu_times.nice = 0;
700 
701  uv__convert_utf16_to_utf8(cpu_brand,
702  cpu_brand_size / sizeof(WCHAR),
703  &(cpu_info->model));
704  }
705 
706  uv__free(sppi);
707 
708  *cpu_count_ptr = cpu_count;
709  *cpu_infos_ptr = cpu_infos;
710 
711  return 0;
712 
713  error:
714  if (cpu_infos != NULL) {
715  /* This is safe because the cpu_infos array is zeroed on allocation. */
716  for (i = 0; i < cpu_count; i++)
717  uv__free(cpu_infos[i].model);
718  }
719 
720  uv__free(cpu_infos);
721  uv__free(sppi);
722 
723  return uv_translate_sys_error(err);
724 }
725 
726 
727 static int is_windows_version_or_greater(DWORD os_major,
728  DWORD os_minor,
729  WORD service_pack_major,
730  WORD service_pack_minor) {
731  OSVERSIONINFOEX osvi;
732  DWORDLONG condition_mask = 0;
733  int op = VER_GREATER_EQUAL;
734 
735  /* Initialize the OSVERSIONINFOEX structure. */
736  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
737  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
738  osvi.dwMajorVersion = os_major;
739  osvi.dwMinorVersion = os_minor;
740  osvi.wServicePackMajor = service_pack_major;
741  osvi.wServicePackMinor = service_pack_minor;
742 
743  /* Initialize the condition mask. */
744  VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op);
745  VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op);
746  VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op);
747  VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op);
748 
749  /* Perform the test. */
750  return (int) VerifyVersionInfo(
751  &osvi,
752  VER_MAJORVERSION | VER_MINORVERSION |
753  VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
754  condition_mask);
755 }
756 
757 
758 static int address_prefix_match(int family,
759  struct sockaddr* address,
760  struct sockaddr* prefix_address,
761  int prefix_len) {
762  uint8_t* address_data;
763  uint8_t* prefix_address_data;
764  int i;
765 
766  assert(address->sa_family == family);
767  assert(prefix_address->sa_family == family);
768 
769  if (family == AF_INET6) {
770  address_data = (uint8_t*) &(((struct sockaddr_in6 *) address)->sin6_addr);
771  prefix_address_data =
772  (uint8_t*) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr);
773  } else {
774  address_data = (uint8_t*) &(((struct sockaddr_in *) address)->sin_addr);
775  prefix_address_data =
776  (uint8_t*) &(((struct sockaddr_in *) prefix_address)->sin_addr);
777  }
778 
779  for (i = 0; i < prefix_len >> 3; i++) {
780  if (address_data[i] != prefix_address_data[i])
781  return 0;
782  }
783 
784  if (prefix_len % 8)
785  return prefix_address_data[i] ==
786  (address_data[i] & (0xff << (8 - prefix_len % 8)));
787 
788  return 1;
789 }
790 
791 
793  int* count_ptr) {
794  IP_ADAPTER_ADDRESSES* win_address_buf;
795  ULONG win_address_buf_size;
796  IP_ADAPTER_ADDRESSES* adapter;
797 
798  uv_interface_address_t* uv_address_buf;
799  char* name_buf;
800  size_t uv_address_buf_size;
801  uv_interface_address_t* uv_address;
802 
803  int count;
804 
805  int is_vista_or_greater;
806  ULONG flags;
807 
808  *addresses_ptr = NULL;
809  *count_ptr = 0;
810 
811  is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0);
812  if (is_vista_or_greater) {
813  flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
814  GAA_FLAG_SKIP_DNS_SERVER;
815  } else {
816  /* We need at least XP SP1. */
817  if (!is_windows_version_or_greater(5, 1, 1, 0))
818  return UV_ENOTSUP;
819 
820  flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
821  GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX;
822  }
823 
824 
825  /* Fetch the size of the adapters reported by windows, and then get the list
826  * itself. */
827  win_address_buf_size = 0;
828  win_address_buf = NULL;
829 
830  for (;;) {
831  ULONG r;
832 
833  /* If win_address_buf is 0, then GetAdaptersAddresses will fail with.
834  * ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in
835  * win_address_buf_size. */
836  r = GetAdaptersAddresses(AF_UNSPEC,
837  flags,
838  NULL,
839  win_address_buf,
840  &win_address_buf_size);
841 
842  if (r == ERROR_SUCCESS)
843  break;
844 
845  uv__free(win_address_buf);
846 
847  switch (r) {
848  case ERROR_BUFFER_OVERFLOW:
849  /* This happens when win_address_buf is NULL or too small to hold all
850  * adapters. */
851  win_address_buf = uv__malloc(win_address_buf_size);
852  if (win_address_buf == NULL)
853  return UV_ENOMEM;
854 
855  continue;
856 
857  case ERROR_NO_DATA: {
858  /* No adapters were found. */
859  uv_address_buf = uv__malloc(1);
860  if (uv_address_buf == NULL)
861  return UV_ENOMEM;
862 
863  *count_ptr = 0;
864  *addresses_ptr = uv_address_buf;
865 
866  return 0;
867  }
868 
869  case ERROR_ADDRESS_NOT_ASSOCIATED:
870  return UV_EAGAIN;
871 
872  case ERROR_INVALID_PARAMETER:
873  /* MSDN says:
874  * "This error is returned for any of the following conditions: the
875  * SizePointer parameter is NULL, the Address parameter is not
876  * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for
877  * the parameters requested is greater than ULONG_MAX."
878  * Since the first two conditions are not met, it must be that the
879  * adapter data is too big.
880  */
881  return UV_ENOBUFS;
882 
883  default:
884  /* Other (unspecified) errors can happen, but we don't have any special
885  * meaning for them. */
886  assert(r != ERROR_SUCCESS);
887  return uv_translate_sys_error(r);
888  }
889  }
890 
891  /* Count the number of enabled interfaces and compute how much space is
892  * needed to store their info. */
893  count = 0;
894  uv_address_buf_size = 0;
895 
896  for (adapter = win_address_buf;
897  adapter != NULL;
898  adapter = adapter->Next) {
899  IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
900  int name_size;
901 
902  /* Interfaces that are not 'up' should not be reported. Also skip
903  * interfaces that have no associated unicast address, as to avoid
904  * allocating space for the name for this interface. */
905  if (adapter->OperStatus != IfOperStatusUp ||
906  adapter->FirstUnicastAddress == NULL)
907  continue;
908 
909  /* Compute the size of the interface name. */
910  name_size = WideCharToMultiByte(CP_UTF8,
911  0,
912  adapter->FriendlyName,
913  -1,
914  NULL,
915  0,
916  NULL,
917  FALSE);
918  if (name_size <= 0) {
919  uv__free(win_address_buf);
920  return uv_translate_sys_error(GetLastError());
921  }
922  uv_address_buf_size += name_size;
923 
924  /* Count the number of addresses associated with this interface, and
925  * compute the size. */
926  for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
927  adapter->FirstUnicastAddress;
928  unicast_address != NULL;
929  unicast_address = unicast_address->Next) {
930  count++;
931  uv_address_buf_size += sizeof(uv_interface_address_t);
932  }
933  }
934 
935  /* Allocate space to store interface data plus adapter names. */
936  uv_address_buf = uv__malloc(uv_address_buf_size);
937  if (uv_address_buf == NULL) {
938  uv__free(win_address_buf);
939  return UV_ENOMEM;
940  }
941 
942  /* Compute the start of the uv_interface_address_t array, and the place in
943  * the buffer where the interface names will be stored. */
944  uv_address = uv_address_buf;
945  name_buf = (char*) (uv_address_buf + count);
946 
947  /* Fill out the output buffer. */
948  for (adapter = win_address_buf;
949  adapter != NULL;
950  adapter = adapter->Next) {
951  IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
952  int name_size;
953  size_t max_name_size;
954 
955  if (adapter->OperStatus != IfOperStatusUp ||
956  adapter->FirstUnicastAddress == NULL)
957  continue;
958 
959  /* Convert the interface name to UTF8. */
960  max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf;
961  if (max_name_size > (size_t) INT_MAX)
962  max_name_size = INT_MAX;
963  name_size = WideCharToMultiByte(CP_UTF8,
964  0,
965  adapter->FriendlyName,
966  -1,
967  name_buf,
968  (int) max_name_size,
969  NULL,
970  FALSE);
971  if (name_size <= 0) {
972  uv__free(win_address_buf);
973  uv__free(uv_address_buf);
974  return uv_translate_sys_error(GetLastError());
975  }
976 
977  /* Add an uv_interface_address_t element for every unicast address. */
978  for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
979  adapter->FirstUnicastAddress;
980  unicast_address != NULL;
981  unicast_address = unicast_address->Next) {
982  struct sockaddr* sa;
983  ULONG prefix_len;
984 
985  sa = unicast_address->Address.lpSockaddr;
986 
987  /* XP has no OnLinkPrefixLength field. */
988  if (is_vista_or_greater) {
989  prefix_len =
990  ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength;
991  } else {
992  /* Prior to Windows Vista the FirstPrefix pointed to the list with
993  * single prefix for each IP address assigned to the adapter.
994  * Order of FirstPrefix does not match order of FirstUnicastAddress,
995  * so we need to find corresponding prefix.
996  */
997  IP_ADAPTER_PREFIX* prefix;
998  prefix_len = 0;
999 
1000  for (prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) {
1001  /* We want the longest matching prefix. */
1002  if (prefix->Address.lpSockaddr->sa_family != sa->sa_family ||
1003  prefix->PrefixLength <= prefix_len)
1004  continue;
1005 
1006  if (address_prefix_match(sa->sa_family, sa,
1007  prefix->Address.lpSockaddr, prefix->PrefixLength)) {
1008  prefix_len = prefix->PrefixLength;
1009  }
1010  }
1011 
1012  /* If there is no matching prefix information, return a single-host
1013  * subnet mask (e.g. 255.255.255.255 for IPv4).
1014  */
1015  if (!prefix_len)
1016  prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32;
1017  }
1018 
1019  memset(uv_address, 0, sizeof *uv_address);
1020 
1021  uv_address->name = name_buf;
1022 
1023  if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) {
1024  memcpy(uv_address->phys_addr,
1025  adapter->PhysicalAddress,
1026  sizeof(uv_address->phys_addr));
1027  }
1028 
1029  uv_address->is_internal =
1030  (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
1031 
1032  if (sa->sa_family == AF_INET6) {
1033  uv_address->address.address6 = *((struct sockaddr_in6 *) sa);
1034 
1035  uv_address->netmask.netmask6.sin6_family = AF_INET6;
1036  memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3);
1037  /* This check ensures that we don't write past the size of the data. */
1038  if (prefix_len % 8) {
1039  uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] =
1040  0xff << (8 - prefix_len % 8);
1041  }
1042 
1043  } else {
1044  uv_address->address.address4 = *((struct sockaddr_in *) sa);
1045 
1046  uv_address->netmask.netmask4.sin_family = AF_INET;
1047  uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ?
1048  htonl(0xffffffff << (32 - prefix_len)) : 0;
1049  }
1050 
1051  uv_address++;
1052  }
1053 
1054  name_buf += name_size;
1055  }
1056 
1057  uv__free(win_address_buf);
1058 
1059  *addresses_ptr = uv_address_buf;
1060  *count_ptr = count;
1061 
1062  return 0;
1063 }
1064 
1065 
1067  int count) {
1068  uv__free(addresses);
1069 }
1070 
1071 
1072 int uv_getrusage(uv_rusage_t *uv_rusage) {
1073  FILETIME createTime, exitTime, kernelTime, userTime;
1074  SYSTEMTIME kernelSystemTime, userSystemTime;
1075  PROCESS_MEMORY_COUNTERS memCounters;
1076  IO_COUNTERS ioCounters;
1077  int ret;
1078 
1079  ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
1080  if (ret == 0) {
1081  return uv_translate_sys_error(GetLastError());
1082  }
1083 
1084  ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime);
1085  if (ret == 0) {
1086  return uv_translate_sys_error(GetLastError());
1087  }
1088 
1089  ret = FileTimeToSystemTime(&userTime, &userSystemTime);
1090  if (ret == 0) {
1091  return uv_translate_sys_error(GetLastError());
1092  }
1093 
1094  ret = GetProcessMemoryInfo(GetCurrentProcess(),
1095  &memCounters,
1096  sizeof(memCounters));
1097  if (ret == 0) {
1098  return uv_translate_sys_error(GetLastError());
1099  }
1100 
1101  ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
1102  if (ret == 0) {
1103  return uv_translate_sys_error(GetLastError());
1104  }
1105 
1106  memset(uv_rusage, 0, sizeof(*uv_rusage));
1107 
1108  uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
1109  userSystemTime.wMinute * 60 +
1110  userSystemTime.wSecond;
1111  uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000;
1112 
1113  uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 +
1114  kernelSystemTime.wMinute * 60 +
1115  kernelSystemTime.wSecond;
1116  uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
1117 
1118  uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
1119  uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
1120 
1121  uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount;
1122  uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount;
1123 
1124  return 0;
1125 }
1126 
1127 
1128 int uv_os_homedir(char* buffer, size_t* size) {
1129  uv_passwd_t pwd;
1130  size_t len;
1131  int r;
1132 
1133  /* Check if the USERPROFILE environment variable is set first. The task of
1134  performing input validation on buffer and size is taken care of by
1135  uv_os_getenv(). */
1136  r = uv_os_getenv("USERPROFILE", buffer, size);
1137 
1138  /* Don't return an error if USERPROFILE was not found. */
1139  if (r != UV_ENOENT)
1140  return r;
1141 
1142  /* USERPROFILE is not set, so call uv__getpwuid_r() */
1143  r = uv__getpwuid_r(&pwd);
1144 
1145  if (r != 0) {
1146  return r;
1147  }
1148 
1149  len = strlen(pwd.homedir);
1150 
1151  if (len >= *size) {
1152  *size = len + 1;
1153  uv_os_free_passwd(&pwd);
1154  return UV_ENOBUFS;
1155  }
1156 
1157  memcpy(buffer, pwd.homedir, len + 1);
1158  *size = len;
1159  uv_os_free_passwd(&pwd);
1160 
1161  return 0;
1162 }
1163 
1164 
1165 int uv_os_tmpdir(char* buffer, size_t* size) {
1166  wchar_t path[MAX_PATH + 2];
1167  DWORD bufsize;
1168  size_t len;
1169 
1170  if (buffer == NULL || size == NULL || *size == 0)
1171  return UV_EINVAL;
1172 
1173  len = GetTempPathW(ARRAY_SIZE(path), path);
1174 
1175  if (len == 0) {
1176  return uv_translate_sys_error(GetLastError());
1177  } else if (len > ARRAY_SIZE(path)) {
1178  /* This should not be possible */
1179  return UV_EIO;
1180  }
1181 
1182  /* The returned directory should not have a trailing slash, unless it points
1183  * at a drive root, like c:\. Remove it if needed. */
1184  if (path[len - 1] == L'\\' &&
1185  !(len == 3 && path[1] == L':')) {
1186  len--;
1187  path[len] = L'\0';
1188  }
1189 
1190  /* Check how much space we need */
1191  bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
1192 
1193  if (bufsize == 0) {
1194  return uv_translate_sys_error(GetLastError());
1195  } else if (bufsize > *size) {
1196  *size = bufsize;
1197  return UV_ENOBUFS;
1198  }
1199 
1200  /* Convert to UTF-8 */
1201  bufsize = WideCharToMultiByte(CP_UTF8,
1202  0,
1203  path,
1204  -1,
1205  buffer,
1206  *size,
1207  NULL,
1208  NULL);
1209 
1210  if (bufsize == 0)
1211  return uv_translate_sys_error(GetLastError());
1212 
1213  *size = bufsize - 1;
1214  return 0;
1215 }
1216 
1217 
1219  if (pwd == NULL)
1220  return;
1221 
1222  uv__free(pwd->username);
1223  uv__free(pwd->homedir);
1224  pwd->username = NULL;
1225  pwd->homedir = NULL;
1226 }
1227 
1228 
1229 /*
1230  * Converts a UTF-16 string into a UTF-8 one. The resulting string is
1231  * null-terminated.
1232  *
1233  * If utf16 is null terminated, utf16len can be set to -1, otherwise it must
1234  * be specified.
1235  */
1236 int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
1237  DWORD bufsize;
1238 
1239  if (utf16 == NULL)
1240  return UV_EINVAL;
1241 
1242  /* Check how much space we need */
1243  bufsize = WideCharToMultiByte(CP_UTF8,
1244  0,
1245  utf16,
1246  utf16len,
1247  NULL,
1248  0,
1249  NULL,
1250  NULL);
1251 
1252  if (bufsize == 0)
1253  return uv_translate_sys_error(GetLastError());
1254 
1255  /* Allocate the destination buffer adding an extra byte for the terminating
1256  * NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so
1257  * we do it ourselves always, just in case. */
1258  *utf8 = uv__malloc(bufsize + 1);
1259 
1260  if (*utf8 == NULL)
1261  return UV_ENOMEM;
1262 
1263  /* Convert to UTF-8 */
1264  bufsize = WideCharToMultiByte(CP_UTF8,
1265  0,
1266  utf16,
1267  utf16len,
1268  *utf8,
1269  bufsize,
1270  NULL,
1271  NULL);
1272 
1273  if (bufsize == 0) {
1274  uv__free(*utf8);
1275  *utf8 = NULL;
1276  return uv_translate_sys_error(GetLastError());
1277  }
1278 
1279  (*utf8)[bufsize] = '\0';
1280  return 0;
1281 }
1282 
1283 
1284 /*
1285  * Converts a UTF-8 string into a UTF-16 one. The resulting string is
1286  * null-terminated.
1287  *
1288  * If utf8 is null terminated, utf8len can be set to -1, otherwise it must
1289  * be specified.
1290  */
1291 int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
1292  int bufsize;
1293 
1294  if (utf8 == NULL)
1295  return UV_EINVAL;
1296 
1297  /* Check how much space we need */
1298  bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0);
1299 
1300  if (bufsize == 0)
1301  return uv_translate_sys_error(GetLastError());
1302 
1303  /* Allocate the destination buffer adding an extra byte for the terminating
1304  * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so
1305  * we do it ourselves always, just in case. */
1306  *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1));
1307 
1308  if (*utf16 == NULL)
1309  return UV_ENOMEM;
1310 
1311  /* Convert to UTF-16 */
1312  bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
1313 
1314  if (bufsize == 0) {
1315  uv__free(*utf16);
1316  *utf16 = NULL;
1317  return uv_translate_sys_error(GetLastError());
1318  }
1319 
1320  (*utf16)[bufsize] = L'\0';
1321  return 0;
1322 }
1323 
1324 
1326  HANDLE token;
1327  wchar_t username[UNLEN + 1];
1328  wchar_t path[MAX_PATH];
1329  DWORD bufsize;
1330  int r;
1331 
1332  if (pwd == NULL)
1333  return UV_EINVAL;
1334 
1335  /* Get the home directory using GetUserProfileDirectoryW() */
1336  if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
1337  return uv_translate_sys_error(GetLastError());
1338 
1339  bufsize = ARRAY_SIZE(path);
1340  if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
1341  r = GetLastError();
1342  CloseHandle(token);
1343 
1344  /* This should not be possible */
1345  if (r == ERROR_INSUFFICIENT_BUFFER)
1346  return UV_ENOMEM;
1347 
1348  return uv_translate_sys_error(r);
1349  }
1350 
1351  CloseHandle(token);
1352 
1353  /* Get the username using GetUserNameW() */
1354  bufsize = ARRAY_SIZE(username);
1355  if (!GetUserNameW(username, &bufsize)) {
1356  r = GetLastError();
1357 
1358  /* This should not be possible */
1359  if (r == ERROR_INSUFFICIENT_BUFFER)
1360  return UV_ENOMEM;
1361 
1362  return uv_translate_sys_error(r);
1363  }
1364 
1365  pwd->homedir = NULL;
1366  r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
1367 
1368  if (r != 0)
1369  return r;
1370 
1371  pwd->username = NULL;
1372  r = uv__convert_utf16_to_utf8(username, -1, &pwd->username);
1373 
1374  if (r != 0) {
1375  uv__free(pwd->homedir);
1376  return r;
1377  }
1378 
1379  pwd->shell = NULL;
1380  pwd->uid = -1;
1381  pwd->gid = -1;
1382 
1383  return 0;
1384 }
1385 
1386 
1388  return uv__getpwuid_r(pwd);
1389 }
1390 
1391 
1392 int uv_os_environ(uv_env_item_t** envitems, int* count) {
1393  wchar_t* env;
1394  wchar_t* penv;
1395  int i, cnt;
1396  uv_env_item_t* envitem;
1397 
1398  *envitems = NULL;
1399  *count = 0;
1400 
1401  env = GetEnvironmentStringsW();
1402  if (env == NULL)
1403  return 0;
1404 
1405  for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++);
1406 
1407  *envitems = uv__calloc(i, sizeof(**envitems));
1408  if (*envitems == NULL) {
1409  FreeEnvironmentStringsW(env);
1410  return UV_ENOMEM;
1411  }
1412 
1413  penv = env;
1414  cnt = 0;
1415 
1416  while (*penv != L'\0' && cnt < i) {
1417  char* buf;
1418  char* ptr;
1419 
1420  if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0)
1421  goto fail;
1422 
1423  /* Using buf + 1 here because we know that `buf` has length at least 1,
1424  * and some special environment variables on Windows start with a = sign. */
1425  ptr = strchr(buf + 1, '=');
1426  if (ptr == NULL) {
1427  uv__free(buf);
1428  goto do_continue;
1429  }
1430 
1431  *ptr = '\0';
1432 
1433  envitem = &(*envitems)[cnt];
1434  envitem->name = buf;
1435  envitem->value = ptr + 1;
1436 
1437  cnt++;
1438 
1439  do_continue:
1440  penv += wcslen(penv) + 1;
1441  }
1442 
1443  FreeEnvironmentStringsW(env);
1444 
1445  *count = cnt;
1446  return 0;
1447 
1448 fail:
1449  FreeEnvironmentStringsW(env);
1450 
1451  for (i = 0; i < cnt; i++) {
1452  envitem = &(*envitems)[cnt];
1453  uv__free(envitem->name);
1454  }
1455  uv__free(*envitems);
1456 
1457  *envitems = NULL;
1458  *count = 0;
1459  return UV_ENOMEM;
1460 }
1461 
1462 
1463 int uv_os_getenv(const char* name, char* buffer, size_t* size) {
1464  wchar_t var[MAX_ENV_VAR_LENGTH];
1465  wchar_t* name_w;
1466  DWORD bufsize;
1467  size_t len;
1468  int r;
1469 
1470  if (name == NULL || buffer == NULL || size == NULL || *size == 0)
1471  return UV_EINVAL;
1472 
1473  r = uv__convert_utf8_to_utf16(name, -1, &name_w);
1474 
1475  if (r != 0)
1476  return r;
1477 
1478  SetLastError(ERROR_SUCCESS);
1479  len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
1480  uv__free(name_w);
1481  assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
1482 
1483  if (len == 0) {
1484  r = GetLastError();
1485  if (r != ERROR_SUCCESS)
1486  return uv_translate_sys_error(r);
1487  }
1488 
1489  /* Check how much space we need */
1490  bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
1491 
1492  if (bufsize == 0) {
1493  return uv_translate_sys_error(GetLastError());
1494  } else if (bufsize > *size) {
1495  *size = bufsize;
1496  return UV_ENOBUFS;
1497  }
1498 
1499  /* Convert to UTF-8 */
1500  bufsize = WideCharToMultiByte(CP_UTF8,
1501  0,
1502  var,
1503  -1,
1504  buffer,
1505  *size,
1506  NULL,
1507  NULL);
1508 
1509  if (bufsize == 0)
1510  return uv_translate_sys_error(GetLastError());
1511 
1512  *size = bufsize - 1;
1513  return 0;
1514 }
1515 
1516 
1517 int uv_os_setenv(const char* name, const char* value) {
1518  wchar_t* name_w;
1519  wchar_t* value_w;
1520  int r;
1521 
1522  if (name == NULL || value == NULL)
1523  return UV_EINVAL;
1524 
1525  r = uv__convert_utf8_to_utf16(name, -1, &name_w);
1526 
1527  if (r != 0)
1528  return r;
1529 
1530  r = uv__convert_utf8_to_utf16(value, -1, &value_w);
1531 
1532  if (r != 0) {
1533  uv__free(name_w);
1534  return r;
1535  }
1536 
1537  r = SetEnvironmentVariableW(name_w, value_w);
1538  uv__free(name_w);
1539  uv__free(value_w);
1540 
1541  if (r == 0)
1542  return uv_translate_sys_error(GetLastError());
1543 
1544  return 0;
1545 }
1546 
1547 
1548 int uv_os_unsetenv(const char* name) {
1549  wchar_t* name_w;
1550  int r;
1551 
1552  if (name == NULL)
1553  return UV_EINVAL;
1554 
1555  r = uv__convert_utf8_to_utf16(name, -1, &name_w);
1556 
1557  if (r != 0)
1558  return r;
1559 
1560  r = SetEnvironmentVariableW(name_w, NULL);
1561  uv__free(name_w);
1562 
1563  if (r == 0)
1564  return uv_translate_sys_error(GetLastError());
1565 
1566  return 0;
1567 }
1568 
1569 
1570 int uv_os_gethostname(char* buffer, size_t* size) {
1571  char buf[UV_MAXHOSTNAMESIZE];
1572  size_t len;
1573 
1574  if (buffer == NULL || size == NULL || *size == 0)
1575  return UV_EINVAL;
1576 
1577  uv__once_init(); /* Initialize winsock */
1578 
1579  if (gethostname(buf, sizeof(buf)) != 0)
1580  return uv_translate_sys_error(WSAGetLastError());
1581 
1582  buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
1583  len = strlen(buf);
1584 
1585  if (len >= *size) {
1586  *size = len + 1;
1587  return UV_ENOBUFS;
1588  }
1589 
1590  memcpy(buffer, buf, len + 1);
1591  *size = len;
1592  return 0;
1593 }
1594 
1595 
1596 static int uv__get_handle(uv_pid_t pid, int access, HANDLE* handle) {
1597  int r;
1598 
1599  if (pid == 0)
1600  *handle = GetCurrentProcess();
1601  else
1602  *handle = OpenProcess(access, FALSE, pid);
1603 
1604  if (*handle == NULL) {
1605  r = GetLastError();
1606 
1607  if (r == ERROR_INVALID_PARAMETER)
1608  return UV_ESRCH;
1609  else
1610  return uv_translate_sys_error(r);
1611  }
1612 
1613  return 0;
1614 }
1615 
1616 
1618  HANDLE handle;
1619  int r;
1620 
1621  if (priority == NULL)
1622  return UV_EINVAL;
1623 
1624  r = uv__get_handle(pid, PROCESS_QUERY_LIMITED_INFORMATION, &handle);
1625 
1626  if (r != 0)
1627  return r;
1628 
1629  r = GetPriorityClass(handle);
1630 
1631  if (r == 0) {
1632  r = uv_translate_sys_error(GetLastError());
1633  } else {
1634  /* Map Windows priority classes to Unix nice values. */
1635  if (r == REALTIME_PRIORITY_CLASS)
1637  else if (r == HIGH_PRIORITY_CLASS)
1639  else if (r == ABOVE_NORMAL_PRIORITY_CLASS)
1641  else if (r == NORMAL_PRIORITY_CLASS)
1643  else if (r == BELOW_NORMAL_PRIORITY_CLASS)
1645  else /* IDLE_PRIORITY_CLASS */
1647 
1648  r = 0;
1649  }
1650 
1651  CloseHandle(handle);
1652  return r;
1653 }
1654 
1655 
1657  HANDLE handle;
1658  int priority_class;
1659  int r;
1660 
1661  /* Map Unix nice values to Windows priority classes. */
1662  if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
1663  return UV_EINVAL;
1664  else if (priority < UV_PRIORITY_HIGH)
1665  priority_class = REALTIME_PRIORITY_CLASS;
1667  priority_class = HIGH_PRIORITY_CLASS;
1668  else if (priority < UV_PRIORITY_NORMAL)
1669  priority_class = ABOVE_NORMAL_PRIORITY_CLASS;
1671  priority_class = NORMAL_PRIORITY_CLASS;
1672  else if (priority < UV_PRIORITY_LOW)
1673  priority_class = BELOW_NORMAL_PRIORITY_CLASS;
1674  else
1675  priority_class = IDLE_PRIORITY_CLASS;
1676 
1677  r = uv__get_handle(pid, PROCESS_SET_INFORMATION, &handle);
1678 
1679  if (r != 0)
1680  return r;
1681 
1682  if (SetPriorityClass(handle, priority_class) == 0)
1683  r = uv_translate_sys_error(GetLastError());
1684 
1685  CloseHandle(handle);
1686  return r;
1687 }
1688 
1689 
1691  /* Implementation loosely based on
1692  https://github.com/gagern/gnulib/blob/master/lib/uname.c */
1693  OSVERSIONINFOW os_info;
1694  SYSTEM_INFO system_info;
1695  HKEY registry_key;
1696  WCHAR product_name_w[256];
1697  DWORD product_name_w_size;
1698  int version_size;
1699  int processor_level;
1700  int r;
1701 
1702  if (buffer == NULL)
1703  return UV_EINVAL;
1704 
1705  uv__once_init();
1706  os_info.dwOSVersionInfoSize = sizeof(os_info);
1707  os_info.szCSDVersion[0] = L'\0';
1708 
1709  /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx()
1710  if RtlGetVersion() is not available. */
1711  if (pRtlGetVersion) {
1712  pRtlGetVersion(&os_info);
1713  } else {
1714  /* Silence GetVersionEx() deprecation warning. */
1715  #pragma warning(suppress : 4996)
1716  if (GetVersionExW(&os_info) == 0) {
1717  r = uv_translate_sys_error(GetLastError());
1718  goto error;
1719  }
1720  }
1721 
1722  /* Populate the version field. */
1723  version_size = 0;
1724  r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1725  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
1726  0,
1727  KEY_QUERY_VALUE,
1728  &registry_key);
1729 
1730  if (r == ERROR_SUCCESS) {
1731  product_name_w_size = sizeof(product_name_w);
1732  r = RegGetValueW(registry_key,
1733  NULL,
1734  L"ProductName",
1735  RRF_RT_REG_SZ,
1736  NULL,
1737  (PVOID) product_name_w,
1738  &product_name_w_size);
1739  RegCloseKey(registry_key);
1740 
1741  if (r == ERROR_SUCCESS) {
1742  version_size = WideCharToMultiByte(CP_UTF8,
1743  0,
1744  product_name_w,
1745  -1,
1746  buffer->version,
1747  sizeof(buffer->version),
1748  NULL,
1749  NULL);
1750  if (version_size == 0) {
1751  r = uv_translate_sys_error(GetLastError());
1752  goto error;
1753  }
1754  }
1755  }
1756 
1757  /* Append service pack information to the version if present. */
1758  if (os_info.szCSDVersion[0] != L'\0') {
1759  if (version_size > 0)
1760  buffer->version[version_size - 1] = ' ';
1761 
1762  if (WideCharToMultiByte(CP_UTF8,
1763  0,
1764  os_info.szCSDVersion,
1765  -1,
1766  buffer->version + version_size,
1767  sizeof(buffer->version) - version_size,
1768  NULL,
1769  NULL) == 0) {
1770  r = uv_translate_sys_error(GetLastError());
1771  goto error;
1772  }
1773  }
1774 
1775  /* Populate the sysname field. */
1776 #ifdef __MINGW32__
1777  r = snprintf(buffer->sysname,
1778  sizeof(buffer->sysname),
1779  "MINGW32_NT-%u.%u",
1780  (unsigned int) os_info.dwMajorVersion,
1781  (unsigned int) os_info.dwMinorVersion);
1782  assert(r < sizeof(buffer->sysname));
1783 #else
1784  uv__strscpy(buffer->sysname, "Windows_NT", sizeof(buffer->sysname));
1785 #endif
1786 
1787  /* Populate the release field. */
1788  r = snprintf(buffer->release,
1789  sizeof(buffer->release),
1790  "%d.%d.%d",
1791  (unsigned int) os_info.dwMajorVersion,
1792  (unsigned int) os_info.dwMinorVersion,
1793  (unsigned int) os_info.dwBuildNumber);
1794  assert(r < sizeof(buffer->release));
1795 
1796  /* Populate the machine field. */
1797  GetSystemInfo(&system_info);
1798 
1799  switch (system_info.wProcessorArchitecture) {
1800  case PROCESSOR_ARCHITECTURE_AMD64:
1801  uv__strscpy(buffer->machine, "x86_64", sizeof(buffer->machine));
1802  break;
1803  case PROCESSOR_ARCHITECTURE_IA64:
1804  uv__strscpy(buffer->machine, "ia64", sizeof(buffer->machine));
1805  break;
1806  case PROCESSOR_ARCHITECTURE_INTEL:
1807  uv__strscpy(buffer->machine, "i386", sizeof(buffer->machine));
1808 
1809  if (system_info.wProcessorLevel > 3) {
1810  processor_level = system_info.wProcessorLevel < 6 ?
1811  system_info.wProcessorLevel : 6;
1812  buffer->machine[1] = '0' + processor_level;
1813  }
1814 
1815  break;
1816  case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
1817  uv__strscpy(buffer->machine, "i686", sizeof(buffer->machine));
1818  break;
1819  case PROCESSOR_ARCHITECTURE_MIPS:
1820  uv__strscpy(buffer->machine, "mips", sizeof(buffer->machine));
1821  break;
1822  case PROCESSOR_ARCHITECTURE_ALPHA:
1823  case PROCESSOR_ARCHITECTURE_ALPHA64:
1824  uv__strscpy(buffer->machine, "alpha", sizeof(buffer->machine));
1825  break;
1826  case PROCESSOR_ARCHITECTURE_PPC:
1827  uv__strscpy(buffer->machine, "powerpc", sizeof(buffer->machine));
1828  break;
1829  case PROCESSOR_ARCHITECTURE_SHX:
1830  uv__strscpy(buffer->machine, "sh", sizeof(buffer->machine));
1831  break;
1832  case PROCESSOR_ARCHITECTURE_ARM:
1833  uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
1834  break;
1835  default:
1836  uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
1837  break;
1838  }
1839 
1840  return 0;
1841 
1842 error:
1843  buffer->sysname[0] = '\0';
1844  buffer->release[0] = '\0';
1845  buffer->version[0] = '\0';
1846  buffer->machine[0] = '\0';
1847  return r;
1848 }
1849 
1851  /* Based on https://doxygen.postgresql.org/gettimeofday_8c_source.html */
1852  const uint64_t epoch = (uint64_t) 116444736000000000ULL;
1853  FILETIME file_time;
1854  ULARGE_INTEGER ularge;
1855 
1856  if (tv == NULL)
1857  return UV_EINVAL;
1858 
1859  GetSystemTimeAsFileTime(&file_time);
1860  ularge.LowPart = file_time.dwLowDateTime;
1861  ularge.HighPart = file_time.dwHighDateTime;
1862  tv->tv_sec = (int64_t) ((ularge.QuadPart - epoch) / 10000000L);
1863  tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10);
1864  return 0;
1865 }
1866 
1867 int uv__random_rtlgenrandom(void* buf, size_t buflen) {
1868  if (buflen == 0)
1869  return 0;
1870 
1871  if (SystemFunction036(buf, buflen) == FALSE)
1872  return UV_EIO;
1873 
1874  return 0;
1875 }
1876 
1877 void uv_sleep(unsigned int msec) {
1878  Sleep(msec);
1879 }
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
uv_cpu_times_s::irq
uint64_t irq
Definition: uv.h:1076
uv__get_handle
static int uv__get_handle(uv_pid_t pid, int access, HANDLE *handle)
Definition: libuv/src/win/util.c:1596
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
uv_interface_addresses
int uv_interface_addresses(uv_interface_address_t **addresses_ptr, int *count_ptr)
Definition: libuv/src/win/util.c:792
uv_env_item_s::value
char * value
Definition: uv.h:1220
UV_PRIORITY_HIGH
#define UV_PRIORITY_HIGH
Definition: uv.h:1203
UV_PRIORITY_LOW
#define UV_PRIORITY_LOW
Definition: uv.h:1199
uv_rusage_t::ru_stime
uv_timeval_t ru_stime
Definition: uv.h:1164
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
UV_PRIORITY_ABOVE_NORMAL
#define UV_PRIORITY_ABOVE_NORMAL
Definition: uv.h:1202
env_var
Definition: win/process.c:40
uv_rusage_t
Definition: uv.h:1162
uv_uptime
int uv_uptime(double *uptime)
Definition: libuv/src/win/util.c:501
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
priority
int priority
Definition: abseil-cpp/absl/synchronization/internal/graphcycles.cc:286
uv_passwd_s
Definition: uv.h:1099
uv__util_init
void uv__util_init(void)
Definition: libuv/src/win/util.c:80
uv_cpu_info_s
Definition: uv.h:1079
generate.env
env
Definition: generate.py:37
memset
return memset(p, 0, total)
MAX_ENV_VAR_LENGTH
#define MAX_ENV_VAR_LENGTH
Definition: libuv/src/win/util.c:64
address_prefix_match
static int address_prefix_match(int family, struct sockaddr *address, struct sockaddr *prefix_address, int prefix_len)
Definition: libuv/src/win/util.c:758
uv__malloc
void * uv__malloc(size_t size)
Definition: uv-common.c:75
uv_passwd_s::username
char * username
Definition: uv.h:1100
uv_passwd_s::gid
long gid
Definition: uv.h:1102
uv__random_rtlgenrandom
int uv__random_rtlgenrandom(void *buf, size_t buflen)
Definition: libuv/src/win/util.c:1867
uv_passwd_s::homedir
char * homedir
Definition: uv.h:1104
string.h
uv_timeval64_t::tv_sec
int64_t tv_sec
Definition: uv.h:1158
uv_pid_t
pid_t uv_pid_t
Definition: unix.h:129
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
uv_os_getpid
uv_pid_t uv_os_getpid(void)
Definition: libuv/src/win/util.c:331
UV_MAXHOSTNAMESIZE
#define UV_MAXHOSTNAMESIZE
Definition: uv.h:1237
uv_setup_args
char ** uv_setup_args(int argc, char **argv)
Definition: libuv/src/win/util.c:359
error
grpc_error_handle error
Definition: retry_filter.cc:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
uv_rusage_t::ru_majflt
uint64_t ru_majflt
Definition: uv.h:1170
status
absl::Status status
Definition: rls.cc:251
_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
Definition: winapi.h:4426
is_windows_version_or_greater
static int is_windows_version_or_greater(DWORD os_major, DWORD os_minor, WORD service_pack_major, WORD service_pack_minor)
Definition: libuv/src/win/util.c:727
setup.name
name
Definition: setup.py:542
check_documentation.path
path
Definition: check_documentation.py:57
uv_sleep
void uv_sleep(unsigned int msec)
Definition: libuv/src/win/util.c:1877
uv_env_item_s::name
char * name
Definition: uv.h:1219
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
pRtlNtStatusToDosError
sRtlNtStatusToDosError pRtlNtStatusToDosError
Definition: winapi.c:30
uv_os_getenv
int uv_os_getenv(const char *name, char *buffer, size_t *size)
Definition: libuv/src/win/util.c:1463
uv_os_free_passwd
void uv_os_free_passwd(uv_passwd_t *pwd)
Definition: libuv/src/win/util.c:1218
uv_cpu_info_s::cpu_times
struct uv_cpu_times_s cpu_times
Definition: uv.h:1082
uv_interface_address_s::netmask
union uv_interface_address_s::@401 netmask
uv_timeval_t::tv_sec
long tv_sec
Definition: uv.h:1153
uv_interface_address_s::name
char * name
Definition: uv.h:1086
uv_cwd
int uv_cwd(char *buffer, size_t *size)
Definition: libuv/src/win/util.c:155
uv_os_gethostname
int uv_os_gethostname(char *buffer, size_t *size)
Definition: libuv/src/win/util.c:1570
NT_SUCCESS
#define NT_SUCCESS(status)
Definition: winapi.h:52
ULL
#define ULL(x)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:57
uv_hrtime
uint64_t uv_hrtime(void)
Definition: libuv/src/win/util.c:460
uv_cpu_times_s::nice
uint64_t nice
Definition: uv.h:1073
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
uv_rusage_t::ru_oublock
uint64_t ru_oublock
Definition: uv.h:1173
uv_interface_address_t
struct uv_interface_address_s uv_interface_address_t
Definition: uv.h:243
uv_os_get_passwd
int uv_os_get_passwd(uv_passwd_t *pwd)
Definition: libuv/src/win/util.c:1387
xds_interop_client.int
int
Definition: xds_interop_client.py:113
sockaddr_in6
Definition: ares_ipv6.h:25
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
uv_exepath
int uv_exepath(char *buffer, size_t *size_ptr)
Definition: libuv/src/win/util.c:97
hrtime_interval_
static double hrtime_interval_
Definition: libuv/src/win/util.c:74
uv_passwd_s::shell
char * shell
Definition: uv.h:1103
uv_translate_sys_error
UV_EXTERN int uv_translate_sys_error(int sys_errno)
Definition: unix/core.c:1244
uv_env_item_s
Definition: uv.h:1218
uv__strdup
char * uv__strdup(const char *s)
Definition: uv-common.c:55
uv_os_uname
int uv_os_uname(uv_utsname_t *buffer)
Definition: libuv/src/win/util.c:1690
process_title
static char * process_title
Definition: libuv/src/win/util.c:70
uv_get_process_title
int uv_get_process_title(char *buffer, size_t size)
Definition: libuv/src/win/util.c:427
grpc_core::fail
Poll< absl::StatusOr< std::tuple< T... > > > fail()
Definition: try_join_test.cc:45
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
pNtQuerySystemInformation
sNtQuerySystemInformation pNtQuerySystemInformation
Definition: winapi.c:36
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
counter
static int counter
Definition: abseil-cpp/absl/flags/reflection_test.cc:131
pRtlGetVersion
sRtlGetVersion pRtlGetVersion
Definition: winapi.c:29
epoch
int64_t epoch(int year, int yday, int hour, int min, int sec)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:10172
uv__calloc
void * uv__calloc(size_t count, size_t size)
Definition: uv-common.c:92
uv__free
void uv__free(void *ptr)
Definition: uv-common.c:81
uv_resident_set_memory
int uv_resident_set_memory(size_t *rss)
Definition: libuv/src/win/util.c:485
sockaddr_in6::sin6_family
unsigned short sin6_family
Definition: ares_ipv6.h:27
UV_PRIORITY_BELOW_NORMAL
#define UV_PRIORITY_BELOW_NORMAL
Definition: uv.h:1200
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
bm_speedup.scale
def scale(a, mul)
Definition: bm_speedup.py:24
UNLEN
#define UNLEN
Definition: libuv/src/win/util.c:59
UV_PRIORITY_HIGHEST
#define UV_PRIORITY_HIGHEST
Definition: uv.h:1204
uv_cpu_times_s::user
uint64_t user
Definition: uv.h:1072
uv_timeval64_t::tv_usec
int32_t tv_usec
Definition: uv.h:1159
uv_cpu_info_s::model
char * model
Definition: uv.h:1080
uv_gettimeofday
int uv_gettimeofday(uv_timeval64_t *tv)
Definition: libuv/src/win/util.c:1850
uv_chdir
int uv_chdir(const char *dir)
Definition: libuv/src/win/util.c:218
uv_get_constrained_memory
uint64_t uv_get_constrained_memory(void)
Definition: libuv/src/win/util.c:326
uv_interface_address_s
Definition: uv.h:1085
uv_fatal_error
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35
value
const char * value
Definition: hpack_parser_table.cc:165
uv.h
uv__getpwuid_r
int uv__getpwuid_r(uv_passwd_t *pwd)
Definition: libuv/src/win/util.c:1325
uv_passwd_s::uid
long uid
Definition: uv.h:1101
uv_timeval64_t
Definition: uv.h:1157
FALSE
const BOOL FALSE
Definition: undname.c:47
uv_os_homedir
int uv_os_homedir(char *buffer, size_t *size)
Definition: libuv/src/win/util.c:1128
process_title_lock
static CRITICAL_SECTION process_title_lock
Definition: libuv/src/win/util.c:71
uv__strscpy
ssize_t uv__strscpy(char *d, const char *s, size_t n)
Definition: strscpy.c:4
uv_rusage_t::ru_maxrss
uint64_t ru_maxrss
Definition: uv.h:1165
uv_set_process_title
int uv_set_process_title(const char *title)
Definition: libuv/src/win/util.c:364
uv_get_free_memory
uint64_t uv_get_free_memory(void)
Definition: libuv/src/win/util.c:302
uv_os_getpriority
int uv_os_getpriority(uv_pid_t pid, int *priority)
Definition: libuv/src/win/util.c:1617
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
uv_interface_address_s::address4
struct sockaddr_in address4
Definition: uv.h:1090
uv_free_interface_addresses
void uv_free_interface_addresses(uv_interface_address_t *addresses, int count)
Definition: libuv/src/win/util.c:1066
uv_os_setpriority
int uv_os_setpriority(uv_pid_t pid, int priority)
Definition: libuv/src/win/util.c:1656
uv__convert_utf16_to_utf8
int uv__convert_utf16_to_utf8(const WCHAR *utf16, int utf16len, char **utf8)
Definition: libuv/src/win/util.c:1236
uv_os_unsetenv
int uv_os_unsetenv(const char *name)
Definition: libuv/src/win/util.c:1548
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
uv_interface_address_s::netmask6
struct sockaddr_in6 netmask6
Definition: uv.h:1095
uv_loadavg
void uv_loadavg(double avg[3])
Definition: libuv/src/win/util.c:296
UV_PRIORITY_NORMAL
#define UV_PRIORITY_NORMAL
Definition: uv.h:1201
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
fix_build_deps.r
r
Definition: fix_build_deps.py:491
env
Definition: env.py:1
uv__get_process_title
static int uv__get_process_title(void)
Definition: libuv/src/win/util.c:413
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
uv_os_environ
int uv_os_environ(uv_env_item_t **envitems, int *count)
Definition: libuv/src/win/util.c:1392
uv_interface_address_s::is_internal
int is_internal
Definition: uv.h:1088
uv_timeval_t::tv_usec
long tv_usec
Definition: uv.h:1154
sockaddr_in6::sin6_addr
struct ares_in6_addr sin6_addr
Definition: ares_ipv6.h:30
SystemFunction036
BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength)
uv_cpu_info
int uv_cpu_info(uv_cpu_info_t **cpu_infos_ptr, int *cpu_count_ptr)
Definition: libuv/src/win/util.c:602
handle
static csh handle
Definition: test_arm_regression.c:16
uv_rusage_t::ru_utime
uv_timeval_t ru_utime
Definition: uv.h:1163
uv_interface_address_s::address
union uv_interface_address_s::@400 address
uv_os_setenv
int uv_os_setenv(const char *name, const char *value)
Definition: libuv/src/win/util.c:1517
uv__once_init
void uv__once_init(void)
Definition: win/core.c:314
uv_interface_address_s::phys_addr
char phys_addr[6]
Definition: uv.h:1087
uv_getrusage
int uv_getrusage(uv_rusage_t *uv_rusage)
Definition: libuv/src/win/util.c:1072
uv_interface_address_s::netmask4
struct sockaddr_in netmask4
Definition: uv.h:1094
flags
uint32_t flags
Definition: retry_filter.cc:632
internal.h
SystemProcessorPerformanceInformation
#define SystemProcessorPerformanceInformation
Definition: winapi.h:4436
uv_rusage_t::ru_inblock
uint64_t ru_inblock
Definition: uv.h:1172
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
UV__NANOSEC
#define UV__NANOSEC
Definition: libuv/src/win/util.c:55
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
NTSTATUS
LONG NTSTATUS
Definition: win.h:198
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
uv_cpu_info_s::speed
int speed
Definition: uv.h:1081
access
Definition: bloaty/third_party/zlib/examples/zran.c:75
uv_cpu_times_s::sys
uint64_t sys
Definition: uv.h:1074
uv__convert_utf8_to_utf16
int uv__convert_utf8_to_utf16(const char *utf8, int utf8len, WCHAR **utf16)
Definition: libuv/src/win/util.c:1291
uv__hrtime
uint64_t uv__hrtime(double scale)
Definition: libuv/src/win/util.c:465
MAX_TITLE_LENGTH
#define MAX_TITLE_LENGTH
Definition: libuv/src/win/util.c:52
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
uv_get_total_memory
uint64_t uv_get_total_memory(void)
Definition: libuv/src/win/util.c:314
versiongenerate.buffer_size
int buffer_size
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/xcode/Scripts/versiongenerate.py:65
uv_os_tmpdir
int uv_os_tmpdir(char *buffer, size_t *size)
Definition: libuv/src/win/util.c:1165
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
uv_interface_address_s::address6
struct sockaddr_in6 address6
Definition: uv.h:1091
uv_utsname_s
Definition: uv.h:1107
uv_cpu_times_s::idle
uint64_t idle
Definition: uv.h:1075
uv_os_getppid
uv_pid_t uv_os_getppid(void)
Definition: libuv/src/win/util.c:336


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:49