summaryrefslogtreecommitdiff
path: root/pfinet
diff options
context:
space:
mode:
Diffstat (limited to 'pfinet')
-rw-r--r--pfinet/misc.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/pfinet/misc.c b/pfinet/misc.c
index 6a70814a..b2c3df28 100644
--- a/pfinet/misc.c
+++ b/pfinet/misc.c
@@ -36,3 +36,105 @@ make_sock_user (struct socket *sock, int isroot)
return user;
}
+/* Create a sockaddr port. Fill in *ADDR and *ADDRTYPE accordingly.
+ The address should come from SOCK; PEER is 0 if we want this socket's
+ name and 1 if we want the peer's name. */
+error_t
+make_sockaddr_port (struct socket *sock,
+ int peer,
+ mach_port_t *addr,
+ mach_msg_type_name_t *addrtype)
+{
+ char *buf[128];
+ int buflen = 128;
+ error_t err;
+ struct sock_addr *addrstruct;
+
+ err = (*sock->ops->getname) (sock, (struct sockaddr *)buf, &buflen, peer);
+ if (err)
+ return err;
+
+ addrstruct = ports_allocate_port (pfinet_bucket,
+ sizeof (struct sock_addr) + buflen,
+ addrport_clas);
+ addrstruct->len = buflen;
+ bcopy (buf, addrstruct->address, buflen);
+ *addr = ports_get_right (addr);
+ *addrtype = MACH_MSG_TYPE_MAKE_SEND;
+ return 0;
+}
+
+struct sock_user *
+begin_using_socket_port (mach_port_t port)
+{
+ return ports_lookup_port (pfinet_bucket, port, socketport_class);
+}
+
+void
+end_using_socket_port (struct sock_user *user)
+{
+ ports_port_deref (user);
+}
+
+struct sock_addr *
+begin_using_sockaddr_port (mach_port_t port)
+{
+ return ports_lookup_port (pfinet_bucket, port, addrport_class);
+}
+
+void
+end_using_sockaddr_port (struct sock_addr *addr)
+{
+ ports_port_deref (addr);
+}
+
+struct socket *
+sock_alloc (void)
+{
+ struct socket *sock;
+
+ sock = malloc (sizeof (struct socket));
+ bzero (sock, sizoef (struct socket));
+
+ sock->state = SS_UNCONNECTED;
+}
+
+static inline void sock_release_peer(struct socket *peer)
+{
+ peer->state = SS_DISCONNECTING;
+ wake_up_interruptible(peer->wait);
+ sock_wake_async(peer, 1);
+}
+
+void
+sock_release (struct socket *sock)
+{
+ int oldstate;
+ struct socket *peersock, *nextsock;
+
+ if ((oldstate = sock->state) != SS_UNCONNECTED)
+ sock->state = SS_DISCONNECTING;
+
+ /*
+ * Wake up anyone waiting for connections.
+ */
+
+ for (peersock = sock->iconn; peersock; peersock = nextsock)
+ {
+ nextsock = peersock->next;
+ sock_release_peer(peersock);
+ }
+
+ /*
+ * Wake up anyone we're connected to. First, we release the
+ * protocol, to give it a chance to flush data, etc.
+ */
+
+ peersock = (oldstate == SS_CONNECTED) ? sock->conn : NULL;
+ if (sock->ops)
+ (*sock->ops->release) (sock, peersock);
+ if (peersock)
+ sock_release_peer(peersock);
+}
+
+