Rizin
unix-like reverse engineering framework and cli tools
sunos.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  * Permission is hereby granted, free of charge, to any person obtaining a copy
3  * of this software and associated documentation files (the "Software"), to
4  * deal in the Software without restriction, including without limitation the
5  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6  * sell copies of the Software, and to permit persons to whom the Software is
7  * furnished to do so, subject to the following conditions:
8  *
9  * The above copyright notice and this permission notice shall be included in
10  * all copies or substantial portions of the Software.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18  * IN THE SOFTWARE.
19  */
20 
21 #include "uv.h"
22 #include "internal.h"
23 
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 
31 #ifndef SUNOS_NO_IFADDRS
32 # include <ifaddrs.h>
33 #endif
34 #include <net/if.h>
35 #include <net/if_dl.h>
36 #include <net/if_arp.h>
37 #include <sys/sockio.h>
38 
39 #include <sys/loadavg.h>
40 #include <sys/time.h>
41 #include <unistd.h>
42 #include <kstat.h>
43 #include <fcntl.h>
44 
45 #include <sys/port.h>
46 #include <port.h>
47 
48 #define PORT_FIRED 0x69
49 #define PORT_UNUSED 0x0
50 #define PORT_LOADED 0x99
51 #define PORT_DELETED -1
52 
53 #if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
54 #define PROCFS_FILE_OFFSET_BITS_HACK 1
55 #undef _FILE_OFFSET_BITS
56 #else
57 #define PROCFS_FILE_OFFSET_BITS_HACK 0
58 #endif
59 
60 #include <procfs.h>
61 
62 #if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1)
63 #define _FILE_OFFSET_BITS 64
64 #endif
65 
66 
68  int err;
69  int fd;
70 
71  loop->fs_fd = -1;
72  loop->backend_fd = -1;
73 
74  fd = port_create();
75  if (fd == -1)
76  return UV__ERR(errno);
77 
78  err = uv__cloexec(fd, 1);
79  if (err) {
80  uv__close(fd);
81  return err;
82  }
83  loop->backend_fd = fd;
84 
85  return 0;
86 }
87 
88 
90  if (loop->fs_fd != -1) {
91  uv__close(loop->fs_fd);
92  loop->fs_fd = -1;
93  }
94 
95  if (loop->backend_fd != -1) {
96  uv__close(loop->backend_fd);
97  loop->backend_fd = -1;
98  }
99 }
100 
101 
103 #if defined(PORT_SOURCE_FILE)
104  if (loop->fs_fd != -1) {
105  /* stop the watcher before we blow away its fileno */
106  uv__io_stop(loop, &loop->fs_event_watcher, POLLIN);
107  }
108 #endif
111 }
112 
113 
115  struct port_event* events;
116  uintptr_t i;
117  uintptr_t nfds;
118 
119  assert(loop->watchers != NULL);
120  assert(fd >= 0);
121 
122  events = (struct port_event*) loop->watchers[loop->nwatchers];
123  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
124  if (events == NULL)
125  return;
126 
127  /* Invalidate events with same file descriptor */
128  for (i = 0; i < nfds; i++)
129  if ((int) events[i].portev_object == fd)
130  events[i].portev_object = -1;
131 }
132 
133 
135  if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
136  return UV__ERR(errno);
137 
138  if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd)) {
139  perror("(libuv) port_dissociate()");
140  abort();
141  }
142 
143  return 0;
144 }
145 
146 
148  struct port_event events[1024];
149  struct port_event* pe;
150  struct timespec spec;
151  QUEUE* q;
152  uv__io_t* w;
153  sigset_t* pset;
154  sigset_t set;
155  uint64_t base;
156  uint64_t diff;
157  uint64_t idle_poll;
158  unsigned int nfds;
159  unsigned int i;
160  int saved_errno;
161  int have_signals;
162  int nevents;
163  int count;
164  int err;
165  int fd;
166  int user_timeout;
167  int reset_timeout;
168 
169  if (loop->nfds == 0) {
170  assert(QUEUE_EMPTY(&loop->watcher_queue));
171  return;
172  }
173 
174  while (!QUEUE_EMPTY(&loop->watcher_queue)) {
175  q = QUEUE_HEAD(&loop->watcher_queue);
176  QUEUE_REMOVE(q);
177  QUEUE_INIT(q);
178 
179  w = QUEUE_DATA(q, uv__io_t, watcher_queue);
180  assert(w->pevents != 0);
181 
182  if (port_associate(loop->backend_fd,
183  PORT_SOURCE_FD,
184  w->fd,
185  w->pevents,
186  0)) {
187  perror("(libuv) port_associate()");
188  abort();
189  }
190 
191  w->events = w->pevents;
192  }
193 
194  pset = NULL;
195  if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
196  pset = &set;
197  sigemptyset(pset);
198  sigaddset(pset, SIGPROF);
199  }
200 
201  assert(timeout >= -1);
202  base = loop->time;
203  count = 48; /* Benchmarks suggest this gives the best throughput. */
204 
206  reset_timeout = 1;
207  user_timeout = timeout;
208  timeout = 0;
209  } else {
210  reset_timeout = 0;
211  }
212 
213  for (;;) {
214  /* Only need to set the provider_entry_time if timeout != 0. The function
215  * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
216  */
217  if (timeout != 0)
219 
220  if (timeout != -1) {
221  spec.tv_sec = timeout / 1000;
222  spec.tv_nsec = (timeout % 1000) * 1000000;
223  }
224 
225  /* Work around a kernel bug where nfds is not updated. */
226  events[0].portev_source = 0;
227 
228  nfds = 1;
229  saved_errno = 0;
230 
231  if (pset != NULL)
232  pthread_sigmask(SIG_BLOCK, pset, NULL);
233 
234  err = port_getn(loop->backend_fd,
235  events,
236  ARRAY_SIZE(events),
237  &nfds,
238  timeout == -1 ? NULL : &spec);
239 
240  if (pset != NULL)
241  pthread_sigmask(SIG_UNBLOCK, pset, NULL);
242 
243  if (err) {
244  /* Work around another kernel bug: port_getn() may return events even
245  * on error.
246  */
247  if (errno == EINTR || errno == ETIME) {
248  saved_errno = errno;
249  } else {
250  perror("(libuv) port_getn()");
251  abort();
252  }
253  }
254 
255  /* Update loop->time unconditionally. It's tempting to skip the update when
256  * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
257  * operating system didn't reschedule our process while in the syscall.
258  */
259  SAVE_ERRNO(uv__update_time(loop));
260 
261  if (events[0].portev_source == 0) {
262  if (reset_timeout != 0) {
263  timeout = user_timeout;
264  reset_timeout = 0;
265  }
266 
267  if (timeout == 0)
268  return;
269 
270  if (timeout == -1)
271  continue;
272 
273  goto update_timeout;
274  }
275 
276  if (nfds == 0) {
277  assert(timeout != -1);
278  return;
279  }
280 
281  have_signals = 0;
282  nevents = 0;
283 
284  assert(loop->watchers != NULL);
285  loop->watchers[loop->nwatchers] = (void*) events;
286  loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
287  for (i = 0; i < nfds; i++) {
288  pe = events + i;
289  fd = pe->portev_object;
290 
291  /* Skip invalidated events, see uv__platform_invalidate_fd */
292  if (fd == -1)
293  continue;
294 
295  assert(fd >= 0);
296  assert((unsigned) fd < loop->nwatchers);
297 
298  w = loop->watchers[fd];
299 
300  /* File descriptor that we've stopped watching, ignore. */
301  if (w == NULL)
302  continue;
303 
304  /* Run signal watchers last. This also affects child process watchers
305  * because those are implemented in terms of signal watchers.
306  */
307  if (w == &loop->signal_io_watcher) {
308  have_signals = 1;
309  } else {
311  w->cb(loop, w, pe->portev_events);
312  }
313 
314  nevents++;
315 
316  if (w != loop->watchers[fd])
317  continue; /* Disabled by callback. */
318 
319  /* Events Ports operates in oneshot mode, rearm timer on next run. */
320  if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
321  QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
322  }
323 
324  if (reset_timeout != 0) {
325  timeout = user_timeout;
326  reset_timeout = 0;
327  }
328 
329  if (have_signals != 0) {
331  loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
332  }
333 
334  loop->watchers[loop->nwatchers] = NULL;
335  loop->watchers[loop->nwatchers + 1] = NULL;
336 
337  if (have_signals != 0)
338  return; /* Event loop should cycle now so don't poll again. */
339 
340  if (nevents != 0) {
341  if (nfds == ARRAY_SIZE(events) && --count != 0) {
342  /* Poll for more events but don't block this time. */
343  timeout = 0;
344  continue;
345  }
346  return;
347  }
348 
349  if (saved_errno == ETIME) {
350  assert(timeout != -1);
351  return;
352  }
353 
354  if (timeout == 0)
355  return;
356 
357  if (timeout == -1)
358  continue;
359 
360 update_timeout:
361  assert(timeout > 0);
362 
363  diff = loop->time - base;
364  if (diff >= (uint64_t) timeout)
365  return;
366 
367  timeout -= diff;
368  }
369 }
370 
371 
373  return gethrtime();
374 }
375 
376 
377 /*
378  * We could use a static buffer for the path manipulations that we need outside
379  * of the function, but this function could be called by multiple consumers and
380  * we don't want to potentially create a race condition in the use of snprintf.
381  */
382 int uv_exepath(char* buffer, size_t* size) {
383  ssize_t res;
384  char buf[128];
385 
386  if (buffer == NULL || size == NULL || *size == 0)
387  return UV_EINVAL;
388 
389  snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
390 
391  res = *size - 1;
392  if (res > 0)
393  res = readlink(buf, buffer, res);
394 
395  if (res == -1)
396  return UV__ERR(errno);
397 
398  buffer[res] = '\0';
399  *size = res;
400  return 0;
401 }
402 
403 
405  return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
406 }
407 
408 
410  return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
411 }
412 
413 
415  return 0; /* Memory constraints are unknown. */
416 }
417 
418 
419 void uv_loadavg(double avg[3]) {
420  (void) getloadavg(avg, 3);
421 }
422 
423 
424 #if defined(PORT_SOURCE_FILE)
425 
426 static int uv__fs_event_rearm(uv_fs_event_t *handle) {
427  if (handle->fd == -1)
428  return UV_EBADF;
429 
430  if (port_associate(handle->loop->fs_fd,
431  PORT_SOURCE_FILE,
432  (uintptr_t) &handle->fo,
433  FILE_ATTRIB | FILE_MODIFIED,
434  handle) == -1) {
435  return UV__ERR(errno);
436  }
437  handle->fd = PORT_LOADED;
438 
439  return 0;
440 }
441 
442 
443 static void uv__fs_event_read(uv_loop_t* loop,
444  uv__io_t* w,
445  unsigned int revents) {
447  timespec_t timeout;
448  port_event_t pe;
449  int events;
450  int r;
451 
452  (void) w;
453  (void) revents;
454 
455  do {
456  uint_t n = 1;
457 
458  /*
459  * Note that our use of port_getn() here (and not port_get()) is deliberate:
460  * there is a bug in event ports (Sun bug 6456558) whereby a zeroed timeout
461  * causes port_get() to return success instead of ETIME when there aren't
462  * actually any events (!); by using port_getn() in lieu of port_get(),
463  * we can at least workaround the bug by checking for zero returned events
464  * and treating it as we would ETIME.
465  */
466  do {
467  memset(&timeout, 0, sizeof timeout);
468  r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout);
469  }
470  while (r == -1 && errno == EINTR);
471 
472  if ((r == -1 && errno == ETIME) || n == 0)
473  break;
474 
475  handle = (uv_fs_event_t*) pe.portev_user;
476  assert((r == 0) && "unexpected port_get() error");
477 
478  events = 0;
479  if (pe.portev_events & (FILE_ATTRIB | FILE_MODIFIED))
480  events |= UV_CHANGE;
481  if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED))
482  events |= UV_RENAME;
483  assert(events != 0);
484  handle->fd = PORT_FIRED;
485  handle->cb(handle, NULL, events, 0);
486 
487  if (handle->fd != PORT_DELETED) {
488  r = uv__fs_event_rearm(handle);
489  if (r != 0)
490  handle->cb(handle, NULL, 0, r);
491  }
492  }
493  while (handle->fd != PORT_DELETED);
494 }
495 
496 
498  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
499  return 0;
500 }
501 
502 
505  const char* path,
506  unsigned int flags) {
507  int portfd;
508  int first_run;
509  int err;
510 
511  if (uv__is_active(handle))
512  return UV_EINVAL;
513 
514  first_run = 0;
515  if (handle->loop->fs_fd == -1) {
516  portfd = port_create();
517  if (portfd == -1)
518  return UV__ERR(errno);
519  handle->loop->fs_fd = portfd;
520  first_run = 1;
521  }
522 
524  handle->path = uv__strdup(path);
525  handle->fd = PORT_UNUSED;
526  handle->cb = cb;
527 
528  memset(&handle->fo, 0, sizeof handle->fo);
529  handle->fo.fo_name = handle->path;
530  err = uv__fs_event_rearm(handle);
531  if (err != 0) {
533  return err;
534  }
535 
536  if (first_run) {
537  uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
538  uv__io_start(handle->loop, &handle->loop->fs_event_watcher, POLLIN);
539  }
540 
541  return 0;
542 }
543 
544 
546  if (!uv__is_active(handle))
547  return 0;
548 
549  if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) {
550  port_dissociate(handle->loop->fs_fd,
551  PORT_SOURCE_FILE,
552  (uintptr_t) &handle->fo);
553  }
554 
555  handle->fd = PORT_DELETED;
556  uv__free(handle->path);
557  handle->path = NULL;
558  handle->fo.fo_name = NULL;
560 
561  return 0;
562 }
563 
566 }
567 
568 #else /* !defined(PORT_SOURCE_FILE) */
569 
571  return UV_ENOSYS;
572 }
573 
574 
577  const char* filename,
578  unsigned int flags) {
579  return UV_ENOSYS;
580 }
581 
582 
584  return UV_ENOSYS;
585 }
586 
587 
589  UNREACHABLE();
590 }
591 
592 #endif /* defined(PORT_SOURCE_FILE) */
593 
594 
595 int uv_resident_set_memory(size_t* rss) {
596  psinfo_t psinfo;
597  int err;
598  int fd;
599 
600  fd = open("/proc/self/psinfo", O_RDONLY);
601  if (fd == -1)
602  return UV__ERR(errno);
603 
604  /* FIXME(bnoordhuis) Handle EINTR. */
605  err = UV_EINVAL;
606  if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
607  *rss = (size_t)psinfo.pr_rssize * 1024;
608  err = 0;
609  }
610  uv__close(fd);
611 
612  return err;
613 }
614 
615 
616 int uv_uptime(double* uptime) {
617  kstat_ctl_t *kc;
618  kstat_t *ksp;
619  kstat_named_t *knp;
620 
621  long hz = sysconf(_SC_CLK_TCK);
622 
623  kc = kstat_open();
624  if (kc == NULL)
625  return UV_EPERM;
626 
627  ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc");
628  if (kstat_read(kc, ksp, NULL) == -1) {
629  *uptime = -1;
630  } else {
631  knp = (kstat_named_t*) kstat_data_lookup(ksp, (char*) "clk_intr");
632  *uptime = knp->value.ul / hz;
633  }
634  kstat_close(kc);
635 
636  return 0;
637 }
638 
639 
640 int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
641  int lookup_instance;
642  kstat_ctl_t *kc;
643  kstat_t *ksp;
644  kstat_named_t *knp;
645  uv_cpu_info_t* cpu_info;
646 
647  kc = kstat_open();
648  if (kc == NULL)
649  return UV_EPERM;
650 
651  /* Get count of cpus */
652  lookup_instance = 0;
653  while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) {
654  lookup_instance++;
655  }
656 
657  *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos));
658  if (!(*cpu_infos)) {
659  kstat_close(kc);
660  return UV_ENOMEM;
661  }
662 
663  *count = lookup_instance;
664 
665  cpu_info = *cpu_infos;
666  lookup_instance = 0;
667  while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) {
668  if (kstat_read(kc, ksp, NULL) == -1) {
669  cpu_info->speed = 0;
670  cpu_info->model = NULL;
671  } else {
672  knp = kstat_data_lookup(ksp, (char*) "clock_MHz");
673  assert(knp->data_type == KSTAT_DATA_INT32 ||
674  knp->data_type == KSTAT_DATA_INT64);
675  cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32
676  : knp->value.i64;
677 
678  knp = kstat_data_lookup(ksp, (char*) "brand");
679  assert(knp->data_type == KSTAT_DATA_STRING);
680  cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp));
681  }
682 
683  lookup_instance++;
684  cpu_info++;
685  }
686 
687  cpu_info = *cpu_infos;
688  lookup_instance = 0;
689  for (;;) {
690  ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys");
691 
692  if (ksp == NULL)
693  break;
694 
695  if (kstat_read(kc, ksp, NULL) == -1) {
696  cpu_info->cpu_times.user = 0;
697  cpu_info->cpu_times.nice = 0;
698  cpu_info->cpu_times.sys = 0;
699  cpu_info->cpu_times.idle = 0;
700  cpu_info->cpu_times.irq = 0;
701  } else {
702  knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user");
703  assert(knp->data_type == KSTAT_DATA_UINT64);
704  cpu_info->cpu_times.user = knp->value.ui64;
705 
706  knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel");
707  assert(knp->data_type == KSTAT_DATA_UINT64);
708  cpu_info->cpu_times.sys = knp->value.ui64;
709 
710  knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle");
711  assert(knp->data_type == KSTAT_DATA_UINT64);
712  cpu_info->cpu_times.idle = knp->value.ui64;
713 
714  knp = kstat_data_lookup(ksp, (char*) "intr");
715  assert(knp->data_type == KSTAT_DATA_UINT64);
716  cpu_info->cpu_times.irq = knp->value.ui64;
717  cpu_info->cpu_times.nice = 0;
718  }
719 
720  lookup_instance++;
721  cpu_info++;
722  }
723 
724  kstat_close(kc);
725 
726  return 0;
727 }
728 
729 
730 #ifdef SUNOS_NO_IFADDRS
731 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
732  *count = 0;
733  *addresses = NULL;
734  return UV_ENOSYS;
735 }
736 #else /* SUNOS_NO_IFADDRS */
737 /*
738  * Inspired By:
739  * https://blogs.oracle.com/paulie/entry/retrieving_mac_address_in_solaris
740  * http://www.pauliesworld.org/project/getmac.c
741  */
743  struct ifaddrs* ent) {
744 
745  struct sockaddr_dl* sa_addr;
746  int sockfd;
747  size_t i;
748  struct arpreq arpreq;
749 
750  /* This appears to only work as root */
751  sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
752  memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
753  for (i = 0; i < sizeof(address->phys_addr); i++) {
754  /* Check that all bytes of phys_addr are zero. */
755  if (address->phys_addr[i] != 0)
756  return 0;
757  }
758  memset(&arpreq, 0, sizeof(arpreq));
759  if (address->address.address4.sin_family == AF_INET) {
760  struct sockaddr_in* sin = ((struct sockaddr_in*)&arpreq.arp_pa);
761  sin->sin_addr.s_addr = address->address.address4.sin_addr.s_addr;
762  } else if (address->address.address4.sin_family == AF_INET6) {
763  struct sockaddr_in6* sin = ((struct sockaddr_in6*)&arpreq.arp_pa);
764  memcpy(sin->sin6_addr.s6_addr,
765  address->address.address6.sin6_addr.s6_addr,
766  sizeof(address->address.address6.sin6_addr.s6_addr));
767  } else {
768  return 0;
769  }
770 
772  if (sockfd < 0)
773  return UV__ERR(errno);
774 
775  if (ioctl(sockfd, SIOCGARP, (char*)&arpreq) == -1) {
776  uv__close(sockfd);
777  return UV__ERR(errno);
778  }
779  memcpy(address->phys_addr, arpreq.arp_ha.sa_data, sizeof(address->phys_addr));
780  uv__close(sockfd);
781  return 0;
782 }
783 
784 
785 static int uv__ifaddr_exclude(struct ifaddrs *ent) {
786  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
787  return 1;
788  if (ent->ifa_addr == NULL)
789  return 1;
790  if (ent->ifa_addr->sa_family != AF_INET &&
791  ent->ifa_addr->sa_family != AF_INET6)
792  return 1;
793  return 0;
794 }
795 
797  uv_interface_address_t* address;
798  struct ifaddrs* addrs;
799  struct ifaddrs* ent;
800 
801  *count = 0;
802  *addresses = NULL;
803 
804  if (getifaddrs(&addrs))
805  return UV__ERR(errno);
806 
807  /* Count the number of interfaces */
808  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
809  if (uv__ifaddr_exclude(ent))
810  continue;
811  (*count)++;
812  }
813 
814  if (*count == 0) {
815  freeifaddrs(addrs);
816  return 0;
817  }
818 
819  *addresses = uv__malloc(*count * sizeof(**addresses));
820  if (!(*addresses)) {
821  freeifaddrs(addrs);
822  return UV_ENOMEM;
823  }
824 
825  address = *addresses;
826 
827  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
828  if (uv__ifaddr_exclude(ent))
829  continue;
830 
831  address->name = uv__strdup(ent->ifa_name);
832 
833  if (ent->ifa_addr->sa_family == AF_INET6) {
834  address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
835  } else {
836  address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
837  }
838 
839  if (ent->ifa_netmask->sa_family == AF_INET6) {
840  address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
841  } else {
842  address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
843  }
844 
845  address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) ||
846  (ent->ifa_flags & IFF_LOOPBACK));
847 
848  uv__set_phys_addr(address, ent);
849  address++;
850  }
851 
852  freeifaddrs(addrs);
853 
854  return 0;
855 }
856 #endif /* SUNOS_NO_IFADDRS */
857 
859  int count) {
860  int i;
861 
862  for (i = 0; i < count; i++) {
863  uv__free(addresses[i].name);
864  }
865 
866  uv__free(addresses);
867 }
#define ARRAY_SIZE(a)
__BEGIN_DECLS int getifaddrs(struct ifaddrs **ifap)
void freeifaddrs(struct ifaddrs *ifa)
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
static mcore_handle handle
Definition: asm_mcore.c:8
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
#define w
Definition: crypto_rc6.c:13
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd socket
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len readlink
Definition: sflib.h:65
static static sync static getppid static getegid const char static filename ioctl
Definition: sflib.h:62
#define UV__ERR(x)
Definition: errno.h:29
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static const char struct stat static buf struct stat static buf static vhangup int struct rusage static rusage struct sysinfo static info unsigned static __unused struct utsname static buf const char static size const char static name static pid unsigned static persona static fsgid const void static flags const struct iovec static count static fd const void static len static munlockall struct sched_param static p static sched_yield static policy const struct timespec struct timespec static rem uid_t uid_t uid_t static suid struct pollfd unsigned nfds
Definition: sflib.h:196
assert(limit<=UINT32_MAX/2)
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
#define QUEUE_DATA(ptr, type, field)
Definition: queue.h:30
#define QUEUE_EMPTY(q)
Definition: queue.h:39
#define QUEUE_HEAD(q)
Definition: queue.h:42
#define QUEUE_INSERT_TAIL(h, q)
Definition: queue.h:92
#define QUEUE_INIT(q)
Definition: queue.h:45
void * QUEUE[2]
Definition: queue.h:21
#define QUEUE_REMOVE(q)
Definition: queue.h:101
static sockfd
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
int size_t
Definition: sftypes.h:40
#define EINTR
Definition: sftypes.h:114
#define O_RDONLY
Definition: sftypes.h:486
@ SOCK_DGRAM
Definition: sftypes.h:227
#define AF_INET
Definition: sftypes.h:287
#define AF_INET6
Definition: sftypes.h:295
unsigned long uint64_t
Definition: sftypes.h:28
int ssize_t
Definition: sftypes.h:39
int sigset_t
Definition: sftypes.h:63
_W64 unsigned int uintptr_t
Definition: buffer.h:15
struct sockaddr * ifa_addr
unsigned int ifa_flags
char * ifa_name
struct ifaddrs * ifa_next
struct sockaddr * ifa_netmask
in_addr_t s_addr
Definition: sftypes.h:337
Definition: z80asm.h:102
struct in6_addr sin6_addr
Definition: sftypes.h:375
struct in_addr sin_addr
Definition: sftypes.h:344
long tv_nsec
Definition: sftypes.h:90
time_t tv_sec
Definition: sftypes.h:89
Definition: unix.h:96
struct uv_cpu_times_s cpu_times
Definition: uv.h:1093
char * model
Definition: uv.h:1091
int speed
Definition: uv.h:1092
uint64_t nice
Definition: uv.h:1084
uint64_t sys
Definition: uv.h:1085
uint64_t idle
Definition: uv.h:1086
uint64_t user
Definition: uv.h:1083
uint64_t irq
Definition: uv.h:1087
struct sockaddr_in6 netmask6
Definition: uv.h:1106
struct sockaddr_in6 address6
Definition: uv.h:1102
struct sockaddr_in netmask4
Definition: uv.h:1105
union uv_interface_address_s::@399 netmask
union uv_interface_address_s::@398 address
struct sockaddr_in address4
Definition: uv.h:1101
char phys_addr[6]
Definition: uv.h:1098
Definition: uv.h:1780
uv_loop_t * loop
Definition: main.c:7
uv_timer_t timeout
Definition: main.c:9
void uv__io_stop(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:910
void uv__io_start(uv_loop_t *loop, uv__io_t *w, unsigned int events)
Definition: core.c:882
void uv__io_init(uv__io_t *w, uv__io_cb cb, int fd)
Definition: core.c:865
int uv__close(int fd)
Definition: core.c:569
#define uv__cloexec
Definition: internal.h:169
#define UNREACHABLE()
Definition: internal.h:85
uv_clocktype_t
Definition: internal.h:146
@ UV_LOOP_BLOCK_SIGPROF
Definition: internal.h:137
#define SAVE_ERRNO(block)
Definition: internal.h:92
uint64_t uv_get_total_memory(void)
Definition: sunos.c:409
void uv__fs_event_close(uv_fs_event_t *handle)
Definition: sunos.c:588
static int uv__set_phys_addr(uv_interface_address_t *address, struct ifaddrs *ent)
Definition: sunos.c:742
void uv_loadavg(double avg[3])
Definition: sunos.c:419
int uv_fs_event_stop(uv_fs_event_t *handle)
Definition: sunos.c:583
void uv__platform_invalidate_fd(uv_loop_t *loop, int fd)
Definition: sunos.c:114
uint64_t uv_get_free_memory(void)
Definition: sunos.c:404
#define PORT_FIRED
Definition: sunos.c:48
int uv_interface_addresses(uv_interface_address_t **addresses, int *count)
Definition: sunos.c:796
void uv__io_poll(uv_loop_t *loop, int timeout)
Definition: sunos.c:147
uint64_t uv__hrtime(uv_clocktype_t type)
Definition: sunos.c:372
int uv__io_check_fd(uv_loop_t *loop, int fd)
Definition: sunos.c:134
int uv__platform_loop_init(uv_loop_t *loop)
Definition: sunos.c:67
int uv_fs_event_start(uv_fs_event_t *handle, uv_fs_event_cb cb, const char *filename, unsigned int flags)
Definition: sunos.c:575
int uv_uptime(double *uptime)
Definition: sunos.c:616
#define PORT_DELETED
Definition: sunos.c:51
void uv_free_interface_addresses(uv_interface_address_t *addresses, int count)
Definition: sunos.c:858
int uv__io_fork(uv_loop_t *loop)
Definition: sunos.c:102
int uv_fs_event_init(uv_loop_t *loop, uv_fs_event_t *handle)
Definition: sunos.c:570
int uv_cpu_info(uv_cpu_info_t **cpu_infos, int *count)
Definition: sunos.c:640
#define PORT_UNUSED
Definition: sunos.c:49
uint64_t uv_get_constrained_memory(void)
Definition: sunos.c:414
void uv__platform_loop_delete(uv_loop_t *loop)
Definition: sunos.c:89
static int uv__ifaddr_exclude(struct ifaddrs *ent)
Definition: sunos.c:785
#define PORT_LOADED
Definition: sunos.c:50
int uv_exepath(char *buffer, size_t *size)
Definition: sunos.c:382
int uv_resident_set_memory(size_t *rss)
Definition: sunos.c:595
char * uv__strdup(const char *s)
Definition: uv-common.c:55
void * uv__malloc(size_t size)
Definition: uv-common.c:75
void uv__metrics_update_idle_time(uv_loop_t *loop)
Definition: uv-common.c:872
void uv__free(void *ptr)
Definition: uv-common.c:81
void uv__metrics_set_provider_entry_time(uv_loop_t *loop)
Definition: uv-common.c:899
#define uv__handle_init(loop_, h, type_)
Definition: uv-common.h:301
#define uv__handle_stop(h)
Definition: uv-common.h:266
#define uv__is_active(h)
Definition: uv-common.h:252
#define uv__get_internal_fields(loop)
Definition: uv-common.h:336
#define uv__handle_start(h)
Definition: uv-common.h:258
void(* uv_fs_event_cb)(uv_fs_event_t *handle, const char *filename, int events, int status)
Definition: uv.h:369
@ UV_CHANGE
Definition: uv.h:1542
@ UV_RENAME
Definition: uv.h:1541
@ UV_METRICS_IDLE_TIME
Definition: uv.h:251
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115