version 1.62.2.1, 2003/07/02 15:26:45 |
version 1.62.2.2, 2004/08/03 10:52:58 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. |
* Copyright (c) 1998, 2000, 2004 The NetBSD Foundation, Inc. |
* All rights reserved. |
* All rights reserved. |
* |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* This code is derived from software contributed to The NetBSD Foundation |
|
|
*/ |
*/ |
|
|
/* |
/* |
* Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. |
|
* Copyright (c) 1982, 1986, 1989, 1991, 1993 |
* Copyright (c) 1982, 1986, 1989, 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* The Regents of the University of California. All rights reserved. |
* |
* |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* documentation and/or other materials provided with the distribution. |
|
* 3. Neither the name of the University nor the names of its contributors |
|
* may be used to endorse or promote products derived from this software |
|
* without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
* SUCH DAMAGE. |
|
* |
|
* @(#)uipc_usrreq.c 8.9 (Berkeley) 5/14/95 |
|
*/ |
|
|
|
/* |
|
* Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* 1. Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* 2. Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* This product includes software developed by the University of |
Line 100 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 129 __KERNEL_RCSID(0, "$NetBSD$"); |
|
* rethink name space problems |
* rethink name space problems |
* need a proper out-of-band |
* need a proper out-of-band |
*/ |
*/ |
struct sockaddr_un sun_noname = { sizeof(sun_noname), AF_LOCAL }; |
const struct sockaddr_un sun_noname = { sizeof(sun_noname), AF_LOCAL }; |
ino_t unp_ino; /* prototype for fake inode numbers */ |
ino_t unp_ino; /* prototype for fake inode numbers */ |
|
|
struct mbuf *unp_addsockcred __P((struct proc *, struct mbuf *)); |
struct mbuf *unp_addsockcred(struct proc *, struct mbuf *); |
|
|
int |
int |
unp_output(m, control, unp, p) |
unp_output(struct mbuf *m, struct mbuf *control, struct unpcb *unp, |
struct mbuf *m, *control; |
struct proc *p) |
struct unpcb *unp; |
|
struct proc *p; |
|
{ |
{ |
struct socket *so2; |
struct socket *so2; |
struct sockaddr_un *sun; |
const struct sockaddr_un *sun; |
|
|
so2 = unp->unp_conn->unp_socket; |
so2 = unp->unp_conn->unp_socket; |
if (unp->unp_addr) |
if (unp->unp_addr) |
Line 133 unp_output(m, control, unp, p) |
|
Line 160 unp_output(m, control, unp, p) |
|
} |
} |
|
|
void |
void |
unp_setsockaddr(unp, nam) |
unp_setsockaddr(struct unpcb *unp, struct mbuf *nam) |
struct unpcb *unp; |
|
struct mbuf *nam; |
|
{ |
{ |
struct sockaddr_un *sun; |
const struct sockaddr_un *sun; |
|
|
if (unp->unp_addr) |
if (unp->unp_addr) |
sun = unp->unp_addr; |
sun = unp->unp_addr; |
Line 150 unp_setsockaddr(unp, nam) |
|
Line 175 unp_setsockaddr(unp, nam) |
|
} |
} |
|
|
void |
void |
unp_setpeeraddr(unp, nam) |
unp_setpeeraddr(struct unpcb *unp, struct mbuf *nam) |
struct unpcb *unp; |
|
struct mbuf *nam; |
|
{ |
{ |
struct sockaddr_un *sun; |
const struct sockaddr_un *sun; |
|
|
if (unp->unp_conn && unp->unp_conn->unp_addr) |
if (unp->unp_conn && unp->unp_conn->unp_addr) |
sun = unp->unp_conn->unp_addr; |
sun = unp->unp_conn->unp_addr; |
Line 168 unp_setpeeraddr(unp, nam) |
|
Line 191 unp_setpeeraddr(unp, nam) |
|
|
|
/*ARGSUSED*/ |
/*ARGSUSED*/ |
int |
int |
uipc_usrreq(so, req, m, nam, control, l) |
uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, |
struct socket *so; |
struct mbuf *control, struct lwp *l) |
int req; |
|
struct mbuf *m, *nam, *control; |
|
struct lwp *l; |
|
{ |
{ |
struct unpcb *unp = sotounpcb(so); |
struct unpcb *unp = sotounpcb(so); |
struct socket *so2; |
struct socket *so2; |
struct proc *p; |
struct proc *p; |
|
u_int newhiwat; |
int error = 0; |
int error = 0; |
|
|
if (req == PRU_CONTROL) |
if (req == PRU_CONTROL) |
Line 220 uipc_usrreq(so, req, m, nam, control, l) |
|
Line 241 uipc_usrreq(so, req, m, nam, control, l) |
|
break; |
break; |
|
|
case PRU_CONNECT2: |
case PRU_CONNECT2: |
error = unp_connect2(so, (struct socket *)nam); |
error = unp_connect2(so, (struct socket *)nam, PRU_CONNECT2); |
break; |
break; |
|
|
case PRU_DISCONNECT: |
case PRU_DISCONNECT: |
Line 229 uipc_usrreq(so, req, m, nam, control, l) |
|
Line 250 uipc_usrreq(so, req, m, nam, control, l) |
|
|
|
case PRU_ACCEPT: |
case PRU_ACCEPT: |
unp_setpeeraddr(unp, nam); |
unp_setpeeraddr(unp, nam); |
|
/* |
|
* Mark the initiating STREAM socket as connected *ONLY* |
|
* after it's been accepted. This prevents a client from |
|
* overrunning a server and receiving ECONNREFUSED. |
|
*/ |
|
if (unp->unp_conn != NULL && |
|
(unp->unp_conn->unp_socket->so_state & SS_ISCONNECTING)) |
|
soisconnected(unp->unp_conn->unp_socket); |
break; |
break; |
|
|
case PRU_SHUTDOWN: |
case PRU_SHUTDOWN: |
Line 255 uipc_usrreq(so, req, m, nam, control, l) |
|
Line 284 uipc_usrreq(so, req, m, nam, control, l) |
|
*/ |
*/ |
snd->sb_mbmax += unp->unp_mbcnt - rcv->sb_mbcnt; |
snd->sb_mbmax += unp->unp_mbcnt - rcv->sb_mbcnt; |
unp->unp_mbcnt = rcv->sb_mbcnt; |
unp->unp_mbcnt = rcv->sb_mbcnt; |
snd->sb_hiwat += unp->unp_cc - rcv->sb_cc; |
newhiwat = snd->sb_hiwat + unp->unp_cc - rcv->sb_cc; |
|
(void)chgsbsize(so2->so_uid, |
|
&snd->sb_hiwat, newhiwat, RLIM_INFINITY); |
unp->unp_cc = rcv->sb_cc; |
unp->unp_cc = rcv->sb_cc; |
sowwakeup(so2); |
sowwakeup(so2); |
#undef snd |
#undef snd |
Line 274 uipc_usrreq(so, req, m, nam, control, l) |
|
Line 305 uipc_usrreq(so, req, m, nam, control, l) |
|
* has the side-effect of preventing a caller from |
* has the side-effect of preventing a caller from |
* forging SCM_CREDS. |
* forging SCM_CREDS. |
*/ |
*/ |
if (control && (error = unp_internalize(control, p))) |
if (control && (error = unp_internalize(control, l))) |
break; |
break; |
switch (so->so_type) { |
switch (so->so_type) { |
|
|
Line 330 uipc_usrreq(so, req, m, nam, control, l) |
|
Line 361 uipc_usrreq(so, req, m, nam, control, l) |
|
snd->sb_mbmax -= |
snd->sb_mbmax -= |
rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt; |
rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt; |
unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt; |
unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt; |
snd->sb_hiwat -= rcv->sb_cc - unp->unp_conn->unp_cc; |
newhiwat = snd->sb_hiwat - |
|
(rcv->sb_cc - unp->unp_conn->unp_cc); |
|
(void)chgsbsize(so->so_uid, |
|
&snd->sb_hiwat, newhiwat, RLIM_INFINITY); |
unp->unp_conn->unp_cc = rcv->sb_cc; |
unp->unp_conn->unp_cc = rcv->sb_cc; |
sorwakeup(so2); |
sorwakeup(so2); |
#undef snd |
#undef snd |
|
|
* Unix domain socket option processing. |
* Unix domain socket option processing. |
*/ |
*/ |
int |
int |
uipc_ctloutput(op, so, level, optname, mp) |
uipc_ctloutput(int op, struct socket *so, int level, int optname, |
int op; |
struct mbuf **mp) |
struct socket *so; |
|
int level, optname; |
|
struct mbuf **mp; |
|
{ |
{ |
struct unpcb *unp = sotounpcb(so); |
struct unpcb *unp = sotounpcb(so); |
struct mbuf *m = *mp; |
struct mbuf *m = *mp; |
Line 416 uipc_ctloutput(op, so, level, optname, m |
|
Line 447 uipc_ctloutput(op, so, level, optname, m |
|
case PRCO_SETOPT: |
case PRCO_SETOPT: |
switch (optname) { |
switch (optname) { |
case LOCAL_CREDS: |
case LOCAL_CREDS: |
|
case LOCAL_CONNWAIT: |
if (m == NULL || m->m_len != sizeof(int)) |
if (m == NULL || m->m_len != sizeof(int)) |
error = EINVAL; |
error = EINVAL; |
else { |
else { |
Line 430 uipc_ctloutput(op, so, level, optname, m |
|
Line 462 uipc_ctloutput(op, so, level, optname, m |
|
case LOCAL_CREDS: |
case LOCAL_CREDS: |
OPTSET(UNP_WANTCRED); |
OPTSET(UNP_WANTCRED); |
break; |
break; |
|
case LOCAL_CONNWAIT: |
|
OPTSET(UNP_CONNWAIT); |
|
break; |
} |
} |
} |
} |
break; |
break; |
Line 486 u_long unpdg_recvspace = 4*1024; |
|
Line 521 u_long unpdg_recvspace = 4*1024; |
|
int unp_rights; /* file descriptors in flight */ |
int unp_rights; /* file descriptors in flight */ |
|
|
int |
int |
unp_attach(so) |
unp_attach(struct socket *so) |
struct socket *so; |
|
{ |
{ |
struct unpcb *unp; |
struct unpcb *unp; |
struct timeval tv; |
struct timeval tv; |
|
|
} |
} |
|
|
void |
void |
unp_detach(unp) |
unp_detach(struct unpcb *unp) |
struct unpcb *unp; |
|
{ |
{ |
|
|
if (unp->unp_vnode) { |
if (unp->unp_vnode) { |
|
|
} |
} |
|
|
int |
int |
unp_bind(unp, nam, l) |
unp_bind(struct unpcb *unp, struct mbuf *nam, struct lwp *l) |
struct unpcb *unp; |
|
struct mbuf *nam; |
|
struct lwp *l; |
|
{ |
{ |
struct sockaddr_un *sun; |
struct sockaddr_un *sun; |
struct vnode *vp; |
struct vnode *vp; |
|
struct mount *mp; |
struct vattr vattr; |
struct vattr vattr; |
size_t addrlen; |
size_t addrlen; |
struct proc *p; |
struct proc *p; |
Line 582 unp_bind(unp, nam, l) |
|
Line 613 unp_bind(unp, nam, l) |
|
m_copydata(nam, 0, nam->m_len, (caddr_t)sun); |
m_copydata(nam, 0, nam->m_len, (caddr_t)sun); |
*(((char *)sun) + nam->m_len) = '\0'; |
*(((char *)sun) + nam->m_len) = '\0'; |
|
|
|
restart: |
NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE, |
NDINIT(&nd, CREATE, FOLLOW | LOCKPARENT, UIO_SYSSPACE, |
sun->sun_path, l); |
sun->sun_path, l); |
|
|
Line 589 unp_bind(unp, nam, l) |
|
Line 621 unp_bind(unp, nam, l) |
|
if ((error = namei(&nd)) != 0) |
if ((error = namei(&nd)) != 0) |
goto bad; |
goto bad; |
vp = nd.ni_vp; |
vp = nd.ni_vp; |
if (vp != NULL) { |
if (vp != NULL || vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { |
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); |
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); |
if (nd.ni_dvp == vp) |
if (nd.ni_dvp == vp) |
vrele(nd.ni_dvp); |
vrele(nd.ni_dvp); |
else |
else |
vput(nd.ni_dvp); |
vput(nd.ni_dvp); |
vrele(vp); |
vrele(vp); |
error = EADDRINUSE; |
if (vp != NULL) { |
goto bad; |
error = EADDRINUSE; |
|
goto bad; |
|
} |
|
error = vn_start_write(NULL, &mp, |
|
V_WAIT | V_SLEEPONLY | V_PCATCH); |
|
if (error) |
|
goto bad; |
|
goto restart; |
} |
} |
VATTR_NULL(&vattr); |
VATTR_NULL(&vattr); |
vattr.va_type = VSOCK; |
vattr.va_type = VSOCK; |
vattr.va_mode = ACCESSPERMS; |
vattr.va_mode = ACCESSPERMS; |
VOP_LEASE(nd.ni_dvp, l, p->p_ucred, LEASE_WRITE); |
VOP_LEASE(nd.ni_dvp, l, p->p_ucred, LEASE_WRITE); |
error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); |
error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); |
|
vn_finished_write(mp, 0); |
if (error) |
if (error) |
goto bad; |
goto bad; |
vp = nd.ni_vp; |
vp = nd.ni_vp; |
Line 620 unp_bind(unp, nam, l) |
|
Line 660 unp_bind(unp, nam, l) |
|
} |
} |
|
|
int |
int |
unp_connect(so, nam, l) |
unp_connect(struct socket *so, struct mbuf *nam, struct lwp *l) |
struct socket *so; |
|
struct mbuf *nam; |
|
struct lwp *l; |
|
{ |
{ |
struct sockaddr_un *sun; |
struct sockaddr_un *sun; |
struct vnode *vp; |
struct vnode *vp; |
Line 682 unp_connect(so, nam, l) |
|
Line 719 unp_connect(so, nam, l) |
|
unp3->unp_flags = unp2->unp_flags; |
unp3->unp_flags = unp2->unp_flags; |
so2 = so3; |
so2 = so3; |
} |
} |
error = unp_connect2(so, so2); |
error = unp_connect2(so, so2, PRU_CONNECT); |
bad: |
bad: |
vput(vp); |
vput(vp); |
bad2: |
bad2: |
Line 691 unp_connect(so, nam, l) |
|
Line 728 unp_connect(so, nam, l) |
|
} |
} |
|
|
int |
int |
unp_connect2(so, so2) |
unp_connect2(struct socket *so, struct socket *so2, int req) |
struct socket *so; |
|
struct socket *so2; |
|
{ |
{ |
struct unpcb *unp = sotounpcb(so); |
struct unpcb *unp = sotounpcb(so); |
struct unpcb *unp2; |
struct unpcb *unp2; |
Line 712 unp_connect2(so, so2) |
|
Line 747 unp_connect2(so, so2) |
|
|
|
case SOCK_STREAM: |
case SOCK_STREAM: |
unp2->unp_conn = unp; |
unp2->unp_conn = unp; |
soisconnected(so); |
if (req == PRU_CONNECT && |
|
((unp->unp_flags | unp2->unp_flags) & UNP_CONNWAIT)) |
|
soisconnecting(so); |
|
else |
|
soisconnected(so); |
soisconnected(so2); |
soisconnected(so2); |
break; |
break; |
|
|
Line 723 unp_connect2(so, so2) |
|
Line 762 unp_connect2(so, so2) |
|
} |
} |
|
|
void |
void |
unp_disconnect(unp) |
unp_disconnect(struct unpcb *unp) |
struct unpcb *unp; |
|
{ |
{ |
struct unpcb *unp2 = unp->unp_conn; |
struct unpcb *unp2 = unp->unp_conn; |
|
|
Line 760 unp_disconnect(unp) |
|
Line 798 unp_disconnect(unp) |
|
} |
} |
|
|
#ifdef notdef |
#ifdef notdef |
unp_abort(unp) |
unp_abort(struct unpcb *unp) |
struct unpcb *unp; |
|
{ |
{ |
|
|
unp_detach(unp); |
unp_detach(unp); |
} |
} |
#endif |
#endif |
|
|
void |
void |
unp_shutdown(unp) |
unp_shutdown(struct unpcb *unp) |
struct unpcb *unp; |
|
{ |
{ |
struct socket *so; |
struct socket *so; |
|
|
Line 780 unp_shutdown(unp) |
|
Line 815 unp_shutdown(unp) |
|
} |
} |
|
|
void |
void |
unp_drop(unp, errno) |
unp_drop(struct unpcb *unp, int errno) |
struct unpcb *unp; |
|
int errno; |
|
{ |
{ |
struct socket *so = unp->unp_socket; |
struct socket *so = unp->unp_socket; |
|
|
Line 798 unp_drop(unp, errno) |
|
Line 831 unp_drop(unp, errno) |
|
} |
} |
|
|
#ifdef notdef |
#ifdef notdef |
unp_drain() |
unp_drain(void) |
{ |
{ |
|
|
} |
} |
#endif |
#endif |
|
|
int |
int |
unp_externalize(rights) |
unp_externalize(struct mbuf *rights, struct lwp *l) |
struct mbuf *rights; |
|
{ |
{ |
struct lwp *l = curlwp; /* XXX */ |
|
struct proc *p = l->l_proc; |
|
struct cmsghdr *cm = mtod(rights, struct cmsghdr *); |
struct cmsghdr *cm = mtod(rights, struct cmsghdr *); |
|
struct proc *p = l->l_proc; |
int i, *fdp; |
int i, *fdp; |
struct file **rp; |
struct file **rp; |
struct file *fp; |
struct file *fp; |
Line 918 unp_externalize(rights) |
|
Line 949 unp_externalize(rights) |
|
} |
} |
|
|
int |
int |
unp_internalize(control, p) |
unp_internalize(struct mbuf *control, struct lwp *l) |
struct mbuf *control; |
|
struct proc *p; |
|
{ |
{ |
|
struct proc *p = l->l_proc; |
struct filedesc *fdescp = p->p_fd; |
struct filedesc *fdescp = p->p_fd; |
struct cmsghdr *cm = mtod(control, struct cmsghdr *); |
struct cmsghdr *newcm, *cm = mtod(control, struct cmsghdr *); |
struct file **rp; |
struct file **rp, **files; |
struct file *fp; |
struct file *fp; |
int i, fd, *fdp; |
int i, fd, *fdp; |
int nfds; |
int nfds; |
Line 946 unp_internalize(control, p) |
|
Line 976 unp_internalize(control, p) |
|
} |
} |
|
|
/* Make sure we have room for the struct file pointers */ |
/* Make sure we have room for the struct file pointers */ |
morespace: |
|
neededspace = CMSG_SPACE(nfds * sizeof(struct file *)) - |
neededspace = CMSG_SPACE(nfds * sizeof(struct file *)) - |
control->m_len; |
control->m_len; |
if (neededspace > M_TRAILINGSPACE(control)) { |
if (neededspace > M_TRAILINGSPACE(control)) { |
|
|
/* if we already have a cluster, the message is just too big */ |
/* allocate new space and copy header into it */ |
if (control->m_flags & M_EXT) |
newcm = malloc( |
|
CMSG_SPACE(nfds * sizeof(struct file *)), |
|
M_MBUF, M_WAITOK); |
|
if (newcm == NULL) |
return (E2BIG); |
return (E2BIG); |
|
memcpy(newcm, cm, sizeof(struct cmsghdr)); |
/* allocate a cluster and try again */ |
files = (struct file **)CMSG_DATA(newcm); |
m_clget(control, M_WAIT); |
} else { |
if ((control->m_flags & M_EXT) == 0) |
/* we can convert in-place */ |
return (ENOBUFS); /* allocation failed */ |
newcm = NULL; |
|
files = (struct file **)CMSG_DATA(cm); |
/* copy the data to the cluster */ |
|
memcpy(mtod(control, char *), cm, cm->cmsg_len); |
|
cm = mtod(control, struct cmsghdr *); |
|
goto morespace; |
|
} |
} |
|
|
/* adjust message & mbuf to note amount of space actually used. */ |
|
cm->cmsg_len = CMSG_LEN(nfds * sizeof(struct file *)); |
|
control->m_len = CMSG_SPACE(nfds * sizeof(struct file *)); |
|
|
|
/* |
/* |
* Transform the file descriptors into struct file pointers, in |
* Transform the file descriptors into struct file pointers, in |
* reverse order so that if pointers are bigger than ints, the |
* reverse order so that if pointers are bigger than ints, the |
* int won't get until we're done. |
* int won't get until we're done. |
*/ |
*/ |
fdp = ((int *)CMSG_DATA(cm)) + nfds - 1; |
fdp = (int *)CMSG_DATA(cm) + nfds - 1; |
rp = ((struct file **)CMSG_DATA(cm)) + nfds - 1; |
rp = files + nfds - 1; |
for (i = 0; i < nfds; i++) { |
for (i = 0; i < nfds; i++) { |
fp = fdescp->fd_ofiles[*fdp--]; |
fp = fdescp->fd_ofiles[*fdp--]; |
simple_lock(&fp->f_slock); |
simple_lock(&fp->f_slock); |
Line 990 unp_internalize(control, p) |
|
Line 1014 unp_internalize(control, p) |
|
simple_unlock(&fp->f_slock); |
simple_unlock(&fp->f_slock); |
unp_rights++; |
unp_rights++; |
} |
} |
|
|
|
if (newcm) { |
|
if (control->m_flags & M_EXT) |
|
MEXTREMOVE(control); |
|
MEXTADD(control, newcm, |
|
CMSG_SPACE(nfds * sizeof(struct file *)), |
|
M_MBUF, NULL, NULL); |
|
cm = newcm; |
|
} |
|
|
|
/* adjust message & mbuf to note amount of space actually used. */ |
|
cm->cmsg_len = CMSG_LEN(nfds * sizeof(struct file *)); |
|
control->m_len = CMSG_SPACE(nfds * sizeof(struct file *)); |
|
|
return (0); |
return (0); |
} |
} |
|
|
struct mbuf * |
struct mbuf * |
unp_addsockcred(p, control) |
unp_addsockcred(struct proc *p, struct mbuf *control) |
struct proc *p; |
|
struct mbuf *control; |
|
{ |
{ |
struct cmsghdr *cmp; |
struct cmsghdr *cmp; |
struct sockcred *sc; |
struct sockcred *sc; |
Line 1076 extern struct domain unixdomain; |
|
Line 1112 extern struct domain unixdomain; |
|
* into a separate thread. |
* into a separate thread. |
*/ |
*/ |
void |
void |
unp_gc() |
unp_gc(void) |
{ |
{ |
struct file *fp, *nextfp; |
struct file *fp, *nextfp; |
struct socket *so, *so1; |
struct socket *so, *so1; |
|
|
} |
} |
|
|
void |
void |
unp_dispose(m) |
unp_dispose(struct mbuf *m) |
struct mbuf *m; |
|
{ |
{ |
|
|
if (m) |
if (m) |
|
|
} |
} |
|
|
void |
void |
unp_scan(m0, op, discard) |
unp_scan(struct mbuf *m0, void (*op)(struct file *), int discard) |
struct mbuf *m0; |
|
void (*op) __P((struct file *)); |
|
int discard; |
|
{ |
{ |
struct mbuf *m; |
struct mbuf *m; |
struct file **rp; |
struct file **rp; |
Line 1273 unp_scan(m0, op, discard) |
|
Line 1305 unp_scan(m0, op, discard) |
|
} |
} |
|
|
void |
void |
unp_mark(fp) |
unp_mark(struct file *fp) |
struct file *fp; |
|
{ |
{ |
if (fp == NULL) |
if (fp == NULL) |
return; |
return; |
|
|
} |
} |
|
|
void |
void |
unp_discard(fp) |
unp_discard(struct file *fp) |
struct file *fp; |
|
{ |
{ |
if (fp == NULL) |
if (fp == NULL) |
return; |
return; |