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