From owner-svn-src-head@freebsd.org Wed Mar 22 06:43:11 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D811AD169C3; Wed, 22 Mar 2017 06:43:11 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9611811D9; Wed, 22 Mar 2017 06:43:11 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v2M6hAEt057918; Wed, 22 Mar 2017 06:43:10 GMT (envelope-from ed@FreeBSD.org) Received: (from ed@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v2M6hArU057914; Wed, 22 Mar 2017 06:43:10 GMT (envelope-from ed@FreeBSD.org) Message-Id: <201703220643.v2M6hArU057914@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ed set sender to ed@FreeBSD.org using -f From: Ed Schouten Date: Wed, 22 Mar 2017 06:43:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315700 - in head/sys/compat: cloudabi cloudabi32 cloudabi64 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Mar 2017 06:43:11 -0000 Author: ed Date: Wed Mar 22 06:43:10 2017 New Revision: 315700 URL: https://svnweb.freebsd.org/changeset/base/315700 Log: Make file descriptor passing work for CloudABI's sendmsg(). Reduce the potential amount of code duplication between cloudabi32 and cloudabi64 by creating a cloudabi_sock_recv() utility function. The cloudabi32 and cloudabi64 modules will then only contain code to convert the iovecs to the native pointer size. In cloudabi_sock_recv(), we can now construct an SCM_RIGHTS cmsghdr in an mbuf and pass that on to kern_sendit(). Modified: head/sys/compat/cloudabi/cloudabi_sock.c head/sys/compat/cloudabi/cloudabi_util.h head/sys/compat/cloudabi32/cloudabi32_sock.c head/sys/compat/cloudabi64/cloudabi64_sock.c Modified: head/sys/compat/cloudabi/cloudabi_sock.c ============================================================================== --- head/sys/compat/cloudabi/cloudabi_sock.c Wed Mar 22 05:27:20 2017 (r315699) +++ head/sys/compat/cloudabi/cloudabi_sock.c Wed Mar 22 06:43:10 2017 (r315700) @@ -30,7 +30,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -243,3 +245,51 @@ cloudabi_sys_sock_stat_get(struct thread fdrop(fp, td); return (copyout(&ss, uap->buf, sizeof(ss))); } + +int +cloudabi_sock_send(struct thread *td, cloudabi_fd_t fd, struct iovec *data, + size_t datalen, const cloudabi_fd_t *fds, size_t fdslen, + cloudabi_msgflags_t flags, size_t *rdatalen) +{ + struct msghdr hdr = { + .msg_iov = data, + .msg_iovlen = datalen, + }; + struct mbuf *control; + int error, mflags; + + /* Convert flags. */ + mflags = MSG_NOSIGNAL; + if (flags & CLOUDABI_MSG_EOR) + mflags |= MSG_EOR; + + /* Convert file descriptor array to an SCM_RIGHTS message. */ + if (fdslen > MCLBYTES || CMSG_SPACE(fdslen * sizeof(int)) > MCLBYTES) { + return (EINVAL); + } else if (fdslen > 0) { + struct cmsghdr *chdr; + + control = m_get2(CMSG_SPACE(fdslen * sizeof(int)), + M_WAITOK, MT_CONTROL, 0); + control->m_len = CMSG_SPACE(fdslen * sizeof(int)); + + chdr = mtod(control, struct cmsghdr *); + chdr->cmsg_len = CMSG_LEN(fdslen * sizeof(int)); + chdr->cmsg_level = SOL_SOCKET; + chdr->cmsg_type = SCM_RIGHTS; + error = copyin(fds, CMSG_DATA(chdr), fdslen * sizeof(int)); + if (error != 0) { + m_free(control); + return (error); + } + } else { + control = NULL; + } + + error = kern_sendit(td, fd, &hdr, mflags, control, UIO_USERSPACE); + if (error != 0) + return (error); + *rdatalen = td->td_retval[0]; + td->td_retval[0] = 0; + return (0); +} Modified: head/sys/compat/cloudabi/cloudabi_util.h ============================================================================== --- head/sys/compat/cloudabi/cloudabi_util.h Wed Mar 22 05:27:20 2017 (r315699) +++ head/sys/compat/cloudabi/cloudabi_util.h Wed Mar 22 06:43:10 2017 (r315700) @@ -77,6 +77,10 @@ int cloudabi_futex_lock_wrlock(struct th cloudabi_scope_t, cloudabi_clockid_t, cloudabi_timestamp_t, cloudabi_timestamp_t); +/* Socket operations. */ +int cloudabi_sock_send(struct thread *, cloudabi_fd_t, struct iovec *, size_t, + const cloudabi_fd_t *, size_t, cloudabi_msgflags_t, size_t *); + /* vDSO setup and teardown. */ void cloudabi_vdso_init(struct sysentvec *, char *, char *); void cloudabi_vdso_destroy(struct sysentvec *); Modified: head/sys/compat/cloudabi32/cloudabi32_sock.c ============================================================================== --- head/sys/compat/cloudabi32/cloudabi32_sock.c Wed Mar 22 05:27:20 2017 (r315699) +++ head/sys/compat/cloudabi32/cloudabi32_sock.c Wed Mar 22 06:43:10 2017 (r315700) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Nuxi, https://nuxi.nl/ + * Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -105,44 +105,37 @@ cloudabi32_sys_sock_send(struct thread * cloudabi32_send_in_t si; cloudabi32_send_out_t so = {}; cloudabi32_ciovec_t iovobj; - struct msghdr msghdr = {}; + struct iovec *iov; const cloudabi32_ciovec_t *user_iov; - size_t i; - int error, flags; + size_t datalen, i; + int error; error = copyin(uap->in, &si, sizeof(si)); if (error != 0) return (error); - /* Convert results in cloudabi_send_in_t to struct msghdr. */ + /* Convert iovecs to native format. */ if (si.si_data_len > UIO_MAXIOV) return (EINVAL); - msghdr.msg_iovlen = si.si_data_len; - msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec), + iov = malloc(si.si_data_len * sizeof(struct iovec), M_SOCKET, M_WAITOK); user_iov = TO_PTR(si.si_data); - for (i = 0; i < msghdr.msg_iovlen; i++) { + for (i = 0; i < si.si_data_len; i++) { error = copyin(&user_iov[i], &iovobj, sizeof(iovobj)); if (error != 0) { - free(msghdr.msg_iov, M_SOCKET); + free(iov, M_SOCKET); return (error); } - msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf); - msghdr.msg_iov[i].iov_len = iovobj.buf_len; + iov[i].iov_base = TO_PTR(iovobj.buf); + iov[i].iov_len = iovobj.buf_len; } - flags = MSG_NOSIGNAL; - if (si.si_flags & CLOUDABI_MSG_EOR) - flags |= MSG_EOR; - - /* TODO(ed): Add file descriptor passing. */ - error = kern_sendit(td, uap->sock, &msghdr, flags, NULL, UIO_USERSPACE); - free(msghdr.msg_iov, M_SOCKET); + error = cloudabi_sock_send(td, uap->sock, iov, si.si_data_len, + TO_PTR(si.si_fds), si.si_fds_len, si.si_flags, &datalen); + free(iov, M_SOCKET); if (error != 0) return (error); - /* Convert results in msghdr to cloudabi_send_out_t. */ - so.so_datalen = td->td_retval[0]; - td->td_retval[0] = 0; + so.so_datalen = datalen; return (copyout(&so, uap->out, sizeof(so))); } Modified: head/sys/compat/cloudabi64/cloudabi64_sock.c ============================================================================== --- head/sys/compat/cloudabi64/cloudabi64_sock.c Wed Mar 22 05:27:20 2017 (r315699) +++ head/sys/compat/cloudabi64/cloudabi64_sock.c Wed Mar 22 06:43:10 2017 (r315700) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Nuxi, https://nuxi.nl/ + * Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -105,44 +105,37 @@ cloudabi64_sys_sock_send(struct thread * cloudabi64_send_in_t si; cloudabi64_send_out_t so = {}; cloudabi64_ciovec_t iovobj; - struct msghdr msghdr = {}; + struct iovec *iov; const cloudabi64_ciovec_t *user_iov; - size_t i; - int error, flags; + size_t datalen, i; + int error; error = copyin(uap->in, &si, sizeof(si)); if (error != 0) return (error); - /* Convert results in cloudabi_send_in_t to struct msghdr. */ + /* Convert iovecs to native format. */ if (si.si_data_len > UIO_MAXIOV) return (EINVAL); - msghdr.msg_iovlen = si.si_data_len; - msghdr.msg_iov = malloc(msghdr.msg_iovlen * sizeof(struct iovec), + iov = malloc(si.si_data_len * sizeof(struct iovec), M_SOCKET, M_WAITOK); user_iov = TO_PTR(si.si_data); - for (i = 0; i < msghdr.msg_iovlen; i++) { + for (i = 0; i < si.si_data_len; i++) { error = copyin(&user_iov[i], &iovobj, sizeof(iovobj)); if (error != 0) { - free(msghdr.msg_iov, M_SOCKET); + free(iov, M_SOCKET); return (error); } - msghdr.msg_iov[i].iov_base = TO_PTR(iovobj.buf); - msghdr.msg_iov[i].iov_len = iovobj.buf_len; + iov[i].iov_base = TO_PTR(iovobj.buf); + iov[i].iov_len = iovobj.buf_len; } - flags = MSG_NOSIGNAL; - if (si.si_flags & CLOUDABI_MSG_EOR) - flags |= MSG_EOR; - - /* TODO(ed): Add file descriptor passing. */ - error = kern_sendit(td, uap->sock, &msghdr, flags, NULL, UIO_USERSPACE); - free(msghdr.msg_iov, M_SOCKET); + error = cloudabi_sock_send(td, uap->sock, iov, si.si_data_len, + TO_PTR(si.si_fds), si.si_fds_len, si.si_flags, &datalen); + free(iov, M_SOCKET); if (error != 0) return (error); - /* Convert results in msghdr to cloudabi_send_out_t. */ - so.so_datalen = td->td_retval[0]; - td->td_retval[0] = 0; + so.so_datalen = datalen; return (copyout(&so, uap->out, sizeof(so))); }