Module Name: src
Committed By: christos
Date: Fri Nov 4 02:13:09 UTC 2011
Modified Files:
src/sys/kern: uipc_syscalls.c
Log Message:
Fix error I introduced in previous commit that caused asymmetric connects
when SOCK_NONBLOCK or SOCK_CLOEXEC was specified. Factor out common code
and simplify error return.
To generate a diff of this commit:
cvs rdiff -u -r1.147 -r1.148 src/sys/kern/uipc_syscalls.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/uipc_syscalls.c
diff -u src/sys/kern/uipc_syscalls.c:1.147 src/sys/kern/uipc_syscalls.c:1.148
--- src/sys/kern/uipc_syscalls.c:1.147 Wed Sep 21 14:10:25 2011
+++ src/sys/kern/uipc_syscalls.c Thu Nov 3 22:13:08 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_syscalls.c,v 1.147 2011/09/21 18:10:25 christos Exp $ */
+/* $NetBSD: uipc_syscalls.c,v 1.148 2011/11/04 02:13:08 christos Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.147 2011/09/21 18:10:25 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.148 2011/11/04 02:13:08 christos Exp $");
#include "opt_pipe.h"
@@ -400,8 +400,32 @@ do_sys_connect(struct lwp *l, int fd, st
return (error);
}
+static int
+makesocket(struct lwp *l, file_t **fp, int *fd, int flags, int type,
+ int domain, int proto, struct socket *soo)
+{
+ int error;
+ struct socket *so;
+ int fnonblock = (flags & SOCK_NONBLOCK) ? FNONBLOCK : 0;
+
+ if ((error = socreate(domain, &so, type, proto, l, soo)) != 0)
+ return error;
+
+ if ((error = fd_allocfile(fp, fd)) != 0) {
+ soclose(so);
+ return error;
+ }
+ fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0);
+ (*fp)->f_flag = FREAD|FWRITE|fnonblock;
+ (*fp)->f_type = DTYPE_SOCKET;
+ (*fp)->f_ops = &socketops;
+ (*fp)->f_data = so;
+ return 0;
+}
+
int
-sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap, register_t *retval)
+sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap,
+ register_t *retval)
{
/* {
syscallarg(int) domain;
@@ -415,57 +439,46 @@ sys_socketpair(struct lwp *l, const stru
proc_t *p;
int flags = SCARG(uap, type) & SOCK_FLAGS_MASK;
int type = SCARG(uap, type) & ~SOCK_FLAGS_MASK;
- int fnonblock = (flags & SOCK_NONBLOCK) ? FNONBLOCK : 0;
+ int domain = SCARG(uap, domain);
+ int proto = SCARG(uap, protocol);
p = curproc;
- error = socreate(SCARG(uap, domain), &so1, type,
- SCARG(uap, protocol), l, NULL);
- if (error)
- return (error);
- error = socreate(SCARG(uap, domain), &so2, type,
- SCARG(uap, protocol), l, so1);
+
+ error = makesocket(l, &fp1, &fd, flags, type, domain, proto, NULL);
if (error)
- goto free1;
- if ((error = fd_allocfile(&fp1, &fd)) != 0)
- goto free2;
- fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0);
+ return error;
+ so1 = fp1->f_data;
sv[0] = fd;
- fp1->f_flag = FREAD|FWRITE|fnonblock;
- fp1->f_type = DTYPE_SOCKET;
- fp1->f_ops = &socketops;
- fp1->f_data = so1;
- if ((error = fd_allocfile(&fp2, &fd)) != 0)
- goto free3;
- fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0);
- fp2->f_flag = FREAD|FWRITE|fnonblock;
- fp2->f_type = DTYPE_SOCKET;
- fp2->f_ops = &socketops;
- fp2->f_data = so2;
+
+ error = makesocket(l, &fp2, &fd, flags, type, domain, proto, so1);
+ if (error)
+ goto out;
+ so2 = fp2->f_data;
sv[1] = fd;
+
solock(so1);
error = soconnect2(so1, so2);
- if (error == 0 && SCARG(uap, type) == SOCK_DGRAM) {
+ if (error == 0 && type == SOCK_DGRAM) {
/*
* Datagram socket connection is asymmetric.
*/
error = soconnect2(so2, so1);
}
sounlock(so1);
+
if (error == 0)
- error = copyout(sv, SCARG(uap, rsv), 2 * sizeof(int));
+ error = copyout(sv, SCARG(uap, rsv), sizeof(sv));
if (error == 0) {
fd_affix(p, fp2, sv[1]);
fd_affix(p, fp1, sv[0]);
- return (0);
+ return 0;
}
fd_abort(p, fp2, sv[1]);
- free3:
- fd_abort(p, fp1, sv[0]);
- free2:
(void)soclose(so2);
- free1:
+out:
+ fd_abort(p, fp1, sv[0]);
(void)soclose(so1);
- return (error);
+ return error;
}
int