summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authordchagin <dchagin@FreeBSD.org>2009-05-31 12:12:38 +0000
committerdchagin <dchagin@FreeBSD.org>2009-05-31 12:12:38 +0000
commitceed8fedd1150a6a8402e15ed264f72c76fb2a6a (patch)
tree44cd99cc657082d1dc34dcb6f13ee1f0d4e4676b /sys/kern/uipc_syscalls.c
parent861b77b0175f90ae49506e05c337ab56500751eb (diff)
downloadFreeBSD-src-ceed8fedd1150a6a8402e15ed264f72c76fb2a6a.zip
FreeBSD-src-ceed8fedd1150a6a8402e15ed264f72c76fb2a6a.tar.gz
Split native socketpair() syscall onto kern_socketpair() which should
be used by kernel consumers and socketpair() itself. Approved by: kib (mentor) MFC after: 1 month
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r--sys/kern/uipc_syscalls.c53
1 files changed, 29 insertions, 24 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 9adbbc6..66eb7e1 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -588,51 +588,43 @@ done1:
}
int
-socketpair(td, uap)
- struct thread *td;
- struct socketpair_args /* {
- int domain;
- int type;
- int protocol;
- int *rsv;
- } */ *uap;
+kern_socketpair(struct thread *td, int domain, int type, int protocol,
+ int *rsv)
{
struct filedesc *fdp = td->td_proc->p_fd;
struct file *fp1, *fp2;
struct socket *so1, *so2;
- int fd, error, sv[2];
+ int fd, error;
#ifdef MAC
/* We might want to have a separate check for socket pairs. */
- error = mac_socket_check_create(td->td_ucred, uap->domain, uap->type,
- uap->protocol);
+ error = mac_socket_check_create(td->td_ucred, domain, type,
+ protocol);
if (error)
return (error);
#endif
- error = socreate(uap->domain, &so1, uap->type, uap->protocol,
- td->td_ucred, td);
+ error = socreate(domain, &so1, type, protocol, td->td_ucred, td);
if (error)
return (error);
- error = socreate(uap->domain, &so2, uap->type, uap->protocol,
- td->td_ucred, td);
+ error = socreate(domain, &so2, type, protocol, td->td_ucred, td);
if (error)
goto free1;
/* On success extra reference to `fp1' and 'fp2' is set by falloc. */
error = falloc(td, &fp1, &fd);
if (error)
goto free2;
- sv[0] = fd;
+ rsv[0] = fd;
fp1->f_data = so1; /* so1 already has ref count */
error = falloc(td, &fp2, &fd);
if (error)
goto free3;
fp2->f_data = so2; /* so2 already has ref count */
- sv[1] = fd;
+ rsv[1] = fd;
error = soconnect2(so1, so2);
if (error)
goto free4;
- if (uap->type == SOCK_DGRAM) {
+ if (type == SOCK_DGRAM) {
/*
* Datagram socket connection is asymmetric.
*/
@@ -642,18 +634,14 @@ socketpair(td, uap)
}
finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops);
finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops);
- so1 = so2 = NULL;
- error = copyout(sv, uap->rsv, 2 * sizeof (int));
- if (error)
- goto free4;
fdrop(fp1, td);
fdrop(fp2, td);
return (0);
free4:
- fdclose(fdp, fp2, sv[1], td);
+ fdclose(fdp, fp2, rsv[1], td);
fdrop(fp2, td);
free3:
- fdclose(fdp, fp1, sv[0], td);
+ fdclose(fdp, fp1, rsv[0], td);
fdrop(fp1, td);
free2:
if (so2 != NULL)
@@ -664,6 +652,23 @@ free1:
return (error);
}
+int
+socketpair(struct thread *td, struct socketpair_args *uap)
+{
+ int error, sv[2];
+
+ error = kern_socketpair(td, uap->domain, uap->type,
+ uap->protocol, sv);
+ if (error)
+ return (error);
+ error = copyout(sv, uap->rsv, 2 * sizeof(int));
+ if (error) {
+ (void)kern_close(td, sv[0]);
+ (void)kern_close(td, sv[1]);
+ }
+ return (error);
+}
+
static int
sendit(td, s, mp, flags)
struct thread *td;
OpenPOWER on IntegriCloud