Skip site navigation (1)Skip section navigation (2)
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>