summaryrefslogtreecommitdiff
path: root/pfinet/socket-ops.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-10-25 22:29:25 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-10-25 22:29:25 +0000
commitfbc36e6518e4ddf9d46b1deacdaa9c583513b207 (patch)
treebc09c6b291cd1587088706b5ddd37d683d6acb7f /pfinet/socket-ops.c
parentb70339c9e9191c3d62c66bfa0abe9138050a15c7 (diff)
Formerly socket-ops.c.~2~
Diffstat (limited to 'pfinet/socket-ops.c')
-rw-r--r--pfinet/socket-ops.c181
1 files changed, 180 insertions, 1 deletions
diff --git a/pfinet/socket-ops.c b/pfinet/socket-ops.c
index 873560d8..9998ca8c 100644
--- a/pfinet/socket-ops.c
+++ b/pfinet/socket-ops.c
@@ -54,7 +54,186 @@ S_socket_accept (struct sock_user *user,
mach_port_t *addr_port,
mach_msg_type_name_t *addr_port_type)
{
+ struct socket *sock, *newsock;
+ error_t err;
+ int i;
+
+ if (!user)
+ return EOPNOTSUPP;
+
+ mutex_lock (&global_lock);
+
+ sock = user->sock;
+ newsock = 0;
+ err = 0;
+
+ if ((sock->state != SS_UNCONNECTED)
+ || (!(sock->flags & SO_ACCEPTCON)))
+ err = EINVAL;
+ else if (!(newsock = sock_alloc ()))
+ err = ENOSR;
+
+ if (err)
+ goto out;
+
+ newsock->type = sock->type;
+ newsock->ops = sock->ops;
+
+ err = - (*sock->ops->dup) (newsock, sock);
+ if (err)
+ goto out;
+
+ /* O_NONBLOCK flag in Linux comes from fd table for third
+ arg here... what to do? XXX */
+ err = - (*sock->ops->accept) (sock, newsock, 0);
+ if (err)
+ goto out;
+
+ make_sockaddr_port (newsock, 1, addr_port, addr_port_type);
+
+ *new_port = ports_get_right (make_sock_user (newsock, sock->isroot));
+ *new_port_type = MACH_MSG_TYPE_MAKE_SEND;
+
+ out:
+ if (err && newsock)
+ sock_release (newsock);
+ mutex_unlock (&global_lock);
+ return err;
+}
+
+error_t
+S_socket_connect (struct sock_user *user,
+ struct sock_addr *addr)
+{
+ struct socket *sock;
+ error_t err;
+
+ if (!user || !addr)
+ return EOPNOTSUPP;
+
+ sock = user->sock;
+
+ mutex_lock (&global_lock);
+
+ err = 0;
+
+ if (sock->state == SS_CONNECTED
+ && sock->type != SOCK_DGRAM)
+ err = EISCONN;
+ else if (sock->state != SS_UNCONNECTED
+ && sock->state != SS_CONNECTING)
+ err = EINVAL;
+
+
+ if (!err)
+ /* Flags here come from fd table in Linux for O_NONBLOCK... XXX */
+ err = - (*sock->ops->connect) (sock, addr->address, addr->len, 0);
+
+ mutex_unlock (&global_lock);
+
+ return err;
+}
+
+error_t
+S_socket_bind (struct user_sock *user,
+ struct sock_addr *addr)
+{
+ error_t err;
+
+ if (!sock)
+ return EOPNOTSUPP;
+
+ mutex_lock (&global_lock);
+ err = (*user->sock->ops->bind) (user->sock, addr->address, addr->len);
+ mutex_unlock (&global_lock);
+
+ return err;
+}
+
+error_t
+S_socket_name (struct sock_user *user,
+ mach_port_t *addr_port,
+ mach_port_name_t *addr_port_name)
+{
if (!user)
return EOPNOTSUPP;
-
+ mutex_lock (&global_lock);
+ make_sockaddr_port (user->sock, 0, addr_port, addr_port_name);
+ mutex_unlock (&global_lock);
+ return 0;
+}
+
+error_t
+S_socket_peername (struct sock_user *user,
+ mach_port_t *addr_port,
+ mach_port_name_t *addr_port_name)
+{
+ error_t err;
+
+ if (!user)
+ return EOPNOTSUPP;
+
+ mutex_lock (&global_lock);
+ err = make_sockaddr_port (user->sock, 1, addr_port, addr_port_name);
+ mutex_unlock (&global_lock);
+
+ return err;
+}
+
+error_t
+S_socket_connect2 (struct sock_user *user1,
+ struct sock_user *user2)
+{
+ error_t err;
+
+ if (!user1 || !user2)
+ return EOPNOTSUPP;
+
+ mutex_lock (&global_lock);
+
+ if (user1->sock->type != user2->sock->type)
+ err = EINVAL;
+ else if (user1->sock->state != SS_UNCONNECTED
+ && user2->sock->state != SS_UNCONNECTED)
+ err = EISCONN;
+ else
+ err = - (*user1->sock->ops->socketpair) (user1->sock, user2->sock);
+
+ if (!err)
+ {
+ user1->sock->conn = user2->sock;
+ user2->sock->conn = user1->sock;
+ user1->sock->state = SS_CONNECTED;
+ user2->sock->state = SS_CONNECTED;
+ }
+
+ mutex_unlock (&global_lock);
+ return err;
+}
+
+error_t
+S_socket_create_address (mach_port_t server,
+ int sockaddr_type,
+ char *data,
+ mach_msg_number_t *data_len,
+ mach_port_t *addr_port,
+ mach_msg_type_name_t *addr_port_type,
+ int binding)
+{
+ struct sock_addr *addr;
+
+ if (sockaddr_type != AF_INET)
+ return EAFNOTSUPP;
+
+ addr = ports_allocate_port (pfinet_bucket,
+ sizeof (struct sock_addr) + data_len,
+ addrport_class);
+ addr->len = data_len;
+ bcopy (data, addr->address, data_len);
+
+ *addr_port = ports_get_right (addr);
+ *addr_port_type = MACH_MSG_TYPE_MAKE_SEND;
+ return 0;
+}
+