summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-07-24 15:20:08 +0000
committerrwatson <rwatson@FreeBSD.org>2006-07-24 15:20:08 +0000
commit40868fda8a777cd2639ad89e252401b8b27c8c91 (patch)
treeb3a0ac6c1795bad8df68bc26486cfcd7d7e796ec
parent0dd0f8ec80a478a694b1ee6de99c7b84a2d3aa2b (diff)
downloadFreeBSD-src-40868fda8a777cd2639ad89e252401b8b27c8c91.zip
FreeBSD-src-40868fda8a777cd2639ad89e252401b8b27c8c91.tar.gz
soreceive_generic(), and sopoll_generic(). Add new functions sosend(),
soreceive(), and sopoll(), which are wrappers for pru_sosend, pru_soreceive, and pru_sopoll, and are now used univerally by socket consumers rather than either directly invoking the old so*() functions or directly invoking the protocol switch method (about an even split prior to this commit). This completes an architectural change that was begun in 1996 to permit protocols to provide substitute implementations, as now used by UDP. Consumers now uniformly invoke sosend(), soreceive(), and sopoll() to perform these operations on sockets -- in particular, distributed file systems and socket system calls. Architectural head nod: sam, gnn, wollman
-rw-r--r--sys/kern/sys_socket.c8
-rw-r--r--sys/kern/uipc_domain.c6
-rw-r--r--sys/kern/uipc_socket.c54
-rw-r--r--sys/kern/uipc_syscalls.c6
-rw-r--r--sys/kern/uipc_usrreq.c6
-rw-r--r--sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c9
-rw-r--r--sys/netgraph/ng_ksocket.c7
-rw-r--r--sys/netncp/ncp_sock.c17
-rw-r--r--sys/netsmb/smb_trantcp.c12
-rw-r--r--sys/nfsclient/nfs_socket.c17
-rw-r--r--sys/nfsserver/nfs_srvsock.c9
-rw-r--r--sys/sys/protosw.h9
-rw-r--r--sys/sys/socketvar.h8
13 files changed, 99 insertions, 69 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 7c352be..4d0a1ac 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -88,7 +88,7 @@ soo_read(fp, uio, active_cred, flags, td)
return (error);
}
#endif
- error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, uio, 0, 0, 0);
+ error = soreceive(so, 0, uio, 0, 0, 0);
NET_UNLOCK_GIANT();
return (error);
}
@@ -115,8 +115,7 @@ soo_write(fp, uio, active_cred, flags, td)
return (error);
}
#endif
- error = so->so_proto->pr_usrreqs->pru_sosend(so, 0, uio, 0, 0, 0,
- uio->uio_td);
+ error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td);
if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) {
PROC_LOCK(uio->uio_td->td_proc);
psignal(uio->uio_td->td_proc, SIGPIPE);
@@ -243,8 +242,7 @@ soo_poll(fp, events, active_cred, td)
return (error);
}
#endif
- error = (so->so_proto->pr_usrreqs->pru_sopoll)
- (so, events, fp->f_cred, td);
+ error = sopoll(so, events, fp->f_cred, td);
NET_UNLOCK_GIANT();
return (error);
diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c
index 28cddce..7cd9118 100644
--- a/sys/kern/uipc_domain.c
+++ b/sys/kern/uipc_domain.c
@@ -119,9 +119,9 @@ protosw_init(struct protosw *pr)
DEFAULT(pu->pru_rcvd, pru_rcvd_notsupp);
DEFAULT(pu->pru_rcvoob, pru_rcvoob_notsupp);
DEFAULT(pu->pru_sense, pru_sense_null);
- DEFAULT(pu->pru_sosend, sosend);
- DEFAULT(pu->pru_soreceive, soreceive);
- DEFAULT(pu->pru_sopoll, sopoll);
+ DEFAULT(pu->pru_sosend, sosend_generic);
+ DEFAULT(pu->pru_soreceive, soreceive_generic);
+ DEFAULT(pu->pru_sopoll, sopoll_generic);
#undef DEFAULT
if (pr->pr_init)
(*pr->pr_init)();
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 973c614..b92e085 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1093,7 +1093,7 @@ out:
*/
#define snderr(errno) { error = (errno); goto release; }
int
-sosend(so, addr, uio, top, control, flags, td)
+sosend_generic(so, addr, uio, top, control, flags, td)
struct socket *so;
struct sockaddr *addr;
struct uio *uio;
@@ -1256,6 +1256,25 @@ out:
}
#undef snderr
+int
+sosend(so, addr, uio, top, control, flags, td)
+ struct socket *so;
+ struct sockaddr *addr;
+ struct uio *uio;
+ struct mbuf *top;
+ struct mbuf *control;
+ int flags;
+ struct thread *td;
+{
+
+ /* XXXRW: Temporary debugging. */
+ KASSERT(so->so_proto->pr_usrreqs->pru_sosend != sosend,
+ ("sosend: protocol calls sosend"));
+
+ return (so->so_proto->pr_usrreqs->pru_sosend(so, addr, uio, top,
+ control, flags, td));
+}
+
/*
* The part of soreceive() that implements reading non-inline out-of-band
* data from a socket. For more complete comments, see soreceive(), from
@@ -1361,7 +1380,7 @@ sockbuf_pushsync(struct sockbuf *sb, struct mbuf *nextrecord)
* the count in uio_resid.
*/
int
-soreceive(so, psa, uio, mp0, controlp, flagsp)
+soreceive_generic(so, psa, uio, mp0, controlp, flagsp)
struct socket *so;
struct sockaddr **psa;
struct uio *uio;
@@ -1802,6 +1821,24 @@ out:
}
int
+soreceive(so, psa, uio, mp0, controlp, flagsp)
+ struct socket *so;
+ struct sockaddr **psa;
+ struct uio *uio;
+ struct mbuf **mp0;
+ struct mbuf **controlp;
+ int *flagsp;
+{
+
+ /* XXXRW: Temporary debugging. */
+ KASSERT(so->so_proto->pr_usrreqs->pru_soreceive != soreceive,
+ ("soreceive: protocol calls soreceive"));
+
+ return (so->so_proto->pr_usrreqs->pru_soreceive(so, psa, uio, mp0,
+ controlp, flagsp));
+}
+
+int
soshutdown(so, how)
struct socket *so;
int how;
@@ -2411,6 +2448,19 @@ int
sopoll(struct socket *so, int events, struct ucred *active_cred,
struct thread *td)
{
+
+ /* XXXRW: Temporary debugging. */
+ KASSERT(so->so_proto->pr_usrreqs->pru_sopoll != sopoll,
+ ("sopoll: protocol calls sopoll"));
+
+ return (so->so_proto->pr_usrreqs->pru_sopoll(so, events, active_cred,
+ td));
+}
+
+int
+sopoll_generic(struct socket *so, int events, struct ucred *active_cred,
+ struct thread *td)
+{
int revents = 0;
SOCKBUF_LOCK(&so->so_snd);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index a9eaa0d..431fbb9 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -803,8 +803,7 @@ kern_sendit(td, s, mp, flags, control, segflg)
ktruio = cloneuio(&auio);
#endif
len = auio.uio_resid;
- error = so->so_proto->pr_usrreqs->pru_sosend(so, mp->msg_name, &auio,
- 0, control, flags, td);
+ error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
if (error) {
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
@@ -1020,8 +1019,7 @@ kern_recvit(td, s, mp, fromseg, controlp)
ktruio = cloneuio(&auio);
#endif
len = auio.uio_resid;
- error = so->so_proto->pr_usrreqs->pru_soreceive(so, &fromsa, &auio,
- (struct mbuf **)0,
+ error = soreceive(so, &fromsa, &auio, (struct mbuf **)0,
(mp->msg_control || controlp) ? &control : (struct mbuf **)0,
&mp->msg_flags);
if (error) {
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index e0885c3..42226a1 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -786,9 +786,9 @@ struct pr_usrreqs uipc_usrreqs = {
.pru_sense = uipc_sense,
.pru_shutdown = uipc_shutdown,
.pru_sockaddr = uipc_sockaddr,
- .pru_sosend = sosend,
- .pru_soreceive = soreceive,
- .pru_sopoll = sopoll,
+ .pru_sosend = sosend_generic,
+ .pru_soreceive = soreceive_generic,
+ .pru_sopoll = sopoll_generic,
.pru_close = uipc_close,
};
diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
index 4e599cf..1e0c1a7 100644
--- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
+++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c
@@ -1558,8 +1558,8 @@ ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s)
flags = MSG_DONTWAIT;
m = NULL;
- error = (*s->l2so->so_proto->pr_usrreqs->pru_soreceive)(s->l2so,
- NULL, &uio, &m, (struct mbuf **) NULL, &flags);
+ error = soreceive(s->l2so, NULL, &uio, &m,
+ (struct mbuf **) NULL, &flags);
if (error != 0) {
if (error == EWOULDBLOCK)
return (0); /* XXX can happen? */
@@ -1610,9 +1610,8 @@ ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s)
return (0); /* we are done */
/* Call send function on the L2CAP socket */
- error = (*s->l2so->so_proto->pr_usrreqs->pru_sosend)
- (s->l2so, NULL, NULL, m, NULL, 0,
- curthread /* XXX */);
+ error = sosend(s->l2so, NULL, NULL, m, NULL, 0,
+ curthread /* XXX */);
if (error != 0) {
NG_BTSOCKET_RFCOMM_ERR(
"%s: Could not send data to L2CAP socket, error=%d\n", __func__, error);
diff --git a/sys/netgraph/ng_ksocket.c b/sys/netgraph/ng_ksocket.c
index 6f5f492..3e702d0 100644
--- a/sys/netgraph/ng_ksocket.c
+++ b/sys/netgraph/ng_ksocket.c
@@ -920,7 +920,7 @@ ng_ksocket_rcvdata(hook_p hook, item_p item)
sa = &stag->sa;
/* Send packet */
- error = (*so->so_proto->pr_usrreqs->pru_sosend)(so, sa, 0, m, 0, 0, td);
+ error = sosend(so, sa, 0, m, 0, 0, td);
return (error);
}
@@ -1101,9 +1101,8 @@ ng_ksocket_incoming2(node_p node, hook_p hook, void *arg1, int waitflag)
struct mbuf *n;
/* Try to get next packet from socket */
- if ((error = (*so->so_proto->pr_usrreqs->pru_soreceive)
- (so, (so->so_state & SS_ISCONNECTED) ? NULL : &sa,
- &auio, &m, (struct mbuf **)0, &flags)) != 0)
+ if ((error = soreceive(so, (so->so_state & SS_ISCONNECTED) ?
+ NULL : &sa, &auio, &m, (struct mbuf **)0, &flags)) != 0)
break;
/* See if we got anything */
diff --git a/sys/netncp/ncp_sock.c b/sys/netncp/ncp_sock.c
index 8edf4bc..a51ead2 100644
--- a/sys/netncp/ncp_sock.c
+++ b/sys/netncp/ncp_sock.c
@@ -139,10 +139,9 @@ int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen)
auio.uio_td = td;
flags = MSG_DONTWAIT;
-/* error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, &auio,
- (struct mbuf **)0, (struct mbuf **)0, &flags);*/
- error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, &auio,
- mp, (struct mbuf **)0, &flags);
+/* error = soreceive(so, 0, &auio, (struct mbuf **)0, (struct mbuf **)0,
+ &flags);*/
+ error = soreceive(so, 0, &auio, mp, (struct mbuf **)0, &flags);
*rlen = len - auio.uio_resid;
/* if (!error) {
*rlen=iov.iov_len;
@@ -168,7 +167,7 @@ ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp)
for (;;) {
m = m_copym(top, 0, M_COPYALL, M_TRYWAIT);
/* NCPDDEBUG(m);*/
- error = so->so_proto->pr_usrreqs->pru_sosend(so, to, 0, m, 0, flags, td);
+ error = sosend(so, to, 0, m, 0, flags, td);
if (error == 0 || error == EINTR || error == ENETDOWN)
break;
if (rqp->rexmit == 0) break;
@@ -189,7 +188,7 @@ ncp_poll(struct socket *so, int events)
struct thread *td = curthread;
struct ucred *cred = NULL;
- return so->so_proto->pr_usrreqs->pru_sopoll(so, events, cred, td);
+ return (sopoll(so, events, cred, td));
}
int
@@ -443,8 +442,8 @@ ncp_watchdog(struct ncp_conn *conn) {
auio.uio_resid = len = 1000000;
auio.uio_td = curthread;
flags = MSG_DONTWAIT;
- error = so->so_proto->pr_usrreqs->pru_soreceive(so,
- (struct sockaddr**)&sa, &auio, &m, (struct mbuf**)0, &flags);
+ error = soreceive(so, (struct sockaddr**)&sa, &auio, &m,
+ (struct mbuf**)0, &flags);
if (error) break;
len -= auio.uio_resid;
NCPSDEBUG("got watch dog %d\n",len);
@@ -452,7 +451,7 @@ ncp_watchdog(struct ncp_conn *conn) {
buf = mtod(m, char*);
if (buf[1] != '?') break;
buf[1] = 'Y';
- error = so->so_proto->pr_usrreqs->pru_sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
+ error = sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
NCPSDEBUG("send watch dog %d\n",error);
break;
}
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c
index 6c17e5d..4c273cd 100644
--- a/sys/netsmb/smb_trantcp.c
+++ b/sys/netsmb/smb_trantcp.c
@@ -75,8 +75,7 @@ SYSCTL_DECL(_net_smb);
SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &smb_tcpsndbuf, 0, "");
SYSCTL_INT(_net_smb, OID_AUTO, tcprcvbuf, CTLFLAG_RW, &smb_tcprcvbuf, 0, "");
-#define nb_sosend(so,m,flags,td) (so)->so_proto->pr_usrreqs->pru_sosend( \
- so, NULL, 0, m, 0, flags, td)
+#define nb_sosend(so,m,flags,td) sosend(so, NULL, 0, m, 0, flags, td)
static int nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
u_int8_t *rpcodep, struct thread *td);
@@ -98,8 +97,7 @@ nb_setsockopt_int(struct socket *so, int level, int name, int val)
static __inline int
nb_poll(struct nbpcb *nbp, int events, struct thread *td)
{
- return nbp->nbp_tso->so_proto->pr_usrreqs->pru_sopoll(nbp->nbp_tso,
- events, NULL, td);
+ return sopoll(nbp->nbp_tso, events, NULL, td);
}
static int
@@ -377,8 +375,7 @@ nbssn_recvhdr(struct nbpcb *nbp, int *lenp,
auio.uio_offset = 0;
auio.uio_resid = sizeof(len);
auio.uio_td = td;
- error = so->so_proto->pr_usrreqs->pru_soreceive
- (so, (struct sockaddr **)NULL, &auio,
+ error = soreceive(so, (struct sockaddr **)NULL, &auio,
(struct mbuf **)NULL, (struct mbuf **)NULL, &flags);
if (error)
return error;
@@ -461,8 +458,7 @@ nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
*/
do {
rcvflg = MSG_WAITALL;
- error = so->so_proto->pr_usrreqs->pru_soreceive
- (so, (struct sockaddr **)NULL,
+ error = soreceive(so, (struct sockaddr **)NULL,
&auio, &tm, (struct mbuf **)NULL, &rcvflg);
} while (error == EWOULDBLOCK || error == EINTR ||
error == ERESTART);
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c
index 46d52bf..3df174e 100644
--- a/sys/nfsclient/nfs_socket.c
+++ b/sys/nfsclient/nfs_socket.c
@@ -606,8 +606,7 @@ nfs_send(struct socket *so, struct sockaddr *nam, struct mbuf *top,
else
flags = 0;
- error = so->so_proto->pr_usrreqs->pru_sosend(so, sendnam, 0, top, 0,
- flags, curthread /*XXX*/);
+ error = sosend(so, sendnam, 0, top, 0, flags, curthread /*XXX*/);
if (error == ENOBUFS && so->so_type == SOCK_DGRAM) {
error = 0;
mtx_lock(&rep->r_mtx);
@@ -946,9 +945,8 @@ nfs_clnt_tcp_soupcall(struct socket *so, void *arg, int waitflag)
auio.uio_iovcnt = 0;
mp = NULL;
rcvflg = (MSG_DONTWAIT | MSG_SOCALLBCK);
- error = so->so_proto->pr_usrreqs->pru_soreceive
- (so, (struct sockaddr **)0,
- &auio, &mp, (struct mbuf **)0, &rcvflg);
+ error = soreceive(so, (struct sockaddr **)0, &auio,
+ &mp, (struct mbuf **)0, &rcvflg);
/*
* We've already tested that the socket is readable. 2 cases
* here, we either read 0 bytes (client closed connection),
@@ -1016,9 +1014,8 @@ nfs_clnt_tcp_soupcall(struct socket *so, void *arg, int waitflag)
auio.uio_iovcnt = 0;
mp = NULL;
rcvflg = (MSG_DONTWAIT | MSG_SOCALLBCK);
- error = so->so_proto->pr_usrreqs->pru_soreceive
- (so, (struct sockaddr **)0,
- &auio, &mp, (struct mbuf **)0, &rcvflg);
+ error = soreceive(so, (struct sockaddr **)0, &auio,
+ &mp, (struct mbuf **)0, &rcvflg);
if (error || auio.uio_resid > 0) {
if (error && error != ECONNRESET) {
log(LOG_ERR,
@@ -1058,9 +1055,7 @@ nfs_clnt_udp_soupcall(struct socket *so, void *arg, int waitflag)
auio.uio_resid = 1000000000;
do {
mp = control = NULL;
- error = so->so_proto->pr_usrreqs->pru_soreceive(so,
- NULL, &auio, &mp,
- &control, &rcvflag);
+ error = soreceive(so, NULL, &auio, &mp, &control, &rcvflag);
if (control)
m_freem(control);
if (mp)
diff --git a/sys/nfsserver/nfs_srvsock.c b/sys/nfsserver/nfs_srvsock.c
index 5721b39..ffeb4ef 100644
--- a/sys/nfsserver/nfs_srvsock.c
+++ b/sys/nfsserver/nfs_srvsock.c
@@ -466,8 +466,7 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
auio.uio_resid = 1000000000;
flags = MSG_DONTWAIT;
NFSD_UNLOCK();
- error = so->so_proto->pr_usrreqs->pru_soreceive
- (so, &nam, &auio, &mp, NULL, &flags);
+ error = soreceive(so, &nam, &auio, &mp, NULL, &flags);
NFSD_LOCK();
if (error || mp == NULL) {
if (error == EWOULDBLOCK)
@@ -503,8 +502,7 @@ nfsrv_rcv(struct socket *so, void *arg, int waitflag)
auio.uio_resid = 1000000000;
flags = MSG_DONTWAIT;
NFSD_UNLOCK();
- error = so->so_proto->pr_usrreqs->pru_soreceive
- (so, &nam, &auio, &mp, NULL, &flags);
+ error = soreceive(so, &nam, &auio, &mp, NULL, &flags);
if (mp) {
struct nfsrv_rec *rec;
rec = malloc(sizeof(struct nfsrv_rec),
@@ -785,8 +783,7 @@ nfsrv_send(struct socket *so, struct sockaddr *nam, struct mbuf *top)
else
flags = 0;
- error = so->so_proto->pr_usrreqs->pru_sosend(so, sendnam, 0, top, 0,
- flags, curthread/*XXX*/);
+ error = sosend(so, sendnam, 0, top, 0, flags, curthread/*XXX*/);
if (error == ENOBUFS && so->so_type == SOCK_DGRAM)
error = 0;
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 2fe23c8..367d5b6 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -228,15 +228,6 @@ struct pr_usrreqs {
int (*pru_sense)(struct socket *so, struct stat *sb);
int (*pru_shutdown)(struct socket *so);
int (*pru_sockaddr)(struct socket *so, struct sockaddr **nam);
-
- /*
- * These four added later, so they are out of order. They are used
- * for shortcutting (fast path input/output) in some protocols.
- * XXX - that's a lie, they are not implemented yet
- * Rather than calling sosend() etc. directly, calls are made
- * through these entry points. For protocols which still use
- * the generic code, these just point to those routines.
- */
int (*pru_sosend)(struct socket *so, struct sockaddr *addr,
struct uio *uio, struct mbuf *top, struct mbuf *control,
int flags, struct thread *td);
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index c6d1272..184ff99 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -530,8 +530,13 @@ int soopt_mcopyout(struct sockopt *sopt, struct mbuf *m);
int sopoll(struct socket *so, int events, struct ucred *active_cred,
struct thread *td);
+int sopoll_generic(struct socket *so, int events,
+ struct ucred *active_cred, struct thread *td);
int soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio,
struct mbuf **mp0, struct mbuf **controlp, int *flagsp);
+int soreceive_generic(struct socket *so, struct sockaddr **paddr,
+ struct uio *uio, struct mbuf **mp0, struct mbuf **controlp,
+ int *flagsp);
int soreserve(struct socket *so, u_long sndcc, u_long rcvcc);
void sorflush(struct socket *so);
int sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
@@ -540,6 +545,9 @@ int sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
int sosend_dgram(struct socket *so, struct sockaddr *addr,
struct uio *uio, struct mbuf *top, struct mbuf *control,
int flags, struct thread *td);
+int sosend_generic(struct socket *so, struct sockaddr *addr,
+ struct uio *uio, struct mbuf *top, struct mbuf *control,
+ int flags, struct thread *td);
int sosetopt(struct socket *so, struct sockopt *sopt);
int soshutdown(struct socket *so, int how);
void sotoxsocket(struct socket *so, struct xsocket *xso);
OpenPOWER on IntegriCloud