void svc_getreq_poll (struct pollfd *pfdp, int pollretval) { register int i; register int fds_found; for (i = fds_found = 0; i < svc_max_pollfd && fds_found < pollretval; ++i) { register struct pollfd *p = &pfdp[i]; if (p->fd != -1 && p->revents) { /* fd has input waiting */ ++fds_found; if (p->revents & POLLNVAL) xprt_unregister (xports[p->fd]); else svc_getreq_common (p->fd); } } }
void svc_getreq_poll (struct pollfd *pfdp, int pollretval) { if (pollretval == 0) return; register int fds_found; for (int i = fds_found = 0; i < svc_max_pollfd; ++i) { register struct pollfd *p = &pfdp[i]; if (p->fd != -1 && p->revents) { /* fd has input waiting */ if (p->revents & POLLNVAL) xprt_unregister (xports[p->fd]); else svc_getreq_common (p->fd); if (++fds_found >= pollretval) break; } } }
/* ARGSUSED */ static enum clnt_stat clnt_raw_call(CLIENT *h, AUTH *auth, rpcproc_t proc, xdrproc_t xargs, void *argsp, xdrproc_t xresults, void *resultsp, struct timeval timeout) { struct clntraw_private *clp = clntraw_private; XDR *xdrs = &clp->xdr_stream; struct rpc_msg msg; enum clnt_stat status; struct rpc_err error; assert(h != NULL); mutex_lock(&clntraw_lock); if (clp == NULL) { mutex_unlock(&clntraw_lock); return (RPC_FAILED); } mutex_unlock(&clntraw_lock); call_again: /* * send request */ xdrs->x_op = XDR_ENCODE; XDR_SETPOS(xdrs, 0); clp->u.mashl_rpcmsg.rm_xid ++ ; if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) || (! XDR_PUTINT32(xdrs, (int32_t *)&proc)) || (! AUTH_MARSHALL(auth, xdrs)) || (! (*xargs)(xdrs, argsp))) { return (RPC_CANTENCODEARGS); } (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ /* * We have to call server input routine here because this is * all going on in one process. Yuk. */ svc_getreq_common(FD_SETSIZE); /* * get results */ xdrs->x_op = XDR_DECODE; XDR_SETPOS(xdrs, 0); msg.acpted_rply.ar_verf = _null_auth; msg.acpted_rply.ar_results.where = resultsp; msg.acpted_rply.ar_results.proc = xresults; if (! xdr_replymsg(xdrs, &msg)) { /* * It's possible for xdr_replymsg() to fail partway * through its attempt to decode the result from the * server. If this happens, it will leave the reply * structure partially populated with dynamically * allocated memory. (This can happen if someone uses * clntudp_bufcreate() to create a CLIENT handle and * specifies a receive buffer size that is too small.) * This memory must be free()ed to avoid a leak. */ int op = xdrs->x_op; xdrs->x_op = XDR_FREE; xdr_replymsg(xdrs, &msg); xdrs->x_op = op; return (RPC_CANTDECODERES); } _seterr_reply(&msg, &error); status = error.re_status; if (status == RPC_SUCCESS) { if (! AUTH_VALIDATE(auth, &msg.acpted_rply.ar_verf)) { status = RPC_AUTHERROR; } } /* end successful completion */ else { if (AUTH_REFRESH(auth, &msg)) goto call_again; } /* end of unsuccessful completion */ if (status == RPC_SUCCESS) { if (! AUTH_VALIDATE(auth, &msg.acpted_rply.ar_verf)) { status = RPC_AUTHERROR; } if (msg.acpted_rply.ar_verf.oa_base != NULL) { xdrs->x_op = XDR_FREE; (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); } } return (status); }
/*ARGSUSED*/ static enum clnt_stat clnt_raw_call(CLIENT *h, rpcproc_t proc, xdrproc_t xargs, caddr_t argsp, xdrproc_t xresults, caddr_t resultsp, struct timeval timeout) { struct clnt_raw_private *clp; XDR xdrs; struct rpc_msg msg; uint_t start; rpc_callerr.re_errno = 0; rpc_callerr.re_terrno = 0; (void) mutex_lock(&clntraw_lock); clp = clnt_raw_private; if (clp == NULL) { (void) mutex_unlock(&clntraw_lock); return (rpc_callerr.re_status = RPC_FAILED); } (void) mutex_unlock(&clntraw_lock); call_again: /* * send request */ xdrmem_create(&xdrs, clp->raw_netbuf->buf, clp->raw_netbuf->maxlen, XDR_ENCODE); start = XDR_GETPOS(&xdrs); /* LINTED pointer alignment */ ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid++; if ((!XDR_PUTBYTES(&xdrs, clp->mashl_callmsg, clp->mcnt)) || (!XDR_PUTINT32(&xdrs, (int32_t *)&proc)) || (!AUTH_MARSHALL(h->cl_auth, &xdrs)) || (!(*xargs)(&xdrs, argsp))) { XDR_DESTROY(&xdrs); return (rpc_callerr.re_status = RPC_CANTENCODEARGS); } clp->raw_netbuf->len = XDR_GETPOS(&xdrs) - start; XDR_DESTROY(&xdrs); /* * We have to call server input routine here because this is * all going on in one process. * By convention using FD_SETSIZE as the pseudo file descriptor. */ svc_getreq_common(FD_SETSIZE); /* * get results */ xdrmem_create(&xdrs, clp->raw_netbuf->buf, clp->raw_netbuf->len, XDR_DECODE); msg.acpted_rply.ar_verf = _null_auth; msg.acpted_rply.ar_results.where = resultsp; msg.acpted_rply.ar_results.proc = xresults; if (!xdr_replymsg(&xdrs, &msg)) { XDR_DESTROY(&xdrs); return (rpc_callerr.re_status = RPC_CANTDECODERES); } XDR_DESTROY(&xdrs); if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) && (msg.acpted_rply.ar_stat == SUCCESS)) rpc_callerr.re_status = RPC_SUCCESS; else __seterr_reply(&msg, &rpc_callerr); if (rpc_callerr.re_status == RPC_SUCCESS) { if (!AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { rpc_callerr.re_status = RPC_AUTHERROR; rpc_callerr.re_why = AUTH_INVALIDRESP; } if (msg.acpted_rply.ar_verf.oa_base != NULL) { xdr_free(xdr_opaque_auth, (char *)&(msg.acpted_rply.ar_verf)); } /* end successful completion */ } else { if (AUTH_REFRESH(h->cl_auth, &msg)) goto call_again; /* end of unsuccessful completion */ } return (rpc_callerr.re_status); }