Esempio n. 1
0
/*
 * Interface between xdr serializer and tcp connection.
 * Behaves like the system calls, read & write, but keeps some error state
 * around for the rpc level.
 */
static int
read_vc(void *ctp, void *buf, int len)
{
	struct sockaddr sa;
	socklen_t sal;
	struct ct_data *ct = (struct ct_data *)ctp;
	struct pollfd fd;
	int milliseconds = (int)((ct->ct_wait.tv_sec * 1000) +
	    (ct->ct_wait.tv_usec / 1000));

	if (len == 0)
		return (0);
	fd.fd = ct->ct_fd;
	fd.events = POLLIN;
	for (;;) {
		switch (_poll(&fd, 1, milliseconds)) {
		case 0:
			ct->ct_error.re_status = RPC_TIMEDOUT;
			return (-1);

		case -1:
			if (errno == EINTR)
				continue;
			ct->ct_error.re_status = RPC_CANTRECV;
			ct->ct_error.re_errno = errno;
			return (-1);
		}
		break;
	}

	sal = sizeof(sa);
	if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) &&
	    (sa.sa_family == AF_LOCAL)) {
		len = __msgread(ct->ct_fd, buf, (size_t)len);
	} else {
		len = _read(ct->ct_fd, buf, (size_t)len);
	}

	switch (len) {
	case 0:
		/* premature eof */
		ct->ct_error.re_errno = ECONNRESET;
		ct->ct_error.re_status = RPC_CANTRECV;
		len = -1;  /* it's really an error */
		break;

	case -1:
		ct->ct_error.re_errno = errno;
		ct->ct_error.re_status = RPC_CANTRECV;
		break;
	}
	return (len);
}
/*
 * Interface between xdr serializer and unix connection.
 * Behaves like the system calls, read & write, but keeps some error state
 * around for the rpc level.
 */
static int
readunix (char *ctptr, char *buf, int len)
{
  struct ct_data *ct = (struct ct_data *) ctptr;
  struct pollfd fd;
  int milliseconds = ((ct->ct_wait.tv_sec * 1000)
		      + (ct->ct_wait.tv_usec / 1000));

  if (len == 0)
    return 0;

  fd.fd = ct->ct_sock;
  fd.events = POLLIN;
  while (TRUE)
    {
      switch (poll (&fd, 1, milliseconds))
        {
        case 0:
          ct->ct_error.re_status = RPC_TIMEDOUT;
          return -1;

        case -1:
          if (errno == EINTR)
            continue;
          ct->ct_error.re_status = RPC_CANTRECV;
          ct->ct_error.re_errno = errno;
          return -1;
        }
      break;
    }
  switch (len = __msgread (ct->ct_sock, buf, len))
    {

    case 0:
      /* premature eof */
      ct->ct_error.re_errno = ECONNRESET;
      ct->ct_error.re_status = RPC_CANTRECV;
      len = -1;			/* it's really an error */
      break;

    case -1:
      ct->ct_error.re_errno = errno;
      ct->ct_error.re_status = RPC_CANTRECV;
      break;
    }
  return len;
}
Esempio n. 3
0
/*
 * reads data from the unix connection.
 * any error is fatal and the connection is closed.
 * (And a read of zero bytes is a half closed stream => error.)
 */
static int
readunix (char *xprtptr, char *buf, int len)
{
  SVCXPRT *xprt = (SVCXPRT *) xprtptr;
  int sock = xprt->xp_sock;
  int milliseconds = 35 * 1000;
  struct pollfd pollfd;

  do
    {
      pollfd.fd = sock;
      pollfd.events = POLLIN;
      switch (__poll (&pollfd, 1, milliseconds))
	{
	case -1:
	  if (errno == EINTR)
	    continue;
	  /*FALLTHROUGH*/
	case 0:
	  goto fatal_err;
	default:
	  if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)
	      || (pollfd.revents & POLLNVAL))
	    goto fatal_err;
	  break;
	}
    }
  while ((pollfd.revents & POLLIN) == 0);

  if ((len = __msgread (sock, buf, len)) > 0)
    return len;

 fatal_err:
  ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
  return -1;
}