* Copyright (c) 1982, 1986, 1989, 1990 Regents of the University of California.
* All rights reserved.
*
- * Redistribution is only permitted until one year after the first shipment
- * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
- * binary forms are permitted provided that: (1) source distributions retain
- * this entire copyright notice and comment, and (2) distributions including
- * binaries display the following acknowledgement: This product includes
- * software developed by the University of California, Berkeley and its
- * contributors'' in the documentation or other materials provided with the
- * distribution and in all advertising materials mentioning features or use
- * of this software. 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 AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. 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.
*
- * @(#)uipc_syscalls.c 7.20 (Berkeley) 6/30/90
+ * 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_syscalls.c 7.24 (Berkeley) 6/3/91
*/
#include "param.h"
-#include "user.h"
+#include "filedesc.h"
#include "proc.h"
#include "file.h"
#include "buf.h"
* System call interface to the socket abstraction.
*/
-struct file *getsock();
extern struct fileops socketops;
-/* ARGSUSED */
socket(p, uap, retval)
struct proc *p;
register struct args {
} *uap;
int *retval;
{
+ struct filedesc *fdp = p->p_fd;
struct socket *so;
struct file *fp;
int fd, error;
- if (error = falloc(&fp, &fd))
+ if (error = falloc(p, &fp, &fd))
return (error);
fp->f_flag = FREAD|FWRITE;
fp->f_type = DTYPE_SOCKET;
fp->f_ops = &socketops;
if (error = socreate(uap->domain, &so, uap->type, uap->protocol)) {
- u.u_ofile[fd] = 0;
- crfree(fp->f_cred);
- fp->f_count = 0;
+ fdp->fd_ofiles[fd] = 0;
+ ffree(fp);
} else {
fp->f_data = (caddr_t)so;
*retval = fd;
} *uap;
int *retval;
{
- register struct file *fp;
+ struct file *fp;
struct mbuf *nam;
int error;
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
if (error = sockargs(&nam, uap->name, uap->namelen, MT_SONAME))
return (error);
} *uap;
int *retval;
{
- register struct file *fp;
+ struct file *fp;
int error;
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
return (solisten((struct socket *)fp->f_data, uap->backlog));
}
#define accept1 accept
#endif
-/* ARGSUSED */
accept1(p, uap, retval)
struct proc *p;
register struct args {
if (uap->name && (error = copyin((caddr_t)uap->anamelen,
(caddr_t)&namelen, sizeof (namelen))))
return (error);
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
s = splnet();
so = (struct socket *)fp->f_data;
splx(s);
return (error);
}
- if (error = falloc(&fp, retval)) {
+ if (error = falloc(p, &fp, retval)) {
splx(s);
return (error);
}
} *uap;
int *retval;
{
- register struct file *fp;
+ struct file *fp;
register struct socket *so;
struct mbuf *nam;
int error, s;
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
so = (struct socket *)fp->f_data;
if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING))
return (error);
}
-/* ARGSUSED */
socketpair(p, uap, retval)
struct proc *p;
register struct args {
} *uap;
int retval[];
{
+ register struct filedesc *fdp = p->p_fd;
struct file *fp1, *fp2;
struct socket *so1, *so2;
int fd, error, sv[2];
return (error);
if (error = socreate(uap->domain, &so2, uap->type, uap->protocol))
goto free1;
- if (error = falloc(&fp1, &fd))
+ if (error = falloc(p, &fp1, &fd))
goto free2;
sv[0] = fd;
fp1->f_flag = FREAD|FWRITE;
fp1->f_type = DTYPE_SOCKET;
fp1->f_ops = &socketops;
fp1->f_data = (caddr_t)so1;
- if (error = falloc(&fp2, &fd))
+ if (error = falloc(p, &fp2, &fd))
goto free3;
fp2->f_flag = FREAD|FWRITE;
fp2->f_type = DTYPE_SOCKET;
retval[1] = sv[1]; /* XXX ??? */
return (error);
free4:
- crfree(fp2->f_cred);
- fp2->f_count = 0;
- u.u_ofile[sv[1]] = 0;
+ ffree(fp2);
+ fdp->fd_ofiles[sv[1]] = 0;
free3:
- crfree(fp1->f_cred);
- fp1->f_count = 0;
- u.u_ofile[sv[0]] = 0;
+ ffree(fp1);
+ fdp->fd_ofiles[sv[0]] = 0;
free2:
(void)soclose(so2);
free1:
return (error);
}
-/* ARGSUSED */
sendto(p, uap, retval)
struct proc *p;
register struct args {
{
struct msghdr msg;
struct iovec aiov;
+ int error;
msg.msg_name = uap->to;
msg.msg_namelen = uap->tolen;
#endif
aiov.iov_base = uap->buf;
aiov.iov_len = uap->len;
- return (sendit(uap->s, &msg, uap->flags, retval));
+ return (sendit(p, uap->s, &msg, uap->flags, retval));
}
#ifdef COMPAT_43
-/* ARGSUSED */
osend(p, uap, retval)
struct proc *p;
register struct args {
aiov.iov_len = uap->len;
msg.msg_control = 0;
msg.msg_flags = 0;
- return (sendit(uap->s, &msg, uap->flags, retval));
+ return (sendit(p, uap->s, &msg, uap->flags, retval));
}
#define MSG_COMPAT 0x8000
-/* ARGSUSED */
osendmsg(p, uap, retval)
struct proc *p;
register struct args {
goto done;
msg.msg_flags = MSG_COMPAT;
msg.msg_iov = iov;
- error = sendit(uap->s, &msg, uap->flags, retval);
+ error = sendit(p, uap->s, &msg, uap->flags, retval);
done:
if (iov != aiov)
FREE(iov, M_IOV);
}
#endif
-/* ARGSUSED */
sendmsg(p, uap, retval)
struct proc *p;
register struct args {
#ifdef COMPAT_43
msg.msg_flags = 0;
#endif
- error = sendit(uap->s, &msg, uap->flags, retval);
+ error = sendit(p, uap->s, &msg, uap->flags, retval);
done:
if (iov != aiov)
FREE(iov, M_IOV);
return (error);
}
-sendit(s, mp, flags, retsize)
+sendit(p, s, mp, flags, retsize)
+ register struct proc *p;
int s;
register struct msghdr *mp;
int flags, *retsize;
{
- register struct file *fp;
+ struct file *fp;
struct uio auio;
register struct iovec *iov;
register int i;
struct iovec *ktriov = NULL;
#endif
- fp = getsock(s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, s, &fp))
return (error);
auio.uio_iov = mp->msg_iov;
auio.uio_iovcnt = mp->msg_iovlen;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_WRITE;
+ auio.uio_procp = p;
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
iov = mp->msg_iov;
} else
control = 0;
#ifdef KTRACE
- if (KTRPOINT(u.u_procp, KTR_GENIO)) {
+ if (KTRPOINT(p, KTR_GENIO)) {
int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
error == EINTR || error == EWOULDBLOCK))
error = 0;
if (error == EPIPE)
- psignal(u.u_procp, SIGPIPE);
+ psignal(p, SIGPIPE);
}
if (error == 0)
*retsize = len - auio.uio_resid;
#ifdef KTRACE
if (ktriov != NULL) {
if (error == 0)
- ktrgenio(u.u_procp->p_tracep, s, UIO_WRITE,
+ ktrgenio(p->p_tracep, s, UIO_WRITE,
ktriov, *retsize, error);
FREE(ktriov, M_TEMP);
}
}
#endif
-/* ARGSUSED */
recvfrom(p, uap, retval)
struct proc *p;
register struct args {
aiov.iov_len = uap->len;
msg.msg_control = 0;
msg.msg_flags = uap->flags;
- return (recvit(uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));
+ return (recvit(p, uap->s, &msg, (caddr_t)uap->fromlenaddr, retval));
}
#ifdef COMPAT_43
-/* ARGSUSED */
orecv(p, uap, retval)
struct proc *p;
register struct args {
aiov.iov_len = uap->len;
msg.msg_control = 0;
msg.msg_flags = uap->flags;
- return (recvit(uap->s, &msg, (caddr_t)0, retval));
+ return (recvit(p, uap->s, &msg, (caddr_t)0, retval));
}
/*
* overlays the new one, missing only the flags, and with the (old) access
* rights where the control fields are now.
*/
-/* ARGSUSED */
orecvmsg(p, uap, retval)
struct proc *p;
register struct args {
(unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
goto done;
msg.msg_iov = iov;
- error = recvit(uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
+ error = recvit(p, uap->s, &msg, (caddr_t)&uap->msg->msg_namelen, retval);
if (msg.msg_controllen && error == 0)
error = copyout((caddr_t)&msg.msg_controllen,
}
#endif
-/* ARGSUSED */
recvmsg(p, uap, retval)
struct proc *p;
register struct args {
if (error = copyin((caddr_t)uiov, (caddr_t)iov,
(unsigned)(msg.msg_iovlen * sizeof (struct iovec))))
goto done;
- if ((error = recvit(uap->s, &msg, (caddr_t)0, retval)) == 0) {
+ if ((error = recvit(p, uap->s, &msg, (caddr_t)0, retval)) == 0) {
msg.msg_iov = uiov;
error = copyout((caddr_t)&msg, (caddr_t)uap->msg, sizeof(msg));
}
return (error);
}
-recvit(s, mp, namelenp, retsize)
+recvit(p, s, mp, namelenp, retsize)
+ register struct proc *p;
int s;
register struct msghdr *mp;
caddr_t namelenp;
int *retsize;
{
- register struct file *fp;
+ struct file *fp;
struct uio auio;
register struct iovec *iov;
register int i;
struct iovec *ktriov = NULL;
#endif
- fp = getsock(s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, s, &fp))
return (error);
auio.uio_iov = mp->msg_iov;
auio.uio_iovcnt = mp->msg_iovlen;
auio.uio_segflg = UIO_USERSPACE;
auio.uio_rw = UIO_READ;
+ auio.uio_procp = p;
auio.uio_offset = 0; /* XXX */
auio.uio_resid = 0;
iov = mp->msg_iov;
return (EINVAL);
}
#ifdef KTRACE
- if (KTRPOINT(u.u_procp, KTR_GENIO)) {
+ if (KTRPOINT(p, KTR_GENIO)) {
int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
#ifdef KTRACE
if (ktriov != NULL) {
if (error == 0)
- ktrgenio(u.u_procp->p_tracep, s, UIO_READ,
+ ktrgenio(p->p_tracep, s, UIO_READ,
ktriov, len - auio.uio_resid, error);
FREE(ktriov, M_TEMP);
}
struct file *fp;
int error;
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
return (soshutdown((struct socket *)fp->f_data, uap->how));
}
struct mbuf *m = NULL;
int error;
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
if (uap->valsize > MLEN)
return (EINVAL);
struct mbuf *m = NULL;
int valsize, error;
- fp = getsock(uap->s, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->s, &fp))
return (error);
if (uap->val) {
if (error = copyin((caddr_t)uap->avalsize, (caddr_t)&valsize,
struct args *uap;
int retval[];
{
+ register struct filedesc *fdp = p->p_fd;
struct file *rf, *wf;
struct socket *rso, *wso;
int fd, error;
return (error);
if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0))
goto free1;
- if (error = falloc(&rf, &fd))
+ if (error = falloc(p, &rf, &fd))
goto free2;
retval[0] = fd;
rf->f_flag = FREAD;
rf->f_type = DTYPE_SOCKET;
rf->f_ops = &socketops;
rf->f_data = (caddr_t)rso;
- if (error = falloc(&wf, &fd))
+ if (error = falloc(p, &wf, &fd))
goto free3;
wf->f_flag = FWRITE;
wf->f_type = DTYPE_SOCKET;
goto free4;
return (0);
free4:
- wf->f_count = 0;
- u.u_ofile[retval[1]] = 0;
+ ffree(wf);
+ fdp->fd_ofiles[retval[1]] = 0;
free3:
- rf->f_count = 0;
- u.u_ofile[retval[0]] = 0;
+ ffree(rf);
+ fdp->fd_ofiles[retval[0]] = 0;
free2:
(void)soclose(wso);
free1:
} *uap;
int *retval;
{
- register struct file *fp;
+ struct file *fp;
register struct socket *so;
struct mbuf *m;
int len, error;
- fp = getsock(uap->fdes, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->fdes, &fp))
return (error);
if (error = copyin((caddr_t)uap->alen, (caddr_t)&len, sizeof (len)))
return (error);
} *uap;
int *retval;
{
- register struct file *fp;
+ struct file *fp;
register struct socket *so;
struct mbuf *m;
int len, error;
- fp = getsock(uap->fdes, &error);
- if (fp == 0)
+ if (error = getsock(p->p_fd, uap->fdes, &fp))
return (error);
so = (struct socket *)fp->f_data;
if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
return (error);
}
-struct file *
-getsock(fdes, errp)
- int fdes, *errp;
+getsock(fdp, fdes, fpp)
+ struct filedesc *fdp;
+ int fdes;
+ struct file **fpp;
{
register struct file *fp;
- if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) {
- *errp = EBADF;
- return (0);
- }
- if (fp->f_type != DTYPE_SOCKET) {
- *errp = ENOTSOCK;
- return (0);
- }
- return (fp);
+ if ((unsigned)fdes >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[fdes]) == NULL)
+ return (EBADF);
+ if (fp->f_type != DTYPE_SOCKET)
+ return (ENOTSOCK);
+ *fpp = fp;
+ return (0);
}