void shmCtlImpl()

in cachelib/shm/SysVShmSegment.cpp [141:185]


void shmCtlImpl(int shmid, int cmd, shmid_ds* buf) {
  if (cmd != IPC_STAT && cmd != IPC_RMID && cmd != IPC_SET && cmd != SHM_LOCK) {
    util::throwSystemError(EINVAL, "Unsupported shmctl operation");
  }

  const int ret = shmctl(shmid, cmd, buf);
  if (ret == 0) {
    return;
  }

  switch (errno) {
  // EOVERFLOW and EACCES make sense only for stat
  case EOVERFLOW:
  case EACCES:
    XDCHECK_EQ(cmd, IPC_STAT);
    if (cmd != IPC_STAT) {
      util::throwSystemError(errno, "Invalid errno");
    }
  case EFAULT:
    util::throwSystemError(errno);
    break;
  case EINVAL:
  case EIDRM:
    // EINVAL can only mean invalid shmid in our case.
    util::throwSystemError(EIDRM, "Segment does not exist");
    break;
  case EPERM:
    if (cmd != IPC_RMID && cmd != IPC_SET) {
      XDCHECK(false);
      util::throwSystemError(errno, "Invalid errno");
    }
    util::throwSystemError(errno);
    break;
  case ENOMEM:
    XDCHECK_EQ(cmd, SHM_LOCK);
    if (cmd != SHM_LOCK) {
      util::throwSystemError(errno, "Invalid errno");
    }
    util::throwSystemError(errno, "Could not lock memory");
    break;
  default:
    XDCHECK(false);
    util::throwSystemError(errno, "Invalid errno");
  }
}