示例#1
0
文件: netio.c 项目: Nubisa/JXPanel
int pr_netio_lingering_abort(pr_netio_stream_t *nstrm, long linger) {
  int res;

  if (nstrm == NULL) {
    errno = EINVAL;
    return -1;
  }

  /* Send an appropriate response code down the stream asychronously. */
  pr_response_send_async(R_426, _("Transfer aborted. Data connection closed."));

  pr_netio_shutdown(nstrm, 1);

  if (nstrm->strm_fd >= 0) {
    fd_set rs;
    struct timeval tv;

    /* Wait for just a little while for the shutdown to take effect. */
    tv.tv_sec = 0L;
    tv.tv_usec = 300000L;

    while (TRUE) {
      run_schedule();

      FD_ZERO(&rs);
      FD_SET(nstrm->strm_fd, &rs);

      res = select(nstrm->strm_fd+1, &rs, NULL, NULL, &tv);
      if (res == -1) {
        if (errno == EINTR) {
          pr_signals_handle();

          /* Linger some more. */
          tv.tv_sec = 0L;
          tv.tv_usec = 300000L;
          continue;

        } else {
          nstrm->strm_errno = errno;
          return -1;
        }
      }

      break;
    }
  }

  /* Now continue with a normal lingering close. */
  return netio_lingering_close(nstrm, linger,
    NETIO_LINGERING_CLOSE_FL_NO_SHUTDOWN);  
}
示例#2
0
int proxy_netio_shutdown(pr_netio_stream_t *nstrm, int how) {
  int res, xerrno;
  pr_netio_t *curr_netio = NULL;

  if (nstrm == NULL) {
    errno = EINVAL;
    return -1;
  }

  curr_netio = proxy_netio_unset(nstrm->strm_type, "netio_shutdown");
  res = pr_netio_shutdown(nstrm, how);
  xerrno = errno;
  proxy_netio_set(nstrm->strm_type, curr_netio);

  errno = xerrno;
  return res;
}
示例#3
0
文件: netio.c 项目: OPSF/uClinux
static int netio_lingering_close(pr_netio_stream_t *nstrm, long linger,
    int flags) {

  int res;
  struct timeval tv;
  fd_set rs;
  time_t when = time(NULL) + linger;

  if (!nstrm) {
    errno = EINVAL;
    return -1;
  }

  if (!(flags & NETIO_LINGERING_CLOSE_FL_NO_SHUTDOWN))
    pr_netio_shutdown(nstrm, 1);

  tv.tv_sec = linger;
  tv.tv_usec = 0L;

  /* Handle timers during reading, once selected for read this
   * should mean all buffers have been flushed and the receiving end
   * has closed.
   */
  while (TRUE) {
    run_schedule();

    FD_ZERO(&rs);
    FD_SET(nstrm->strm_fd, &rs);

    res = select(nstrm->strm_fd+1, &rs, NULL, NULL, &tv);
    if (res == -1) {
      if (errno == EINTR) {
        time_t now = time(NULL);
        pr_signals_handle();

        /* Still here? If the requested lingering interval hasn't passed,
         * continue lingering.  Reset the timeval struct's fields to
         * linger for the interval remaining in the given period of time.
         */
        if (now < when) {
          tv.tv_sec = when - now;
          tv.tv_usec = 0L;
          continue;
        }

      } else {
        nstrm->strm_errno = errno;
        return -1;
      }
    }

    break;
  }

  if (nstrm->strm_type == PR_NETIO_STRM_CTRL)
    return ctrl_netio ? ctrl_netio->close(nstrm) :
      core_ctrl_netio->close(nstrm);

  if (nstrm->strm_type == PR_NETIO_STRM_DATA)
    return data_netio ? data_netio->close(nstrm) :
      core_data_netio->close(nstrm);

  if (nstrm->strm_type == PR_NETIO_STRM_OTHR)
    return othr_netio ? othr_netio->close(nstrm) :
      core_othr_netio->close(nstrm);

  errno = EPERM;
  return -1;
}
示例#4
0
文件: netio.c 项目: Nubisa/JXPanel
static int netio_lingering_close(pr_netio_stream_t *nstrm, long linger,
    int flags) {
  int res;

  if (nstrm == NULL) {
    errno = EINVAL;
    return -1;
  }

  if (nstrm->strm_fd < 0) {
    /* Already closed. */
    return 0;
  }

  if (!(flags & NETIO_LINGERING_CLOSE_FL_NO_SHUTDOWN)) {
    pr_netio_shutdown(nstrm, 1);
  }

  if (nstrm->strm_fd >= 0) {
    struct timeval tv;
    fd_set rfds;
    time_t when = time(NULL) + linger;

    tv.tv_sec = linger;
    tv.tv_usec = 0L;

    /* Handle timers during reading, once selected for read this
     * should mean all buffers have been flushed and the receiving end
     * has closed.
     */
    while (TRUE) {
      run_schedule();

      FD_ZERO(&rfds);
      FD_SET(nstrm->strm_fd, &rfds);

      pr_trace_msg(trace_channel, 8,
        "lingering %lu secs before closing fd %d", (unsigned long) tv.tv_sec,
        nstrm->strm_fd);

      res = select(nstrm->strm_fd+1, &rfds, NULL, NULL, &tv);
      if (res == -1) {
        if (errno == EINTR) {
          time_t now = time(NULL);
          pr_signals_handle();

          /* Still here? If the requested lingering interval hasn't passed,
           * continue lingering.  Reset the timeval struct's fields to
           * linger for the interval remaining in the given period of time.
           */
          if (now < when) {
            tv.tv_sec = when - now;
            tv.tv_usec = 0L;
            continue;
          }

        } else {
          nstrm->strm_errno = errno;
          return -1;
        }

      } else {
        if (FD_ISSET(nstrm->strm_fd, &rfds)) {
          pr_trace_msg(trace_channel, 8,
            "received data for reading on fd %d, ignoring", nstrm->strm_fd);
        }
      }

      break;
    }
  }

  pr_trace_msg(trace_channel, 8, "done lingering, closing fd %d",
    nstrm->strm_fd);

  switch (nstrm->strm_type) {
    case PR_NETIO_STRM_CTRL:
      return ctrl_netio ? (ctrl_netio->close)(nstrm) :
        (default_ctrl_netio->close)(nstrm);

    case PR_NETIO_STRM_DATA:
      return data_netio ? (data_netio->close)(nstrm) :
        (default_data_netio->close)(nstrm);

    case PR_NETIO_STRM_OTHR:
      return othr_netio ? (othr_netio->close)(nstrm) :
        (default_othr_netio->close)(nstrm);
  }

  errno = EPERM;
  return -1;
}