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(×tamp); 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), ®_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), ®_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