Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105709064
D3218.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D3218.diff
View Options
Index: head/sys/compat/cloudabi/cloudabi_sock.c
===================================================================
--- head/sys/compat/cloudabi/cloudabi_sock.c
+++ head/sys/compat/cloudabi/cloudabi_sock.c
@@ -27,14 +27,62 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/capsicum.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/protosw.h>
#include <sys/socket.h>
+#include <sys/socketvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/un.h>
+#include <net/vnet.h>
+
+#include <netinet/in.h>
+
#include <compat/cloudabi/cloudabi_proto.h>
#include <compat/cloudabi/cloudabi_syscalldefs.h>
+#include <compat/cloudabi/cloudabi_util.h>
+
+/* Converts FreeBSD's struct sockaddr to CloudABI's cloudabi_sockaddr_t. */
+void
+cloudabi_convert_sockaddr(const struct sockaddr *sa, socklen_t sal,
+ cloudabi_sockaddr_t *rsa)
+{
+ const struct sockaddr_in *sin;
+ const struct sockaddr_in6 *sin6;
+
+ /* Zero-sized socket address. */
+ if (sal < offsetof(struct sockaddr, sa_family) + sizeof(sa->sa_family))
+ return;
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ if (sal < sizeof(struct sockaddr_in))
+ return;
+ sin = (const struct sockaddr_in *)sa;
+ rsa->sa_family = CLOUDABI_AF_INET;
+ memcpy(&rsa->sa_inet.addr, &sin->sin_addr,
+ sizeof(rsa->sa_inet.addr));
+ rsa->sa_inet.port = ntohs(sin->sin_port);
+ return;
+ case AF_INET6:
+ if (sal < sizeof(struct sockaddr_in6))
+ return;
+ sin6 = (const struct sockaddr_in6 *)sa;
+ rsa->sa_family = CLOUDABI_AF_INET6;
+ memcpy(&rsa->sa_inet6.addr, &sin6->sin6_addr,
+ sizeof(rsa->sa_inet6.addr));
+ rsa->sa_inet6.port = ntohs(sin6->sin6_port);
+ return;
+ case AF_UNIX:
+ rsa->sa_family = CLOUDABI_AF_UNIX;
+ return;
+ }
+}
/* Copies a pathname into a UNIX socket address structure. */
static int
@@ -62,9 +110,27 @@
cloudabi_sys_sock_accept(struct thread *td,
struct cloudabi_sys_sock_accept_args *uap)
{
+ struct sockaddr *sa;
+ cloudabi_sockstat_t ss = {};
+ socklen_t sal;
+ int error;
- /* Not implemented. */
- return (ENOSYS);
+ if (uap->buf == NULL) {
+ /* Only return the new file descriptor number. */
+ return (kern_accept(td, uap->s, NULL, NULL, NULL));
+ } else {
+ /* Also return properties of the new socket descriptor. */
+ sal = MAX(sizeof(struct sockaddr_in),
+ sizeof(struct sockaddr_in6));
+ error = kern_accept(td, uap->s, (void *)&sa, &sal, NULL);
+ if (error != 0)
+ return (error);
+
+ /* TODO(ed): Fill the other members of cloudabi_sockstat_t. */
+ cloudabi_convert_sockaddr(sa, sal, &ss.ss_peername);
+ free(sa, M_SONAME);
+ return (copyout(&ss, uap->buf, sizeof(ss)));
+ }
}
int
@@ -134,7 +200,51 @@
cloudabi_sys_sock_stat_get(struct thread *td,
struct cloudabi_sys_sock_stat_get_args *uap)
{
+ cloudabi_sockstat_t ss = {};
+ cap_rights_t rights;
+ struct file *fp;
+ struct sockaddr *sa;
+ struct socket *so;
+ int error;
+
+ error = getsock_cap(td, uap->fd, cap_rights_init(&rights,
+ CAP_GETSOCKOPT | CAP_GETPEERNAME | CAP_GETSOCKNAME), &fp, NULL);
+ if (error != 0)
+ return (error);
+ so = fp->f_data;
+
+ CURVNET_SET(so->so_vnet);
+
+ /* Set ss_sockname. */
+ error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
+ if (error == 0) {
+ cloudabi_convert_sockaddr(sa, sa->sa_len, &ss.ss_sockname);
+ free(sa, M_SONAME);
+ }
+
+ /* Set ss_peername. */
+ if ((so->so_state & (SS_ISCONNECTED | SS_ISCONFIRMING)) != 0) {
+ error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
+ if (error == 0) {
+ cloudabi_convert_sockaddr(sa, sa->sa_len,
+ &ss.ss_peername);
+ free(sa, M_SONAME);
+ }
+ }
+
+ CURVNET_RESTORE();
+
+ /* Set ss_error. */
+ SOCK_LOCK(so);
+ ss.ss_error = so->so_error;
+ if ((uap->flags & CLOUDABI_SOCKSTAT_CLEAR_ERROR) != 0)
+ so->so_error = 0;
+ SOCK_UNLOCK(so);
+
+ /* Set ss_state. */
+ if ((so->so_options & SO_ACCEPTCONN) != 0)
+ ss.ss_state |= CLOUDABI_SOCKSTAT_ACCEPTCONN;
- /* Not implemented. */
- return (ENOSYS);
+ fdrop(fp, td);
+ return (copyout(&ss, uap->buf, sizeof(ss)));
}
Index: head/sys/compat/cloudabi/cloudabi_util.h
===================================================================
--- head/sys/compat/cloudabi/cloudabi_util.h
+++ head/sys/compat/cloudabi/cloudabi_util.h
@@ -28,6 +28,8 @@
#ifndef _CLOUDABI_UTIL_H_
#define _CLOUDABI_UTIL_H_
+#include <sys/socket.h>
+
#include <compat/cloudabi/cloudabi_syscalldefs.h>
struct file;
@@ -41,6 +43,10 @@
/* Converts a FreeBSD errno to a CloudABI errno. */
cloudabi_errno_t cloudabi_convert_errno(int);
+/* Converts FreeBSD's struct sockaddr to CloudABI's cloudabi_sockaddr_t. */
+void cloudabi_convert_sockaddr(const struct sockaddr *, socklen_t,
+ cloudabi_sockaddr_t *);
+
/* Converts a file descriptor to a CloudABI file descriptor type. */
cloudabi_filetype_t cloudabi_convert_filetype(const struct file *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 20, 12:52 PM (20 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15530396
Default Alt Text
D3218.diff (4 KB)
Attached To
Mode
D3218: Add the remaining pointer size independent CloudABI socket system calls.
Attached
Detach File
Event Timeline
Log In to Comment