PERFORCE change 100225 for review
John Baldwin
jhb at FreeBSD.org
Wed Jun 28 19:28:24 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100225
Change 100225 by jhb at jhb_mutex on 2006/06/28 19:28:02
Add a kern_accept().
Affected files ...
.. //depot/projects/smpng/sys/kern/uipc_syscalls.c#80 edit
.. //depot/projects/smpng/sys/sys/syscallsubr.h#35 edit
Differences ...
==== //depot/projects/smpng/sys/kern/uipc_syscalls.c#80 (text+ko) ====
@@ -296,10 +296,50 @@
} */ *uap;
int compat;
{
+ struct sockaddr *name, **sap;
+ socklen_t namelen;
+ int error;
+
+ if (uap->name) {
+ error = copyin(uap->anamelen, &namelen, sizeof (namelen));
+ if (error)
+ return (error);
+ sap = &name;
+ } else
+ sap = NULL;
+
+ error = kern_accept(td, uap->s, sap, &namelen, compat);
+
+ if (uap->name) {
+ /*
+ * return a namelen of zero for older code which might
+ * ignore the return value from accept.
+ */
+ if (error && name == NULL) {
+ (void) copyout(&namelen,
+ uap->anamelen, sizeof(*uap->anamelen));
+ return (error);
+ }
+ if (error == 0) {
+ KASSERT(name != NULL,
+ ("%s: success but no sockaddr", __func__));
+ error = copyout(name, uap->name, namelen);
+ }
+ if (error == 0)
+ error = copyout(&namelen, uap->anamelen,
+ sizeof(namelen));
+ }
+ free(name, M_SONAME);
+ return (error);
+}
+
+int
+kern_accept(struct thread *td, int s, struct sockaddr **name,
+ socklen_t *namelen, int compat)
+{
struct filedesc *fdp;
struct file *headfp, *nfp = NULL;
struct sockaddr *sa = NULL;
- socklen_t namelen;
int error;
struct socket *head, *so;
int fd;
@@ -307,16 +347,15 @@
pid_t pgid;
int tmp;
- fdp = td->td_proc->p_fd;
- if (uap->name) {
- error = copyin(uap->anamelen, &namelen, sizeof (namelen));
- if(error)
- return (error);
- if (namelen < 0)
+ if (name) {
+ *name = NULL;
+ if (*namelen < 0)
return (EINVAL);
}
+
+ fdp = td->td_proc->p_fd;
NET_LOCK_GIANT();
- error = getsock(fdp, uap->s, &headfp, &fflag);
+ error = getsock(fdp, s, &headfp, &fflag);
if (error)
goto done2;
head = headfp->f_data;
@@ -407,38 +446,29 @@
* return a namelen of zero for older code which might
* ignore the return value from accept.
*/
- if (uap->name != NULL) {
- namelen = 0;
- (void) copyout(&namelen,
- uap->anamelen, sizeof(*uap->anamelen));
- }
+ if (name)
+ *namelen = 0;
goto noconnection;
}
if (sa == NULL) {
- namelen = 0;
- if (uap->name)
- goto gotnoname;
- error = 0;
+ if (name)
+ *namelen = 0;
goto done;
}
- if (uap->name) {
+ if (name) {
/* check sa_len before it is destroyed */
- if (namelen > sa->sa_len)
- namelen = sa->sa_len;
+ if (*namelen > sa->sa_len)
+ *namelen = sa->sa_len;
#ifdef COMPAT_OLDSOCK
if (compat)
((struct osockaddr *)sa)->sa_family =
sa->sa_family;
#endif
- error = copyout(sa, uap->name, (u_int)namelen);
- if (!error)
-gotnoname:
- error = copyout(&namelen,
- uap->anamelen, sizeof (*uap->anamelen));
+ *name = sa;
+ sa = NULL;
}
noconnection:
- if (sa)
- FREE(sa, M_SONAME);
+ free(sa, M_SONAME);
/*
* close the new descriptor, assuming someone hasn't ripped it
==== //depot/projects/smpng/sys/sys/syscallsubr.h#35 (text+ko) ====
@@ -50,6 +50,8 @@
int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg,
u_int buflen);
+int kern_accept(struct thread *td, int s, struct sockaddr **name,
+ socklen_t *namelen, int compat);
int kern_access(struct thread *td, char *path, enum uio_seg pathseg,
int flags);
int kern_adjtime(struct thread *td, struct timeval *delta,
More information about the p4-projects
mailing list