Blame src/unix/os390.c

Packit Service 7c31a4
/* Copyright libuv project contributors. All rights reserved.
Packit Service 7c31a4
 *
Packit Service 7c31a4
 * Permission is hereby granted, free of charge, to any person obtaining a copy
Packit Service 7c31a4
 * of this software and associated documentation files (the "Software"), to
Packit Service 7c31a4
 * deal in the Software without restriction, including without limitation the
Packit Service 7c31a4
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
Packit Service 7c31a4
 * sell copies of the Software, and to permit persons to whom the Software is
Packit Service 7c31a4
 * furnished to do so, subject to the following conditions:
Packit Service 7c31a4
 *
Packit Service 7c31a4
 * The above copyright notice and this permission notice shall be included in
Packit Service 7c31a4
 * all copies or substantial portions of the Software.
Packit Service 7c31a4
 *
Packit Service 7c31a4
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service 7c31a4
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service 7c31a4
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Packit Service 7c31a4
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit Service 7c31a4
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Packit Service 7c31a4
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
Packit Service 7c31a4
 * IN THE SOFTWARE.
Packit Service 7c31a4
 */
Packit Service 7c31a4
Packit Service 7c31a4
#include "internal.h"
Packit Service 7c31a4
#include <sys/ioctl.h>
Packit Service 7c31a4
#include <net/if.h>
Packit Service 7c31a4
#include <utmpx.h>
Packit Service 7c31a4
#include <unistd.h>
Packit Service 7c31a4
#include <sys/ps.h>
Packit Service 7c31a4
#include <builtins.h>
Packit Service 7c31a4
#include <termios.h>
Packit Service 7c31a4
#include <sys/msg.h>
Packit Service 7c31a4
#if defined(__clang__)
Packit Service 7c31a4
#include "csrsic.h"
Packit Service 7c31a4
#else
Packit Service 7c31a4
#include "//'SYS1.SAMPLIB(CSRSIC)'"
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
#define CVT_PTR           0x10
Packit Service 7c31a4
#define PSA_PTR           0x00
Packit Service 7c31a4
#define CSD_OFFSET        0x294
Packit Service 7c31a4
Packit Service 7c31a4
/*
Packit Service 7c31a4
    Long-term average CPU service used by this logical partition,
Packit Service 7c31a4
    in millions of service units per hour. If this value is above
Packit Service 7c31a4
    the partition's defined capacity, the partition will be capped.
Packit Service 7c31a4
    It is calculated using the physical CPU adjustment factor
Packit Service 7c31a4
    (RCTPCPUA) so it may not match other measures of service which
Packit Service 7c31a4
    are based on the logical CPU adjustment factor. It is available
Packit Service 7c31a4
    if the hardware supports LPAR cluster.
Packit Service 7c31a4
*/
Packit Service 7c31a4
#define RCTLACS_OFFSET    0xC4
Packit Service 7c31a4
Packit Service 7c31a4
/* 32-bit count of alive CPUs. This includes both CPs and IFAs */
Packit Service 7c31a4
#define CSD_NUMBER_ONLINE_CPUS        0xD4
Packit Service 7c31a4
Packit Service 7c31a4
/* Address of system resources manager (SRM) control table */
Packit Service 7c31a4
#define CVTOPCTP_OFFSET   0x25C
Packit Service 7c31a4
Packit Service 7c31a4
/* Address of the RCT table */
Packit Service 7c31a4
#define RMCTRCT_OFFSET    0xE4
Packit Service 7c31a4
Packit Service 7c31a4
/* Address of the rsm control and enumeration area. */
Packit Service 7c31a4
#define CVTRCEP_OFFSET    0x490
Packit Service 7c31a4
Packit Service 7c31a4
/*
Packit Service 7c31a4
    Number of frames currently available to system.
Packit Service 7c31a4
    Excluded are frames backing perm storage, frames offline, and bad frames.
Packit Service 7c31a4
*/
Packit Service 7c31a4
#define RCEPOOL_OFFSET    0x004
Packit Service 7c31a4
Packit Service 7c31a4
/* Total number of frames currently on all available frame queues. */
Packit Service 7c31a4
#define RCEAFC_OFFSET     0x088
Packit Service 7c31a4
Packit Service 7c31a4
/* CPC model length from the CSRSI Service. */
Packit Service 7c31a4
#define CPCMODEL_LENGTH   16
Packit Service 7c31a4
Packit Service 7c31a4
/* Pointer to the home (current) ASCB. */
Packit Service 7c31a4
#define PSAAOLD           0x224
Packit Service 7c31a4
Packit Service 7c31a4
/* Pointer to rsm address space block extension. */
Packit Service 7c31a4
#define ASCBRSME          0x16C
Packit Service 7c31a4
Packit Service 7c31a4
/*
Packit Service 7c31a4
    NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE.
Packit Service 7c31a4
    It does not include 2G frames.
Packit Service 7c31a4
*/
Packit Service 7c31a4
#define RAXFMCT           0x2C
Packit Service 7c31a4
Packit Service 7c31a4
/* Thread Entry constants */
Packit Service 7c31a4
#define PGTH_CURRENT  1
Packit Service 7c31a4
#define PGTH_LEN      26
Packit Service 7c31a4
#define PGTHAPATH     0x20
Packit Service 7c31a4
#pragma linkage(BPX4GTH, OS)
Packit Service 7c31a4
#pragma linkage(BPX1GTH, OS)
Packit Service 7c31a4
Packit Service 7c31a4
/* TOD Clock resolution in nanoseconds */
Packit Service 7c31a4
#define TOD_RES 4.096
Packit Service 7c31a4
Packit Service 7c31a4
typedef unsigned data_area_ptr_assign_type;
Packit Service 7c31a4
Packit Service 7c31a4
typedef union {
Packit Service 7c31a4
  struct {
Packit Service 7c31a4
#if defined(_LP64)
Packit Service 7c31a4
    data_area_ptr_assign_type lower;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
    data_area_ptr_assign_type assign;
Packit Service 7c31a4
  };
Packit Service 7c31a4
  char* deref;
Packit Service 7c31a4
} data_area_ptr;
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv_loadavg(double avg[3]) {
Packit Service 7c31a4
  /* TODO: implement the following */
Packit Service 7c31a4
  avg[0] = 0;
Packit Service 7c31a4
  avg[1] = 0;
Packit Service 7c31a4
  avg[2] = 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__platform_loop_init(uv_loop_t* loop) {
Packit Service 7c31a4
  uv__os390_epoll* ep;
Packit Service 7c31a4
Packit Service 7c31a4
  ep = epoll_create1(0);
Packit Service 7c31a4
  loop->ep = ep;
Packit Service 7c31a4
  if (ep == NULL)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__platform_loop_delete(uv_loop_t* loop) {
Packit Service 7c31a4
  if (loop->ep != NULL) {
Packit Service 7c31a4
    epoll_queue_close(loop->ep);
Packit Service 7c31a4
    loop->ep = NULL;
Packit Service 7c31a4
  }
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uint64_t uv__hrtime(uv_clocktype_t type) {
Packit Service 7c31a4
  unsigned long long timestamp;
Packit Service 7c31a4
  __stckf(&timestamp);
Packit Service 7c31a4
  /* Convert to nanoseconds */
Packit Service 7c31a4
  return timestamp / TOD_RES;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
/*
Packit Service 7c31a4
    Get the exe path using the thread entry information
Packit Service 7c31a4
    in the address space.
Packit Service 7c31a4
*/
Packit Service 7c31a4
static int getexe(const int pid, char* buf, size_t len) {
Packit Service 7c31a4
  struct {
Packit Service 7c31a4
    int pid;
Packit Service 7c31a4
    int thid[2];
Packit Service 7c31a4
    char accesspid;
Packit Service 7c31a4
    char accessthid;
Packit Service 7c31a4
    char asid[2];
Packit Service 7c31a4
    char loginname[8];
Packit Service 7c31a4
    char flag;
Packit Service 7c31a4
    char len;
Packit Service 7c31a4
  } Input_data;
Packit Service 7c31a4
Packit Service 7c31a4
  union {
Packit Service 7c31a4
    struct {
Packit Service 7c31a4
      char gthb[4];
Packit Service 7c31a4
      int pid;
Packit Service 7c31a4
      int thid[2];
Packit Service 7c31a4
      char accesspid;
Packit Service 7c31a4
      char accessthid[3];
Packit Service 7c31a4
      int lenused;
Packit Service 7c31a4
      int offsetProcess;
Packit Service 7c31a4
      int offsetConTTY;
Packit Service 7c31a4
      int offsetPath;
Packit Service 7c31a4
      int offsetCommand;
Packit Service 7c31a4
      int offsetFileData;
Packit Service 7c31a4
      int offsetThread;
Packit Service 7c31a4
    } Output_data;
Packit Service 7c31a4
    char buf[2048];
Packit Service 7c31a4
  } Output_buf;
Packit Service 7c31a4
Packit Service 7c31a4
  struct Output_path_type {
Packit Service 7c31a4
    char gthe[4];
Packit Service 7c31a4
    short int len;
Packit Service 7c31a4
    char path[1024];
Packit Service 7c31a4
  };
Packit Service 7c31a4
Packit Service 7c31a4
  int Input_length;
Packit Service 7c31a4
  int Output_length;
Packit Service 7c31a4
  void* Input_address;
Packit Service 7c31a4
  void* Output_address;
Packit Service 7c31a4
  struct Output_path_type* Output_path;
Packit Service 7c31a4
  int rv;
Packit Service 7c31a4
  int rc;
Packit Service 7c31a4
  int rsn;
Packit Service 7c31a4
Packit Service 7c31a4
  Input_length = PGTH_LEN;
Packit Service 7c31a4
  Output_length = sizeof(Output_buf);
Packit Service 7c31a4
  Output_address = &Output_buf;
Packit Service 7c31a4
  Input_address = &Input_data;
Packit Service 7c31a4
  memset(&Input_data, 0, sizeof Input_data);
Packit Service 7c31a4
  Input_data.flag |= PGTHAPATH;
Packit Service 7c31a4
  Input_data.pid = pid;
Packit Service 7c31a4
  Input_data.accesspid = PGTH_CURRENT;
Packit Service 7c31a4
Packit Service 7c31a4
#ifdef _LP64
Packit Service 7c31a4
  BPX4GTH(&Input_length,
Packit Service 7c31a4
          &Input_address,
Packit Service 7c31a4
          &Output_length,
Packit Service 7c31a4
          &Output_address,
Packit Service 7c31a4
          &rv,
Packit Service 7c31a4
          &rc,
Packit Service 7c31a4
          &rsn;;
Packit Service 7c31a4
#else
Packit Service 7c31a4
  BPX1GTH(&Input_length,
Packit Service 7c31a4
          &Input_address,
Packit Service 7c31a4
          &Output_length,
Packit Service 7c31a4
          &Output_address,
Packit Service 7c31a4
          &rv,
Packit Service 7c31a4
          &rc,
Packit Service 7c31a4
          &rsn;;
Packit Service 7c31a4
#endif
Packit Service 7c31a4
Packit Service 7c31a4
  if (rv == -1) {
Packit Service 7c31a4
    errno = rc;
Packit Service 7c31a4
    return -1;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* Check highest byte to ensure data availability */
Packit Service 7c31a4
  assert(((Output_buf.Output_data.offsetPath >>24) & 0xFF) == 'A');
Packit Service 7c31a4
Packit Service 7c31a4
  /* Get the offset from the lowest 3 bytes */
Packit Service 7c31a4
  Output_path = (struct Output_path_type*) ((char*) (&Output_buf) +
Packit Service 7c31a4
      (Output_buf.Output_data.offsetPath & 0x00FFFFFF));
Packit Service 7c31a4
Packit Service 7c31a4
  if (Output_path->len >= len) {
Packit Service 7c31a4
    errno = ENOBUFS;
Packit Service 7c31a4
    return -1;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  uv__strscpy(buf, Output_path->path, len);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
/*
Packit Service 7c31a4
 * We could use a static buffer for the path manipulations that we need outside
Packit Service 7c31a4
 * of the function, but this function could be called by multiple consumers and
Packit Service 7c31a4
 * we don't want to potentially create a race condition in the use of snprintf.
Packit Service 7c31a4
 * There is no direct way of getting the exe path in zOS - either through /procfs
Packit Service 7c31a4
 * or through some libc APIs. The below approach is to parse the argv[0]'s pattern
Packit Service 7c31a4
 * and use it in conjunction with PATH environment variable to craft one.
Packit Service 7c31a4
 */
Packit Service 7c31a4
int uv_exepath(char* buffer, size_t* size) {
Packit Service 7c31a4
  int res;
Packit Service 7c31a4
  char args[PATH_MAX];
Packit Service 7c31a4
  char abspath[PATH_MAX];
Packit Service 7c31a4
  size_t abspath_size;
Packit Service 7c31a4
  int pid;
Packit Service 7c31a4
Packit Service 7c31a4
  if (buffer == NULL || size == NULL || *size == 0)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  pid = getpid();
Packit Service 7c31a4
  res = getexe(pid, args, sizeof(args));
Packit Service 7c31a4
  if (res < 0)
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  /*
Packit Service 7c31a4
   * Possibilities for args:
Packit Service 7c31a4
   * i) an absolute path such as: /home/user/myprojects/nodejs/node
Packit Service 7c31a4
   * ii) a relative path such as: ./node or ../myprojects/nodejs/node
Packit Service 7c31a4
   * iii) a bare filename such as "node", after exporting PATH variable
Packit Service 7c31a4
   *     to its location.
Packit Service 7c31a4
   */
Packit Service 7c31a4
Packit Service 7c31a4
  /* Case i) and ii) absolute or relative paths */
Packit Service 7c31a4
  if (strchr(args, '/') != NULL) {
Packit Service 7c31a4
    if (realpath(args, abspath) != abspath)
Packit Service 7c31a4
      return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
    abspath_size = strlen(abspath);
Packit Service 7c31a4
Packit Service 7c31a4
    *size -= 1;
Packit Service 7c31a4
    if (*size > abspath_size)
Packit Service 7c31a4
      *size = abspath_size;
Packit Service 7c31a4
Packit Service 7c31a4
    memcpy(buffer, abspath, *size);
Packit Service 7c31a4
    buffer[*size] = '\0';
Packit Service 7c31a4
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
  } else {
Packit Service 7c31a4
    /* Case iii). Search PATH environment variable */
Packit Service 7c31a4
    char trypath[PATH_MAX];
Packit Service 7c31a4
    char* clonedpath = NULL;
Packit Service 7c31a4
    char* token = NULL;
Packit Service 7c31a4
    char* path = getenv("PATH");
Packit Service 7c31a4
Packit Service 7c31a4
    if (path == NULL)
Packit Service 7c31a4
      return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
    clonedpath = uv__strdup(path);
Packit Service 7c31a4
    if (clonedpath == NULL)
Packit Service 7c31a4
      return UV_ENOMEM;
Packit Service 7c31a4
Packit Service 7c31a4
    token = strtok(clonedpath, ":");
Packit Service 7c31a4
    while (token != NULL) {
Packit Service 7c31a4
      snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args);
Packit Service 7c31a4
      if (realpath(trypath, abspath) == abspath) {
Packit Service 7c31a4
        /* Check the match is executable */
Packit Service 7c31a4
        if (access(abspath, X_OK) == 0) {
Packit Service 7c31a4
          abspath_size = strlen(abspath);
Packit Service 7c31a4
Packit Service 7c31a4
          *size -= 1;
Packit Service 7c31a4
          if (*size > abspath_size)
Packit Service 7c31a4
            *size = abspath_size;
Packit Service 7c31a4
Packit Service 7c31a4
          memcpy(buffer, abspath, *size);
Packit Service 7c31a4
          buffer[*size] = '\0';
Packit Service 7c31a4
Packit Service 7c31a4
          uv__free(clonedpath);
Packit Service 7c31a4
          return 0;
Packit Service 7c31a4
        }
Packit Service 7c31a4
      }
Packit Service 7c31a4
      token = strtok(NULL, ":");
Packit Service 7c31a4
    }
Packit Service 7c31a4
    uv__free(clonedpath);
Packit Service 7c31a4
Packit Service 7c31a4
    /* Out of tokens (path entries), and no match found */
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
  }
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uint64_t uv_get_free_memory(void) {
Packit Service 7c31a4
  uint64_t freeram;
Packit Service 7c31a4
Packit Service 7c31a4
  data_area_ptr cvt = {0};
Packit Service 7c31a4
  data_area_ptr rcep = {0};
Packit Service 7c31a4
  cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
Packit Service 7c31a4
  rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
Packit Service 7c31a4
  freeram = *((uint64_t*)(rcep.deref + RCEAFC_OFFSET)) * 4;
Packit Service 7c31a4
  return freeram;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uint64_t uv_get_total_memory(void) {
Packit Service 7c31a4
  uint64_t totalram;
Packit Service 7c31a4
Packit Service 7c31a4
  data_area_ptr cvt = {0};
Packit Service 7c31a4
  data_area_ptr rcep = {0};
Packit Service 7c31a4
  cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
Packit Service 7c31a4
  rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
Packit Service 7c31a4
  totalram = *((uint64_t*)(rcep.deref + RCEPOOL_OFFSET)) * 4;
Packit Service 7c31a4
  return totalram;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
uint64_t uv_get_constrained_memory(void) {
Packit Service 7c31a4
  return 0;  /* Memory constraints are unknown. */
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_resident_set_memory(size_t* rss) {
Packit Service 7c31a4
  char* ascb;
Packit Service 7c31a4
  char* rax;
Packit Service 7c31a4
  size_t nframes;
Packit Service 7c31a4
Packit Service 7c31a4
  ascb  = *(char* __ptr32 *)(PSA_PTR + PSAAOLD);
Packit Service 7c31a4
  rax = *(char* __ptr32 *)(ascb + ASCBRSME);
Packit Service 7c31a4
  nframes = *(unsigned int*)(rax + RAXFMCT);
Packit Service 7c31a4
Packit Service 7c31a4
  *rss = nframes * sysconf(_SC_PAGESIZE);
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_uptime(double* uptime) {
Packit Service 7c31a4
  struct utmpx u ;
Packit Service 7c31a4
  struct utmpx *v;
Packit Service 7c31a4
  time64_t t;
Packit Service 7c31a4
Packit Service 7c31a4
  u.ut_type = BOOT_TIME;
Packit Service 7c31a4
  v = getutxid(&u);
Packit Service 7c31a4
  if (v == NULL)
Packit Service 7c31a4
    return -1;
Packit Service 7c31a4
  *uptime = difftime64(time64(&t), v->ut_tv.tv_sec);
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
Packit Service 7c31a4
  uv_cpu_info_t* cpu_info;
Packit Service 7c31a4
  int idx;
Packit Service 7c31a4
  siv1v2 info;
Packit Service 7c31a4
  data_area_ptr cvt = {0};
Packit Service 7c31a4
  data_area_ptr csd = {0};
Packit Service 7c31a4
  data_area_ptr rmctrct = {0};
Packit Service 7c31a4
  data_area_ptr cvtopctp = {0};
Packit Service 7c31a4
  int cpu_usage_avg;
Packit Service 7c31a4
Packit Service 7c31a4
  cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
Packit Service 7c31a4
Packit Service 7c31a4
  csd.assign = *((data_area_ptr_assign_type *) (cvt.deref + CSD_OFFSET));
Packit Service 7c31a4
  cvtopctp.assign = *((data_area_ptr_assign_type *) (cvt.deref + CVTOPCTP_OFFSET));
Packit Service 7c31a4
  rmctrct.assign = *((data_area_ptr_assign_type *) (cvtopctp.deref + RMCTRCT_OFFSET));
Packit Service 7c31a4
Packit Service 7c31a4
  *count = *((int*) (csd.deref + CSD_NUMBER_ONLINE_CPUS));
Packit Service 7c31a4
  cpu_usage_avg = *((unsigned short int*) (rmctrct.deref + RCTLACS_OFFSET));
Packit Service 7c31a4
Packit Service 7c31a4
  *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t));
Packit Service 7c31a4
  if (!*cpu_infos)
Packit Service 7c31a4
    return UV_ENOMEM;
Packit Service 7c31a4
Packit Service 7c31a4
  cpu_info = *cpu_infos;
Packit Service 7c31a4
  idx = 0;
Packit Service 7c31a4
  while (idx < *count) {
Packit Service 7c31a4
    cpu_info->speed = *(int*)(info.siv1v2si22v1.si22v1cpucapability);
Packit Service 7c31a4
    cpu_info->model = uv__malloc(CPCMODEL_LENGTH + 1);
Packit Service 7c31a4
    memset(cpu_info->model, '\0', CPCMODEL_LENGTH + 1);
Packit Service 7c31a4
    memcpy(cpu_info->model, info.siv1v2si11v1.si11v1cpcmodel, CPCMODEL_LENGTH);
Packit Service 7c31a4
    cpu_info->cpu_times.user = cpu_usage_avg;
Packit Service 7c31a4
    /* TODO: implement the following */
Packit Service 7c31a4
    cpu_info->cpu_times.sys = 0;
Packit Service 7c31a4
    cpu_info->cpu_times.idle = 0;
Packit Service 7c31a4
    cpu_info->cpu_times.irq = 0;
Packit Service 7c31a4
    cpu_info->cpu_times.nice = 0;
Packit Service 7c31a4
    ++cpu_info;
Packit Service 7c31a4
    ++idx;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
Packit Service 7c31a4
                                      int* count) {
Packit Service 7c31a4
  uv_interface_address_t* address;
Packit Service 7c31a4
  int sockfd;
Packit Service 7c31a4
  int maxsize;
Packit Service 7c31a4
  __net_ifconf6header_t ifc;
Packit Service 7c31a4
  __net_ifconf6entry_t* ifr;
Packit Service 7c31a4
  __net_ifconf6entry_t* p;
Packit Service 7c31a4
  __net_ifconf6entry_t flg;
Packit Service 7c31a4
Packit Service 7c31a4
  *count = 0;
Packit Service 7c31a4
  /* Assume maximum buffer size allowable */
Packit Service 7c31a4
  maxsize = 16384;
Packit Service 7c31a4
Packit Service 7c31a4
  if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  ifc.__nif6h_version = 1;
Packit Service 7c31a4
  ifc.__nif6h_buflen = maxsize;
Packit Service 7c31a4
  ifc.__nif6h_buffer = uv__calloc(1, maxsize);;
Packit Service 7c31a4
Packit Service 7c31a4
  if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) {
Packit Service 7c31a4
    uv__close(sockfd);
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
  *count = 0;
Packit Service 7c31a4
  ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer);
Packit Service 7c31a4
  while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) {
Packit Service 7c31a4
    p = ifr;
Packit Service 7c31a4
    ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
Packit Service 7c31a4
          p->__nif6e_addr.sin6_family == AF_INET))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    ++(*count);
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* Alloc the return interface structs */
Packit Service 7c31a4
  *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
Packit Service 7c31a4
  if (!(*addresses)) {
Packit Service 7c31a4
    uv__close(sockfd);
Packit Service 7c31a4
    return UV_ENOMEM;
Packit Service 7c31a4
  }
Packit Service 7c31a4
  address = *addresses;
Packit Service 7c31a4
Packit Service 7c31a4
  ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer);
Packit Service 7c31a4
  while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) {
Packit Service 7c31a4
    p = ifr;
Packit Service 7c31a4
    ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
Packit Service 7c31a4
          p->__nif6e_addr.sin6_family == AF_INET))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    /* All conditions above must match count loop */
Packit Service 7c31a4
Packit Service 7c31a4
    address->name = uv__strdup(p->__nif6e_name);
Packit Service 7c31a4
Packit Service 7c31a4
    if (p->__nif6e_addr.sin6_family == AF_INET6)
Packit Service 7c31a4
      address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr);
Packit Service 7c31a4
    else
Packit Service 7c31a4
      address->address.address4 = *((struct sockaddr_in*) &p->__nif6e_addr);
Packit Service 7c31a4
Packit Service 7c31a4
    /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
Packit Service 7c31a4
Packit Service 7c31a4
    address->is_internal = flg.__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0;
Packit Service 7c31a4
    memset(address->phys_addr, 0, sizeof(address->phys_addr));
Packit Service 7c31a4
    address++;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  uv__close(sockfd);
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
Packit Service 7c31a4
  uv_interface_address_t* address;
Packit Service 7c31a4
  int sockfd;
Packit Service 7c31a4
  int maxsize;
Packit Service 7c31a4
  struct ifconf ifc;
Packit Service 7c31a4
  struct ifreq flg;
Packit Service 7c31a4
  struct ifreq* ifr;
Packit Service 7c31a4
  struct ifreq* p;
Packit Service 7c31a4
  int count_v6;
Packit Service 7c31a4
Packit Service 7c31a4
  *count = 0;
Packit Service 7c31a4
  *addresses = NULL;
Packit Service 7c31a4
Packit Service 7c31a4
  /* get the ipv6 addresses first */
Packit Service 7c31a4
  uv_interface_address_t* addresses_v6;
Packit Service 7c31a4
  uv__interface_addresses_v6(&addresses_v6, &count_v6);
Packit Service 7c31a4
Packit Service 7c31a4
  /* now get the ipv4 addresses */
Packit Service 7c31a4
Packit Service 7c31a4
  /* Assume maximum buffer size allowable */
Packit Service 7c31a4
  maxsize = 16384;
Packit Service 7c31a4
Packit Service 7c31a4
  sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
Packit Service 7c31a4
  if (0 > sockfd)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  ifc.ifc_req = uv__calloc(1, maxsize);
Packit Service 7c31a4
  ifc.ifc_len = maxsize;
Packit Service 7c31a4
  if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
Packit Service 7c31a4
    uv__close(sockfd);
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
#define MAX(a,b) (((a)>(b))?(a):(b))
Packit Service 7c31a4
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
Packit Service 7c31a4
Packit Service 7c31a4
  /* Count all up and running ipv4/ipv6 addresses */
Packit Service 7c31a4
  ifr = ifc.ifc_req;
Packit Service 7c31a4
  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
Packit Service 7c31a4
    p = ifr;
Packit Service 7c31a4
    ifr = (struct ifreq*)
Packit Service 7c31a4
      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(p->ifr_addr.sa_family == AF_INET6 ||
Packit Service 7c31a4
          p->ifr_addr.sa_family == AF_INET))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
Packit Service 7c31a4
    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
Packit Service 7c31a4
      uv__close(sockfd);
Packit Service 7c31a4
      return UV__ERR(errno);
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    (*count)++;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  if (*count == 0) {
Packit Service 7c31a4
    uv__close(sockfd);
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  /* Alloc the return interface structs */
Packit Service 7c31a4
  *addresses = uv__malloc((*count + count_v6) *
Packit Service 7c31a4
                          sizeof(uv_interface_address_t));
Packit Service 7c31a4
Packit Service 7c31a4
  if (!(*addresses)) {
Packit Service 7c31a4
    uv__close(sockfd);
Packit Service 7c31a4
    return UV_ENOMEM;
Packit Service 7c31a4
  }
Packit Service 7c31a4
  address = *addresses;
Packit Service 7c31a4
Packit Service 7c31a4
  /* copy over the ipv6 addresses */
Packit Service 7c31a4
  memcpy(address, addresses_v6, count_v6 * sizeof(uv_interface_address_t));
Packit Service 7c31a4
  address += count_v6;
Packit Service 7c31a4
  *count += count_v6;
Packit Service 7c31a4
  uv__free(addresses_v6);
Packit Service 7c31a4
Packit Service 7c31a4
  ifr = ifc.ifc_req;
Packit Service 7c31a4
  while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
Packit Service 7c31a4
    p = ifr;
Packit Service 7c31a4
    ifr = (struct ifreq*)
Packit Service 7c31a4
      ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(p->ifr_addr.sa_family == AF_INET6 ||
Packit Service 7c31a4
          p->ifr_addr.sa_family == AF_INET))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
Packit Service 7c31a4
    if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
Packit Service 7c31a4
      uv__close(sockfd);
Packit Service 7c31a4
      return UV_ENOSYS;
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
    /* All conditions above must match count loop */
Packit Service 7c31a4
Packit Service 7c31a4
    address->name = uv__strdup(p->ifr_name);
Packit Service 7c31a4
Packit Service 7c31a4
    if (p->ifr_addr.sa_family == AF_INET6) {
Packit Service 7c31a4
      address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
Packit Service 7c31a4
    } else {
Packit Service 7c31a4
      address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
Packit Service 7c31a4
    memset(address->phys_addr, 0, sizeof(address->phys_addr));
Packit Service 7c31a4
    address++;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
#undef ADDR_SIZE
Packit Service 7c31a4
#undef MAX
Packit Service 7c31a4
Packit Service 7c31a4
  uv__close(sockfd);
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv_free_interface_addresses(uv_interface_address_t* addresses,
Packit Service 7c31a4
                                 int count) {
Packit Service 7c31a4
  int i;
Packit Service 7c31a4
  for (i = 0; i < count; ++i)
Packit Service 7c31a4
    uv__free(addresses[i].name);
Packit Service 7c31a4
  uv__free(addresses);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
Packit Service 7c31a4
  struct epoll_event* events;
Packit Service 7c31a4
  struct epoll_event dummy;
Packit Service 7c31a4
  uintptr_t i;
Packit Service 7c31a4
  uintptr_t nfds;
Packit Service 7c31a4
Packit Service 7c31a4
  assert(loop->watchers != NULL);
Packit Service 7c31a4
  assert(fd >= 0);
Packit Service 7c31a4
Packit Service 7c31a4
  events = (struct epoll_event*) loop->watchers[loop->nwatchers];
Packit Service 7c31a4
  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
Packit Service 7c31a4
  if (events != NULL)
Packit Service 7c31a4
    /* Invalidate events with same file descriptor */
Packit Service 7c31a4
    for (i = 0; i < nfds; i++)
Packit Service 7c31a4
      if ((int) events[i].fd == fd)
Packit Service 7c31a4
        events[i].fd = -1;
Packit Service 7c31a4
Packit Service 7c31a4
  /* Remove the file descriptor from the epoll. */
Packit Service 7c31a4
  if (loop->ep != NULL)
Packit Service 7c31a4
    epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, &dummy);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv__io_check_fd(uv_loop_t* loop, int fd) {
Packit Service 7c31a4
  struct pollfd p[1];
Packit Service 7c31a4
  int rv;
Packit Service 7c31a4
Packit Service 7c31a4
  p[0].fd = fd;
Packit Service 7c31a4
  p[0].events = POLLIN;
Packit Service 7c31a4
Packit Service 7c31a4
  do
Packit Service 7c31a4
    rv = poll(p, 1, 0);
Packit Service 7c31a4
  while (rv == -1 && errno == EINTR);
Packit Service 7c31a4
Packit Service 7c31a4
  if (rv == -1)
Packit Service 7c31a4
    abort();
Packit Service 7c31a4
Packit Service 7c31a4
  if (p[0].revents & POLLNVAL)
Packit Service 7c31a4
    return -1;
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__fs_event_close(uv_fs_event_t* handle) {
Packit Service 7c31a4
  uv_fs_event_stop(handle);
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
Packit Service 7c31a4
  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
Packit Service 7c31a4
                      const char* filename, unsigned int flags) {
Packit Service 7c31a4
  uv__os390_epoll* ep;
Packit Service 7c31a4
  _RFIS reg_struct;
Packit Service 7c31a4
  char* path;
Packit Service 7c31a4
  int rc;
Packit Service 7c31a4
Packit Service 7c31a4
  if (uv__is_active(handle))
Packit Service 7c31a4
    return UV_EINVAL;
Packit Service 7c31a4
Packit Service 7c31a4
  ep = handle->loop->ep;
Packit Service 7c31a4
  assert(ep->msg_queue != -1);
Packit Service 7c31a4
Packit Service 7c31a4
  reg_struct.__rfis_cmd  = _RFIS_REG;
Packit Service 7c31a4
  reg_struct.__rfis_qid  = ep->msg_queue;
Packit Service 7c31a4
  reg_struct.__rfis_type = 1;
Packit Service 7c31a4
  memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle));
Packit Service 7c31a4
Packit Service 7c31a4
  path = uv__strdup(filename);
Packit Service 7c31a4
  if (path == NULL)
Packit Service 7c31a4
    return UV_ENOMEM;
Packit Service 7c31a4
Packit Service 7c31a4
  rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
Packit Service 7c31a4
  if (rc != 0)
Packit Service 7c31a4
    return UV__ERR(errno);
Packit Service 7c31a4
Packit Service 7c31a4
  uv__handle_start(handle);
Packit Service 7c31a4
  handle->path = path;
Packit Service 7c31a4
  handle->cb = cb;
Packit Service 7c31a4
  memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok,
Packit Service 7c31a4
         sizeof(handle->rfis_rftok));
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
int uv_fs_event_stop(uv_fs_event_t* handle) {
Packit Service 7c31a4
  uv__os390_epoll* ep;
Packit Service 7c31a4
  _RFIS reg_struct;
Packit Service 7c31a4
  int rc;
Packit Service 7c31a4
Packit Service 7c31a4
  if (!uv__is_active(handle))
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  ep = handle->loop->ep;
Packit Service 7c31a4
  assert(ep->msg_queue != -1);
Packit Service 7c31a4
Packit Service 7c31a4
  reg_struct.__rfis_cmd  = _RFIS_UNREG;
Packit Service 7c31a4
  reg_struct.__rfis_qid  = ep->msg_queue;
Packit Service 7c31a4
  reg_struct.__rfis_type = 1;
Packit Service 7c31a4
  memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
Packit Service 7c31a4
         sizeof(handle->rfis_rftok));
Packit Service 7c31a4
Packit Service 7c31a4
  /*
Packit Service 7c31a4
   * This call will take "/" as the path argument in case we
Packit Service 7c31a4
   * don't care to supply the correct path. The system will simply
Packit Service 7c31a4
   * ignore it.
Packit Service 7c31a4
   */
Packit Service 7c31a4
  rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
Packit Service 7c31a4
  if (rc != 0 && errno != EALREADY && errno != ENOENT)
Packit Service 7c31a4
    abort();
Packit Service 7c31a4
Packit Service 7c31a4
  uv__handle_stop(handle);
Packit Service 7c31a4
Packit Service 7c31a4
  return 0;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
static int os390_message_queue_handler(uv__os390_epoll* ep) {
Packit Service 7c31a4
  uv_fs_event_t* handle;
Packit Service 7c31a4
  int msglen;
Packit Service 7c31a4
  int events;
Packit Service 7c31a4
  _RFIM msg;
Packit Service 7c31a4
Packit Service 7c31a4
  if (ep->msg_queue == -1)
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT);
Packit Service 7c31a4
Packit Service 7c31a4
  if (msglen == -1 && errno == ENOMSG)
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  if (msglen == -1)
Packit Service 7c31a4
    abort();
Packit Service 7c31a4
Packit Service 7c31a4
  events = 0;
Packit Service 7c31a4
  if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE)
Packit Service 7c31a4
    events = UV_CHANGE;
Packit Service 7c31a4
  else if (msg.__rfim_event == _RFIM_RENAME)
Packit Service 7c31a4
    events = UV_RENAME;
Packit Service 7c31a4
  else
Packit Service 7c31a4
    /* Some event that we are not interested in. */
Packit Service 7c31a4
    return 0;
Packit Service 7c31a4
Packit Service 7c31a4
  handle = *(uv_fs_event_t**)(msg.__rfim_utok);
Packit Service 7c31a4
  handle->cb(handle, uv__basename_r(handle->path), events, 0);
Packit Service 7c31a4
  return 1;
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
void uv__io_poll(uv_loop_t* loop, int timeout) {
Packit Service 7c31a4
  static const int max_safe_timeout = 1789569;
Packit Service 7c31a4
  struct epoll_event events[1024];
Packit Service 7c31a4
  struct epoll_event* pe;
Packit Service 7c31a4
  struct epoll_event e;
Packit Service 7c31a4
  uv__os390_epoll* ep;
Packit Service 7c31a4
  int real_timeout;
Packit Service 7c31a4
  QUEUE* q;
Packit Service 7c31a4
  uv__io_t* w;
Packit Service 7c31a4
  uint64_t base;
Packit Service 7c31a4
  int count;
Packit Service 7c31a4
  int nfds;
Packit Service 7c31a4
  int fd;
Packit Service 7c31a4
  int op;
Packit Service 7c31a4
  int i;
Packit Service 7c31a4
Packit Service 7c31a4
  if (loop->nfds == 0) {
Packit Service 7c31a4
    assert(QUEUE_EMPTY(&loop->watcher_queue));
Packit Service 7c31a4
    return;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  while (!QUEUE_EMPTY(&loop->watcher_queue)) {
Packit Service 7c31a4
    uv_stream_t* stream;
Packit Service 7c31a4
Packit Service 7c31a4
    q = QUEUE_HEAD(&loop->watcher_queue);
Packit Service 7c31a4
    QUEUE_REMOVE(q);
Packit Service 7c31a4
    QUEUE_INIT(q);
Packit Service 7c31a4
    w = QUEUE_DATA(q, uv__io_t, watcher_queue);
Packit Service 7c31a4
Packit Service 7c31a4
    assert(w->pevents != 0);
Packit Service 7c31a4
    assert(w->fd >= 0);
Packit Service 7c31a4
Packit Service 7c31a4
    stream= container_of(w, uv_stream_t, io_watcher);
Packit Service 7c31a4
Packit Service 7c31a4
    assert(w->fd < (int) loop->nwatchers);
Packit Service 7c31a4
Packit Service 7c31a4
    e.events = w->pevents;
Packit Service 7c31a4
    e.fd = w->fd;
Packit Service 7c31a4
Packit Service 7c31a4
    if (w->events == 0)
Packit Service 7c31a4
      op = EPOLL_CTL_ADD;
Packit Service 7c31a4
    else
Packit Service 7c31a4
      op = EPOLL_CTL_MOD;
Packit Service 7c31a4
Packit Service 7c31a4
    /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
Packit Service 7c31a4
     * events, skip the syscall and squelch the events after epoll_wait().
Packit Service 7c31a4
     */
Packit Service 7c31a4
    if (epoll_ctl(loop->ep, op, w->fd, &e)) {
Packit Service 7c31a4
      if (errno != EEXIST)
Packit Service 7c31a4
        abort();
Packit Service 7c31a4
Packit Service 7c31a4
      assert(op == EPOLL_CTL_ADD);
Packit Service 7c31a4
Packit Service 7c31a4
      /* We've reactivated a file descriptor that's been watched before. */
Packit Service 7c31a4
      if (epoll_ctl(loop->ep, EPOLL_CTL_MOD, w->fd, &e))
Packit Service 7c31a4
        abort();
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    w->events = w->pevents;
Packit Service 7c31a4
  }
Packit Service 7c31a4
Packit Service 7c31a4
  assert(timeout >= -1);
Packit Service 7c31a4
  base = loop->time;
Packit Service 7c31a4
  count = 48; /* Benchmarks suggest this gives the best throughput. */
Packit Service 7c31a4
  real_timeout = timeout;
Packit Service 7c31a4
  int nevents = 0;
Packit Service 7c31a4
Packit Service 7c31a4
  nfds = 0;
Packit Service 7c31a4
  for (;;) {
Packit Service 7c31a4
    if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
Packit Service 7c31a4
      timeout = max_safe_timeout;
Packit Service 7c31a4
Packit Service 7c31a4
    nfds = epoll_wait(loop->ep, events,
Packit Service 7c31a4
                      ARRAY_SIZE(events), timeout);
Packit Service 7c31a4
Packit Service 7c31a4
    /* Update loop->time unconditionally. It's tempting to skip the update when
Packit Service 7c31a4
     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
Packit Service 7c31a4
     * operating system didn't reschedule our process while in the syscall.
Packit Service 7c31a4
     */
Packit Service 7c31a4
    base = loop->time;
Packit Service 7c31a4
    SAVE_ERRNO(uv__update_time(loop));
Packit Service 7c31a4
    if (nfds == 0) {
Packit Service 7c31a4
      assert(timeout != -1);
Packit Service 7c31a4
Packit Service 7c31a4
      if (timeout > 0) {
Packit Service 7c31a4
        timeout = real_timeout - timeout;
Packit Service 7c31a4
        continue;
Packit Service 7c31a4
      }
Packit Service 7c31a4
Packit Service 7c31a4
      return;
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    if (nfds == -1) {
Packit Service 7c31a4
Packit Service 7c31a4
      if (errno != EINTR)
Packit Service 7c31a4
        abort();
Packit Service 7c31a4
Packit Service 7c31a4
      if (timeout == -1)
Packit Service 7c31a4
        continue;
Packit Service 7c31a4
Packit Service 7c31a4
      if (timeout == 0)
Packit Service 7c31a4
        return;
Packit Service 7c31a4
Packit Service 7c31a4
      /* Interrupted by a signal. Update timeout and poll again. */
Packit Service 7c31a4
      goto update_timeout;
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
Packit Service 7c31a4
    assert(loop->watchers != NULL);
Packit Service 7c31a4
    loop->watchers[loop->nwatchers] = (void*) events;
Packit Service 7c31a4
    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
Packit Service 7c31a4
    for (i = 0; i < nfds; i++) {
Packit Service 7c31a4
      pe = events + i;
Packit Service 7c31a4
      fd = pe->fd;
Packit Service 7c31a4
Packit Service 7c31a4
      /* Skip invalidated events, see uv__platform_invalidate_fd */
Packit Service 7c31a4
      if (fd == -1)
Packit Service 7c31a4
        continue;
Packit Service 7c31a4
Packit Service 7c31a4
      ep = loop->ep;
Packit Service 7c31a4
      if (pe->is_msg) {
Packit Service 7c31a4
        os390_message_queue_handler(ep);
Packit Service 7c31a4
        continue;
Packit Service 7c31a4
      }
Packit Service 7c31a4
Packit Service 7c31a4
      assert(fd >= 0);
Packit Service 7c31a4
      assert((unsigned) fd < loop->nwatchers);
Packit Service 7c31a4
Packit Service 7c31a4
      w = loop->watchers[fd];
Packit Service 7c31a4
Packit Service 7c31a4
      if (w == NULL) {
Packit Service 7c31a4
        /* File descriptor that we've stopped watching, disarm it.
Packit Service 7c31a4
         *
Packit Service 7c31a4
         * Ignore all errors because we may be racing with another thread
Packit Service 7c31a4
         * when the file descriptor is closed.
Packit Service 7c31a4
         */
Packit Service 7c31a4
        epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, pe);
Packit Service 7c31a4
        continue;
Packit Service 7c31a4
      }
Packit Service 7c31a4
Packit Service 7c31a4
      /* Give users only events they're interested in. Prevents spurious
Packit Service 7c31a4
       * callbacks when previous callback invocation in this loop has stopped
Packit Service 7c31a4
       * the current watcher. Also, filters out events that users has not
Packit Service 7c31a4
       * requested us to watch.
Packit Service 7c31a4
       */
Packit Service 7c31a4
      pe->events &= w->pevents | POLLERR | POLLHUP;
Packit Service 7c31a4
Packit Service 7c31a4
      if (pe->events == POLLERR || pe->events == POLLHUP)
Packit Service 7c31a4
        pe->events |= w->pevents & (POLLIN | POLLOUT);
Packit Service 7c31a4
Packit Service 7c31a4
      if (pe->events != 0) {
Packit Service 7c31a4
        w->cb(loop, w, pe->events);
Packit Service 7c31a4
        nevents++;
Packit Service 7c31a4
      }
Packit Service 7c31a4
    }
Packit Service 7c31a4
    loop->watchers[loop->nwatchers] = NULL;
Packit Service 7c31a4
    loop->watchers[loop->nwatchers + 1] = NULL;
Packit Service 7c31a4
Packit Service 7c31a4
    if (nevents != 0) {
Packit Service 7c31a4
      if (nfds == ARRAY_SIZE(events) && --count != 0) {
Packit Service 7c31a4
        /* Poll for more events but don't block this time. */
Packit Service 7c31a4
        timeout = 0;
Packit Service 7c31a4
        continue;
Packit Service 7c31a4
      }
Packit Service 7c31a4
      return;
Packit Service 7c31a4
    }
Packit Service 7c31a4
Packit Service 7c31a4
    if (timeout == 0)
Packit Service 7c31a4
      return;
Packit Service 7c31a4
Packit Service 7c31a4
    if (timeout == -1)
Packit Service 7c31a4
      continue;
Packit Service 7c31a4
Packit Service 7c31a4
update_timeout:
Packit Service 7c31a4
    assert(timeout > 0);
Packit Service 7c31a4
Packit Service 7c31a4
    real_timeout -= (loop->time - base);
Packit Service 7c31a4
    if (real_timeout <= 0)
Packit Service 7c31a4
      return;
Packit Service 7c31a4
Packit Service 7c31a4
    timeout = real_timeout;
Packit Service 7c31a4
  }
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
void uv__set_process_title(const char* title) {
Packit Service 7c31a4
  /* do nothing */
Packit Service 7c31a4
}
Packit Service 7c31a4
Packit Service 7c31a4
int uv__io_fork(uv_loop_t* loop) {
Packit Service 7c31a4
  /*
Packit Service 7c31a4
    Nullify the msg queue but don't close it because
Packit Service 7c31a4
    it is still being used by the parent.
Packit Service 7c31a4
  */
Packit Service 7c31a4
  loop->ep = NULL;
Packit Service 7c31a4
Packit Service 7c31a4
  uv__platform_loop_delete(loop);
Packit Service 7c31a4
  return uv__platform_loop_init(loop);
Packit Service 7c31a4
}