Date: Wed, 28 Jun 2006 19:28:22 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 100225 for review Message-ID: <200606281928.k5SJSM2o042135@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100225 Change 100225 by jhb@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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606281928.k5SJSM2o042135>