diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-11-08 19:50:54 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-11-08 19:50:54 +0000 |
commit | d461cfc6f412e624cb9bef8e8440c0b6129d1911 (patch) | |
tree | 102e4cb1a6582e7ca3f33daea7d99c98460d2b41 /pfinet | |
parent | a38ef5ce7dbb509d4f2af23af4b6967efb57f6e5 (diff) |
Formerly misc.c.~2~
Diffstat (limited to 'pfinet')
-rw-r--r-- | pfinet/misc.c | 102 |
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); +} + + |