Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Utilities / cmlibuv / src / unix / os390.c
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
94 typedef unsigned data_area_ptr_assign_type;
95
96 typedef 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
107 void 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
115 int 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
127 void 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
135 uint64_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
143 static 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  */
156 int 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
172 uint64_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
184 uint64_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
190 uint64_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
201 int 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
215 int 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
229 int 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
273 static 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
396 int 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
571 void 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
580 void 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
603 int 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
624 int 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
630 static 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
654 int 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
680 int 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
720 int uv_fs_event_stop(uv_fs_event_t* handle) {
721   uv__fs_event_stop(handle);
722   return 0;
723 }
724
725
726 void 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
740 static 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
804 void 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
1032 update_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
1044 int 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 }