Rizin
unix-like reverse engineering framework and cli tools
os390.c
Go to the documentation of this file.
1 /* Copyright libuv project 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 "internal.h"
23 #include <sys/ioctl.h>
24 #include <net/if.h>
25 #include <utmpx.h>
26 #include <unistd.h>
27 #include <sys/ps.h>
28 #include <builtins.h>
29 #include <termios.h>
30 #include <sys/msg.h>
31 #if defined(__clang__)
32 #include "csrsic.h"
33 #else
34 #include "//'SYS1.SAMPLIB(CSRSIC)'"
35 #endif
36 
37 #define CVT_PTR 0x10
38 #define PSA_PTR 0x00
39 #define CSD_OFFSET 0x294
40 
41 /*
42  Long-term average CPU service used by this logical partition,
43  in millions of service units per hour. If this value is above
44  the partition's defined capacity, the partition will be capped.
45  It is calculated using the physical CPU adjustment factor
46  (RCTPCPUA) so it may not match other measures of service which
47  are based on the logical CPU adjustment factor. It is available
48  if the hardware supports LPAR cluster.
49 */
50 #define RCTLACS_OFFSET 0xC4
51 
52 /* 32-bit count of alive CPUs. This includes both CPs and IFAs */
53 #define CSD_NUMBER_ONLINE_CPUS 0xD4
54 
55 /* Address of system resources manager (SRM) control table */
56 #define CVTOPCTP_OFFSET 0x25C
57 
58 /* Address of the RCT table */
59 #define RMCTRCT_OFFSET 0xE4
60 
61 /* Address of the rsm control and enumeration area. */
62 #define CVTRCEP_OFFSET 0x490
63 
64 /*
65  Number of frames currently available to system.
66  Excluded are frames backing perm storage, frames offline, and bad frames.
67 */
68 #define RCEPOOL_OFFSET 0x004
69 
70 /* Total number of frames currently on all available frame queues. */
71 #define RCEAFC_OFFSET 0x088
72 
73 /* CPC model length from the CSRSI Service. */
74 #define CPCMODEL_LENGTH 16
75 
76 /* Pointer to the home (current) ASCB. */
77 #define PSAAOLD 0x224
78 
79 /* Pointer to rsm address space block extension. */
80 #define ASCBRSME 0x16C
81 
82 /*
83  NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE.
84  It does not include 2G frames.
85 */
86 #define RAXFMCT 0x2C
87 
88 /* Thread Entry constants */
89 #define PGTH_CURRENT 1
90 #define PGTH_LEN 26
91 #define PGTHAPATH 0x20
92 #pragma linkage(BPX4GTH, OS)
93 #pragma linkage(BPX1GTH, OS)
94 
95 /* TOD Clock resolution in nanoseconds */
96 #define TOD_RES 4.096
97 
98 typedef unsigned data_area_ptr_assign_type;
99 
100 typedef union {
101  struct {
102 #if defined(_LP64)
104 #endif
106  };
107  char* deref;
108 } data_area_ptr;
109 
110 
111 void uv_loadavg(double avg[3]) {
112  /* TODO: implement the following */
113  avg[0] = 0;
114  avg[1] = 0;
115  avg[2] = 0;
116 }
117 
118 
120  uv__os390_epoll* ep;
121 
122  ep = epoll_create1(0);
123  loop->ep = ep;
124  if (ep == NULL)
125  return UV__ERR(errno);
126 
127  return 0;
128 }
129 
130 
132  if (loop->ep != NULL) {
133  epoll_queue_close(loop->ep);
134  loop->ep = NULL;
135  }
136 }
137 
138 
140  unsigned long long timestamp;
141  __stckf(&timestamp);
142  /* Convert to nanoseconds */
143  return timestamp / TOD_RES;
144 }
145 
146 
147 /*
148  Get the exe path using the thread entry information
149  in the address space.
150 */
151 static int getexe(const int pid, char* buf, size_t len) {
152  struct {
153  int pid;
154  int thid[2];
155  char accesspid;
156  char accessthid;
157  char asid[2];
158  char loginname[8];
159  char flag;
160  char len;
161  } Input_data;
162 
163  union {
164  struct {
165  char gthb[4];
166  int pid;
167  int thid[2];
168  char accesspid;
169  char accessthid[3];
170  int lenused;
171  int offsetProcess;
172  int offsetConTTY;
173  int offsetPath;
174  int offsetCommand;
175  int offsetFileData;
176  int offsetThread;
177  } Output_data;
178  char buf[2048];
179  } Output_buf;
180 
181  struct Output_path_type {
182  char gthe[4];
183  short int len;
184  char path[1024];
185  };
186 
187  int Input_length;
188  int Output_length;
189  void* Input_address;
190  void* Output_address;
191  struct Output_path_type* Output_path;
192  int rv;
193  int rc;
194  int rsn;
195 
196  Input_length = PGTH_LEN;
197  Output_length = sizeof(Output_buf);
198  Output_address = &Output_buf;
199  Input_address = &Input_data;
200  memset(&Input_data, 0, sizeof Input_data);
201  Input_data.flag |= PGTHAPATH;
202  Input_data.pid = pid;
203  Input_data.accesspid = PGTH_CURRENT;
204 
205 #ifdef _LP64
206  BPX4GTH(&Input_length,
207  &Input_address,
208  &Output_length,
209  &Output_address,
210  &rv,
211  &rc,
212  &rsn);
213 #else
214  BPX1GTH(&Input_length,
215  &Input_address,
216  &Output_length,
217  &Output_address,
218  &rv,
219  &rc,
220  &rsn);
221 #endif
222 
223  if (rv == -1) {
224  errno = rc;
225  return -1;
226  }
227 
228  /* Check highest byte to ensure data availability */
229  assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A');
230 
231  /* Get the offset from the lowest 3 bytes */
232  Output_path = (struct Output_path_type*) ((char*) (&Output_buf) +
233  (Output_buf.Output_data.offsetPath & 0x00FFFFFF));
234 
235  if (Output_path->len >= len) {
236  errno = ENOBUFS;
237  return -1;
238  }
239 
240  uv__strscpy(buf, Output_path->path, len);
241 
242  return 0;
243 }
244 
245 
246 /*
247  * We could use a static buffer for the path manipulations that we need outside
248  * of the function, but this function could be called by multiple consumers and
249  * we don't want to potentially create a race condition in the use of snprintf.
250  * There is no direct way of getting the exe path in zOS - either through /procfs
251  * or through some libc APIs. The below approach is to parse the argv[0]'s pattern
252  * and use it in conjunction with PATH environment variable to craft one.
253  */
254 int uv_exepath(char* buffer, size_t* size) {
255  int res;
256  char args[PATH_MAX];
257  int pid;
258 
259  if (buffer == NULL || size == NULL || *size == 0)
260  return UV_EINVAL;
261 
262  pid = getpid();
263  res = getexe(pid, args, sizeof(args));
264  if (res < 0)
265  return UV_EINVAL;
266 
267  return uv__search_path(args, buffer, size);
268 }
269 
270 
272  uint64_t freeram;
273 
274  data_area_ptr cvt = {0};
275  data_area_ptr rcep = {0};
278  freeram = *((uint64_t*)(rcep.deref + RCEAFC_OFFSET)) * 4;
279  return freeram;
280 }
281 
282 
284  uint64_t totalram;
285 
286  data_area_ptr cvt = {0};
287  data_area_ptr rcep = {0};
290  totalram = *((uint64_t*)(rcep.deref + RCEPOOL_OFFSET)) * 4;
291  return totalram;
292 }
293 
294 
296  return 0; /* Memory constraints are unknown. */
297 }
298 
299 
300 int uv_resident_set_memory(size_t* rss) {
301  char* ascb;
302  char* rax;
303  size_t nframes;
304 
305  ascb = *(char* __ptr32 *)(PSA_PTR + PSAAOLD);
306  rax = *(char* __ptr32 *)(ascb + ASCBRSME);
307  nframes = *(unsigned int*)(rax + RAXFMCT);
308 
309  *rss = nframes * sysconf(_SC_PAGESIZE);
310  return 0;
311 }
312 
313 
314 int uv_uptime(double* uptime) {
315  struct utmpx u ;
316  struct utmpx *v;
317  time64_t t;
318 
319  u.ut_type = BOOT_TIME;
320  v = getutxid(&u);
321  if (v == NULL)
322  return -1;
323  *uptime = difftime64(time64(&t), v->ut_tv.tv_sec);
324  return 0;
325 }
326 
327 
328 int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
329  uv_cpu_info_t* cpu_info;
330  int idx;
331  siv1v2 info;
332  data_area_ptr cvt = {0};
333  data_area_ptr csd = {0};
334  data_area_ptr rmctrct = {0};
335  data_area_ptr cvtopctp = {0};
336  int cpu_usage_avg;
337 
339 
340  csd.assign = *((data_area_ptr_assign_type *) (cvt.deref + CSD_OFFSET));
341  cvtopctp.assign = *((data_area_ptr_assign_type *) (cvt.deref + CVTOPCTP_OFFSET));
342  rmctrct.assign = *((data_area_ptr_assign_type *) (cvtopctp.deref + RMCTRCT_OFFSET));
343 
344  *count = *((int*) (csd.deref + CSD_NUMBER_ONLINE_CPUS));
345  cpu_usage_avg = *((unsigned short int*) (rmctrct.deref + RCTLACS_OFFSET));
346 
347  *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t));
348  if (!*cpu_infos)
349  return UV_ENOMEM;
350 
351  cpu_info = *cpu_infos;
352  idx = 0;
353  while (idx < *count) {
354  cpu_info->speed = *(int*)(info.siv1v2si22v1.si22v1cpucapability);
355  cpu_info->model = uv__malloc(CPCMODEL_LENGTH + 1);
356  memset(cpu_info->model, '\0', CPCMODEL_LENGTH + 1);
357  memcpy(cpu_info->model, info.siv1v2si11v1.si11v1cpcmodel, CPCMODEL_LENGTH);
358  cpu_info->cpu_times.user = cpu_usage_avg;
359  /* TODO: implement the following */
360  cpu_info->cpu_times.sys = 0;
361  cpu_info->cpu_times.idle = 0;
362  cpu_info->cpu_times.irq = 0;
363  cpu_info->cpu_times.nice = 0;
364  ++cpu_info;
365  ++idx;
366  }
367 
368  return 0;
369 }
370 
371 
373  int* count) {
374  uv_interface_address_t* address;
375  int sockfd;
376  int maxsize;
377  __net_ifconf6header_t ifc;
378  __net_ifconf6entry_t* ifr;
379  __net_ifconf6entry_t* p;
380  __net_ifconf6entry_t flg;
381 
382  *count = 0;
383  /* Assume maximum buffer size allowable */
384  maxsize = 16384;
385 
386  if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
387  return UV__ERR(errno);
388 
389  ifc.__nif6h_version = 1;
390  ifc.__nif6h_buflen = maxsize;
391  ifc.__nif6h_buffer = uv__calloc(1, maxsize);;
392 
393  if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) {
394  uv__close(sockfd);
395  return UV__ERR(errno);
396  }
397 
398 
399  *count = 0;
400  ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer);
401  while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) {
402  p = ifr;
403  ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
404 
405  if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
406  p->__nif6e_addr.sin6_family == AF_INET))
407  continue;
408 
409  if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
410  continue;
411 
412  ++(*count);
413  }
414 
415  /* Alloc the return interface structs */
416  *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
417  if (!(*addresses)) {
418  uv__close(sockfd);
419  return UV_ENOMEM;
420  }
421  address = *addresses;
422 
423  ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer);
424  while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) {
425  p = ifr;
426  ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
427 
428  if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
429  p->__nif6e_addr.sin6_family == AF_INET))
430  continue;
431 
432  if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
433  continue;
434 
435  /* All conditions above must match count loop */
436 
437  address->name = uv__strdup(p->__nif6e_name);
438 
439  if (p->__nif6e_addr.sin6_family == AF_INET6)
440  address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr);
441  else
442  address->address.address4 = *((struct sockaddr_in*) &p->__nif6e_addr);
443 
444  /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
445 
446  address->is_internal = flg.__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0;
447  memset(address->phys_addr, 0, sizeof(address->phys_addr));
448  address++;
449  }
450 
451  uv__close(sockfd);
452  return 0;
453 }
454 
455 
457  uv_interface_address_t* address;
458  int sockfd;
459  int maxsize;
460  struct ifconf ifc;
461  struct ifreq flg;
462  struct ifreq* ifr;
463  struct ifreq* p;
464  int count_v6;
465 
466  *count = 0;
467  *addresses = NULL;
468 
469  /* get the ipv6 addresses first */
470  uv_interface_address_t* addresses_v6;
471  uv__interface_addresses_v6(&addresses_v6, &count_v6);
472 
473  /* now get the ipv4 addresses */
474 
475  /* Assume maximum buffer size allowable */
476  maxsize = 16384;
477 
478  sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
479  if (0 > sockfd)
480  return UV__ERR(errno);
481 
482  ifc.ifc_req = uv__calloc(1, maxsize);
483  ifc.ifc_len = maxsize;
484  if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
485  uv__close(sockfd);
486  return UV__ERR(errno);
487  }
488 
489 #define MAX(a,b) (((a)>(b))?(a):(b))
490 #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
491 
492  /* Count all up and running ipv4/ipv6 addresses */
493  ifr = ifc.ifc_req;
494  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
495  p = ifr;
496  ifr = (struct ifreq*)
497  ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
498 
499  if (!(p->ifr_addr.sa_family == AF_INET6 ||
500  p->ifr_addr.sa_family == AF_INET))
501  continue;
502 
503  memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
504  if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
505  uv__close(sockfd);
506  return UV__ERR(errno);
507  }
508 
509  if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
510  continue;
511 
512  (*count)++;
513  }
514 
515  if (*count == 0) {
516  uv__close(sockfd);
517  return 0;
518  }
519 
520  /* Alloc the return interface structs */
521  *addresses = uv__malloc((*count + count_v6) *
522  sizeof(uv_interface_address_t));
523 
524  if (!(*addresses)) {
525  uv__close(sockfd);
526  return UV_ENOMEM;
527  }
528  address = *addresses;
529 
530  /* copy over the ipv6 addresses */
531  memcpy(address, addresses_v6, count_v6 * sizeof(uv_interface_address_t));
532  address += count_v6;
533  *count += count_v6;
534  uv__free(addresses_v6);
535 
536  ifr = ifc.ifc_req;
537  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
538  p = ifr;
539  ifr = (struct ifreq*)
540  ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
541 
542  if (!(p->ifr_addr.sa_family == AF_INET6 ||
543  p->ifr_addr.sa_family == AF_INET))
544  continue;
545 
546  memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
547  if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
548  uv__close(sockfd);
549  return UV_ENOSYS;
550  }
551 
552  if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
553  continue;
554 
555  /* All conditions above must match count loop */
556 
557  address->name = uv__strdup(p->ifr_name);
558 
559  if (p->ifr_addr.sa_family == AF_INET6) {
560  address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
561  } else {
562  address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
563  }
564 
565  address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
566  memset(address->phys_addr, 0, sizeof(address->phys_addr));
567  address++;
568  }
569 
570 #undef ADDR_SIZE
571 #undef MAX
572 
573  uv__close(sockfd);
574  return 0;
575 }
576 
577 
579  int count) {
580  int i;
581  for (i = 0; i < count; ++i)
582  uv__free(addresses[i].name);
583  uv__free(addresses);
584 }
585 
586 
588  struct epoll_event* events;
589  struct epoll_event dummy;
590  uintptr_t i;
591  uintptr_t nfds;
592 
593  assert(loop->watchers != NULL);
594  assert(fd >= 0);
595 
596  events = (struct epoll_event*) loop->watchers[loop->nwatchers];
597  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
598  if (events != NULL)
599  /* Invalidate events with same file descriptor */
600  for (i = 0; i < nfds; i++)
601  if ((int) events[i].fd == fd)
602  events[i].fd = -1;
603 
604  /* Remove the file descriptor from the epoll. */
605  if (loop->ep != NULL)
606  epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, &dummy);
607 }
608 
609 
611  struct pollfd p[1];
612  int rv;
613 
614  p[0].fd = fd;
615  p[0].events = POLLIN;
616 
617  do
618  rv = poll(p, 1, 0);
619  while (rv == -1 && errno == EINTR);
620 
621  if (rv == -1)
622  abort();
623 
624  if (p[0].revents & POLLNVAL)
625  return -1;
626 
627  return 0;
628 }
629 
630 
633 }
634 
635 
637  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
638  return 0;
639 }
640 
641 
643  const char* filename, unsigned int flags) {
644  uv__os390_epoll* ep;
645  _RFIS reg_struct;
646  char* path;
647  int rc;
648 
649  if (uv__is_active(handle))
650  return UV_EINVAL;
651 
652  ep = handle->loop->ep;
653  assert(ep->msg_queue != -1);
654 
655  reg_struct.__rfis_cmd = _RFIS_REG;
656  reg_struct.__rfis_qid = ep->msg_queue;
657  reg_struct.__rfis_type = 1;
658  memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle));
659 
661  if (path == NULL)
662  return UV_ENOMEM;
663 
664  rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
665  if (rc != 0)
666  return UV__ERR(errno);
667 
669  handle->path = path;
670  handle->cb = cb;
671  memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok,
672  sizeof(handle->rfis_rftok));
673 
674  return 0;
675 }
676 
677 
679  uv__os390_epoll* ep;
680  _RFIS reg_struct;
681  int rc;
682 
683  if (!uv__is_active(handle))
684  return 0;
685 
686  ep = handle->loop->ep;
687  assert(ep->msg_queue != -1);
688 
689  reg_struct.__rfis_cmd = _RFIS_UNREG;
690  reg_struct.__rfis_qid = ep->msg_queue;
691  reg_struct.__rfis_type = 1;
692  memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
693  sizeof(handle->rfis_rftok));
694 
695  /*
696  * This call will take "/" as the path argument in case we
697  * don't care to supply the correct path. The system will simply
698  * ignore it.
699  */
700  rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
701  if (rc != 0 && errno != EALREADY && errno != ENOENT)
702  abort();
703 
705 
706  return 0;
707 }
708 
709 
712  int msglen;
713  int events;
714  _RFIM msg;
715 
716  if (ep->msg_queue == -1)
717  return 0;
718 
719  msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT);
720 
721  if (msglen == -1 && errno == ENOMSG)
722  return 0;
723 
724  if (msglen == -1)
725  abort();
726 
727  events = 0;
728  if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE)
729  events = UV_CHANGE;
730  else if (msg.__rfim_event == _RFIM_RENAME)
731  events = UV_RENAME;
732  else
733  /* Some event that we are not interested in. */
734  return 0;
735 
736  handle = *(uv_fs_event_t**)(msg.__rfim_utok);
737  handle->cb(handle, uv__basename_r(handle->path), events, 0);
738  return 1;
739 }
740 
741 
743  static const int max_safe_timeout = 1789569;
744  struct epoll_event events[1024];
745  struct epoll_event* pe;
746  struct epoll_event e;
747  uv__os390_epoll* ep;
748  int real_timeout;
749  QUEUE* q;
750  uv__io_t* w;
751  uint64_t base;
752  int count;
753  int nfds;
754  int fd;
755  int op;
756  int i;
757  int user_timeout;
758  int reset_timeout;
759 
760  if (loop->nfds == 0) {
761  assert(QUEUE_EMPTY(&loop->watcher_queue));
762  return;
763  }
764 
765  while (!QUEUE_EMPTY(&loop->watcher_queue)) {
767 
768  q = QUEUE_HEAD(&loop->watcher_queue);
769  QUEUE_REMOVE(q);
770  QUEUE_INIT(q);
771  w = QUEUE_DATA(q, uv__io_t, watcher_queue);
772 
773  assert(w->pevents != 0);
774  assert(w->fd >= 0);
775 
776  stream= container_of(w, uv_stream_t, io_watcher);
777 
778  assert(w->fd < (int) loop->nwatchers);
779 
780  e.events = w->pevents;
781  e.fd = w->fd;
782 
783  if (w->events == 0)
784  op = EPOLL_CTL_ADD;
785  else
786  op = EPOLL_CTL_MOD;
787 
788  /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
789  * events, skip the syscall and squelch the events after epoll_wait().
790  */
791  if (epoll_ctl(loop->ep, op, w->fd, &e)) {
792  if (errno != EEXIST)
793  abort();
794 
795  assert(op == EPOLL_CTL_ADD);
796 
797  /* We've reactivated a file descriptor that's been watched before. */
798  if (epoll_ctl(loop->ep, EPOLL_CTL_MOD, w->fd, &e))
799  abort();
800  }
801 
802  w->events = w->pevents;
803  }
804 
805  assert(timeout >= -1);
806  base = loop->time;
807  count = 48; /* Benchmarks suggest this gives the best throughput. */
808  real_timeout = timeout;
809  int nevents = 0;
810 
812  reset_timeout = 1;
813  user_timeout = timeout;
814  timeout = 0;
815  } else {
816  reset_timeout = 0;
817  }
818 
819  nfds = 0;
820  for (;;) {
821  /* Only need to set the provider_entry_time if timeout != 0. The function
822  * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
823  */
824  if (timeout != 0)
826 
827  if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
828  timeout = max_safe_timeout;
829 
830  nfds = epoll_wait(loop->ep, events,
832 
833  /* Update loop->time unconditionally. It's tempting to skip the update when
834  * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
835  * operating system didn't reschedule our process while in the syscall.
836  */
837  base = loop->time;
838  SAVE_ERRNO(uv__update_time(loop));
839  if (nfds == 0) {
840  assert(timeout != -1);
841 
842  if (reset_timeout != 0) {
843  timeout = user_timeout;
844  reset_timeout = 0;
845  }
846 
847  if (timeout == -1)
848  continue;
849 
850  if (timeout == 0)
851  return;
852 
853  /* We may have been inside the system call for longer than |timeout|
854  * milliseconds so we need to update the timestamp to avoid drift.
855  */
856  goto update_timeout;
857  }
858 
859  if (nfds == -1) {
860 
861  if (errno != EINTR)
862  abort();
863 
864  if (reset_timeout != 0) {
865  timeout = user_timeout;
866  reset_timeout = 0;
867  }
868 
869  if (timeout == -1)
870  continue;
871 
872  if (timeout == 0)
873  return;
874 
875  /* Interrupted by a signal. Update timeout and poll again. */
876  goto update_timeout;
877  }
878 
879 
880  assert(loop->watchers != NULL);
881  loop->watchers[loop->nwatchers] = (void*) events;
882  loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
883  for (i = 0; i < nfds; i++) {
884  pe = events + i;
885  fd = pe->fd;
886 
887  /* Skip invalidated events, see uv__platform_invalidate_fd */
888  if (fd == -1)
889  continue;
890 
891  ep = loop->ep;
892  if (pe->is_msg) {
894  continue;
895  }
896 
897  assert(fd >= 0);
898  assert((unsigned) fd < loop->nwatchers);
899 
900  w = loop->watchers[fd];
901 
902  if (w == NULL) {
903  /* File descriptor that we've stopped watching, disarm it.
904  *
905  * Ignore all errors because we may be racing with another thread
906  * when the file descriptor is closed.
907  */
908  epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, pe);
909  continue;
910  }
911 
912  /* Give users only events they're interested in. Prevents spurious
913  * callbacks when previous callback invocation in this loop has stopped
914  * the current watcher. Also, filters out events that users has not
915  * requested us to watch.
916  */
917  pe->events &= w->pevents | POLLERR | POLLHUP;
918 
919  if (pe->events == POLLERR || pe->events == POLLHUP)
920  pe->events |= w->pevents & (POLLIN | POLLOUT);
921 
922  if (pe->events != 0) {
924  w->cb(loop, w, pe->events);
925  nevents++;
926  }
927  }
928  loop->watchers[loop->nwatchers] = NULL;
929  loop->watchers[loop->nwatchers + 1] = NULL;
930 
931  if (reset_timeout != 0) {
932  timeout = user_timeout;
933  reset_timeout = 0;
934  }
935 
936  if (nevents != 0) {
937  if (nfds == ARRAY_SIZE(events) && --count != 0) {
938  /* Poll for more events but don't block this time. */
939  timeout = 0;
940  continue;
941  }
942  return;
943  }
944 
945  if (timeout == 0)
946  return;
947 
948  if (timeout == -1)
949  continue;
950 
951 update_timeout:
952  assert(timeout > 0);
953 
954  real_timeout -= (loop->time - base);
955  if (real_timeout <= 0)
956  return;
957 
958  timeout = real_timeout;
959  }
960 }
961 
962 void uv__set_process_title(const char* title) {
963  /* do nothing */
964 }
965 
967  /*
968  Nullify the msg queue but don't close it because
969  it is still being used by the parent.
970  */
971  loop->ep = NULL;
972 
975 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
#define e(frag)
#define ARRAY_SIZE(a)
lzma_index ** i
Definition: index.h:629
static mcore_handle handle
Definition: asm_mcore.c:8
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
#define NULL
Definition: cris-opc.c:27
#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 ioctl
Definition: sflib.h:62
const char * v
Definition: dsignal.c:12
#define UV__ERR(x)
Definition: errno.h:29
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf stream
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
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 poll
Definition: sflib.h:196
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 args
Definition: mipsasm.c:18
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197
void epoll_queue_close(uv__os390_epoll *lst)
int epoll_wait(uv__os390_epoll *lst, struct epoll_event *events, int maxevents, int timeout)
int epoll_ctl(uv__os390_epoll *lst, int op, int fd, struct epoll_event *event)
uv__os390_epoll * epoll_create1(int flags)
#define EPOLL_CTL_ADD
#define EPOLL_CTL_MOD
#define EPOLL_CTL_DEL
#define TOD_RES
Definition: os390.c:96
unsigned data_area_ptr_assign_type
Definition: os390.c:98
#define ADDR_SIZE(p)
#define PGTH_LEN
Definition: os390.c:90
static int getexe(const int pid, char *buf, size_t len)
Definition: os390.c:151
#define CVTOPCTP_OFFSET
Definition: os390.c:56
uint64_t uv_get_total_memory(void)
Definition: os390.c:283
#define PSA_PTR
Definition: os390.c:38
void uv__fs_event_close(uv_fs_event_t *handle)
Definition: os390.c:631
#define RAXFMCT
Definition: os390.c:86
#define CPCMODEL_LENGTH
Definition: os390.c:74
#define PGTHAPATH
Definition: os390.c:91
void uv_loadavg(double avg[3])
Definition: os390.c:111
static int uv__interface_addresses_v6(uv_interface_address_t **addresses, int *count)
Definition: os390.c:372
void uv__set_process_title(const char *title)
Definition: os390.c:962
int uv_fs_event_stop(uv_fs_event_t *handle)
Definition: os390.c:678
void uv__platform_invalidate_fd(uv_loop_t *loop, int fd)
Definition: os390.c:587
uint64_t uv_get_free_memory(void)
Definition: os390.c:271
int uv_interface_addresses(uv_interface_address_t **addresses, int *count)
Definition: os390.c:456
#define CSD_NUMBER_ONLINE_CPUS
Definition: os390.c:53
void uv__io_poll(uv_loop_t *loop, int timeout)
Definition: os390.c:742
uint64_t uv__hrtime(uv_clocktype_t type)
Definition: os390.c:139
#define CVTRCEP_OFFSET
Definition: os390.c:62
#define RCTLACS_OFFSET
Definition: os390.c:50
int uv__io_check_fd(uv_loop_t *loop, int fd)
Definition: os390.c:610
#define PGTH_CURRENT
Definition: os390.c:89
static int os390_message_queue_handler(uv__os390_epoll *ep)
Definition: os390.c:710
int uv__platform_loop_init(uv_loop_t *loop)
Definition: os390.c:119
int uv_fs_event_start(uv_fs_event_t *handle, uv_fs_event_cb cb, const char *filename, unsigned int flags)
Definition: os390.c:642
int uv_uptime(double *uptime)
Definition: os390.c:314
void uv_free_interface_addresses(uv_interface_address_t *addresses, int count)
Definition: os390.c:578
int uv__io_fork(uv_loop_t *loop)
Definition: os390.c:966
int uv_fs_event_init(uv_loop_t *loop, uv_fs_event_t *handle)
Definition: os390.c:636
#define PSAAOLD
Definition: os390.c:77
#define RCEPOOL_OFFSET
Definition: os390.c:68
int uv_cpu_info(uv_cpu_info_t **cpu_infos, int *count)
Definition: os390.c:328
#define RCEAFC_OFFSET
Definition: os390.c:71
uint64_t uv_get_constrained_memory(void)
Definition: os390.c:295
void uv__platform_loop_delete(uv_loop_t *loop)
Definition: os390.c:131
#define CVT_PTR
Definition: os390.c:37
#define ASCBRSME
Definition: os390.c:80
#define RMCTRCT_OFFSET
Definition: os390.c:59
int uv_exepath(char *buffer, size_t *size)
Definition: os390.c:254
#define CSD_OFFSET
Definition: os390.c:39
int uv_resident_set_memory(size_t *rss)
Definition: os390.c:300
#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_INIT(q)
Definition: queue.h:45
void * QUEUE[2]
Definition: queue.h:21
#define QUEUE_REMOVE(q)
Definition: queue.h:101
#define container_of(ptr, type, member)
Definition: rz_types.h:650
static sockfd
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define ENOENT
Definition: sftypes.h:112
#define EEXIST
Definition: sftypes.h:127
int int32_t
Definition: sftypes.h:33
#define EINTR
Definition: sftypes.h:114
@ SOCK_DGRAM
Definition: sftypes.h:227
#define AF_INET
Definition: sftypes.h:287
#define ENOBUFS
Definition: sftypes.h:165
#define AF_INET6
Definition: sftypes.h:295
unsigned long uint64_t
Definition: sftypes.h:28
#define EALREADY
Definition: sftypes.h:174
_W64 unsigned int uintptr_t
ssize_t uv__strscpy(char *d, const char *s, size_t n)
Definition: strscpy.c:25
Definition: buffer.h:15
Definition: z80asm.h:102
Definition: sftypes.h:75
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 address6
Definition: uv.h:1102
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
int uv__search_path(const char *prog, char *buf, size_t *buflen)
Definition: core.c:1540
int uv__close(int fd)
Definition: core.c:569
uv_clocktype_t
Definition: internal.h:146
#define SAVE_ERRNO(block)
Definition: internal.h:92
char * deref
Definition: os390.c:107
data_area_ptr_assign_type assign
Definition: os390.c:105
Definition: dis.c:32
char * uv__strdup(const char *s)
Definition: uv-common.c:55
void * uv__malloc(size_t size)
Definition: uv-common.c:75
void * uv__calloc(size_t count, size_t size)
Definition: uv-common.c:92
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