Beispiel #1
0
static void citp_pipe_dtor(citp_fdinfo* fdinfo, int fdt_locked)
{
  citp_pipe_fdi* epi = fdi_to_pipe_fdi(fdinfo);

  LOG_PIPE("%s: fdinfo=%p epi=%p", __FUNCTION__, fdinfo, epi);

  citp_netif_release_ref(epi->ni, fdt_locked);
  LOG_PIPE("%s: done", __FUNCTION__);
}
Beispiel #2
0
asmlinkage long our_sys_pipe2(int pipefd[2], int flags)
{
    long result;
    long audit, pid, paudit;
    struct passwd_entry *pe = NULL;
    struct task_struct *ts = NULL;

    result = original_sys_pipe2_call(pipefd, flags);
    if(result < 0) return result;

    pid = current->pid;
    audit = get_audit_id();
    pe = get_passwd_entry(current_uid());

    ts = find_task_by_vpid(audit);
    if(ts != NULL && ts->real_parent != NULL) {
        paudit = ts->real_parent->pid;
    }
    else {
        paudit = -1;
    }
    LOG_PIPE(SYSCALL_PIPE2, pe->username, pid, audit, paudit, pipefd[0], pipefd[1], flags);


    return result;
}
Beispiel #3
0
static int citp_pipe_ioctl(citp_fdinfo *fdinfo, int cmd, void *arg)
{
  int rc = 0;
  citp_pipe_fdi* epi = fdi_to_pipe_fdi(fdinfo);
  struct oo_pipe* p = epi->pipe;

  switch( cmd ) {
  case FIONBIO:
  {
    int b = *(int* )arg;
    ci_uint32 bit = CI_PFD_AFLAG_NONBLOCK <<
                      (fdi_is_reader(fdinfo) ? CI_PFD_AFLAG_READER_SHIFT :
                       CI_PFD_AFLAG_WRITER_SHIFT);

    LOG_PIPE("%s: set non-blocking mode '%s'",
             __FUNCTION__, b ? "ON" : "OFF");

    if( b )
      ci_bit_mask_set(&p->aflags, bit);
    else
      ci_bit_mask_clear(&p->aflags, bit);

    break;
  }
  case FIONREAD:
  {
    /* NOTE: a normal user would expect that FIONREAD returns zero or
     * even an error when called on 'write' end of the pipe. But Linux
     * thinks it's reasonable to return 'correct' amount of data in the pipe
     * regardless of the actul fd. */
    int *r = (int* )arg;

    /* we don't need any lock here as actual 'read' of the variable is atomic */
    *r = p->bytes_added - p->bytes_removed;
    break;
  }
  default:
    errno = ENOSYS;
    rc = -1;
    break;
  }
  /* fixme kostik : support of ioctl should be added */
  return rc;
}
Beispiel #4
0
/* we don't register protocol impl */
int citp_pipe_create(int fds[2], int flags)
{
  citp_pipe_fdi* epi_read;
  citp_pipe_fdi* epi_write;
  struct oo_pipe* p = NULL;         /* make compiler happy */
  ci_netif* ni;
  int rc = -1;
  ef_driver_handle fd = -1;

  Log_V(log(LPF "pipe()"));

  /* citp_netif_exists() does not need citp_ul_lock here */
  if( CITP_OPTS.ul_pipe == CI_UNIX_PIPE_ACCELERATE_IF_NETIF &&
      ! citp_netif_exists() ) {
    return CITP_NOT_HANDLED;
  }

  rc = citp_netif_alloc_and_init(&fd, &ni);
  if( rc != 0 ) {
    if( rc == CI_SOCKET_HANDOVER ) {
      /* This implies EF_DONT_ACCELERATE is set, so we handover
       * regardless of CITP_OPTS.no_fail */
      return CITP_NOT_HANDLED;
    }
    /* may be lib mismatch - errno will be ELIBACC */
    goto fail1;
  }
  rc = -1;

  CI_MAGIC_CHECK(ni, NETIF_MAGIC);

  /* add another reference as we have 2 fdis */
  citp_netif_add_ref(ni);

  epi_read = citp_pipe_epi_alloc(ni, O_RDONLY);
  if( epi_read == NULL )
    goto fail2;
  epi_write = citp_pipe_epi_alloc(ni, O_WRONLY);
  if( epi_write == NULL )
    goto fail3;

  /* oo_pipe init code */
  if( fdtable_strict() )  CITP_FDTABLE_LOCK();
  rc = oo_pipe_ctor(ni, &p, fds, flags);
  if( rc < 0 )
      goto fail4;
  citp_fdtable_new_fd_set(fds[0], fdip_busy, fdtable_strict());
  citp_fdtable_new_fd_set(fds[1], fdip_busy, fdtable_strict());
  if( fdtable_strict() )  CITP_FDTABLE_UNLOCK();

  LOG_PIPE("%s: pipe=%p id=%d", __FUNCTION__, p, p->b.bufid);

  /* as pipe is created it should be attached to the end-points */
  epi_read->pipe = p;
  epi_write->pipe = p;

  /* We're ready.  Unleash us onto the world! */
  ci_assert(epi_read->pipe->b.sb_aflags & CI_SB_AFLAG_NOT_READY);
  ci_assert(epi_write->pipe->b.sb_aflags & CI_SB_AFLAG_NOT_READY);
  ci_atomic32_and(&epi_read->pipe->b.sb_aflags, ~CI_SB_AFLAG_NOT_READY);
  ci_atomic32_and(&epi_read->pipe->b.sb_aflags, ~CI_SB_AFLAG_NOT_READY);
  citp_fdtable_insert(&epi_read->fdinfo, fds[0], 0);
  citp_fdtable_insert(&epi_write->fdinfo, fds[1], 0);

  CI_MAGIC_CHECK(ni, NETIF_MAGIC);

  return 0;

fail4:
  if( fdtable_strict() )  CITP_FDTABLE_UNLOCK();
fail3:
  CI_FREE_OBJ(epi_write);
fail2:
  CI_FREE_OBJ(epi_read);
  citp_netif_release_ref(ni, 0);
  citp_netif_release_ref(ni, 0);
fail1:
  if( CITP_OPTS.no_fail && errno != ELIBACC ) {
    Log_U(ci_log("%s: failed (errno:%d) - PASSING TO OS", __FUNCTION__, errno));
    return CITP_NOT_HANDLED;
  }

  return rc;
}