summaryrefslogtreecommitdiff
path: root/pflocal/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'pflocal/socket.c')
-rw-r--r--pflocal/socket.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/pflocal/socket.c b/pflocal/socket.c
index 1478dcac..f64e403b 100644
--- a/pflocal/socket.c
+++ b/pflocal/socket.c
@@ -18,5 +18,102 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#include <socket.h>
+
#include "pflocal.h"
+
+/* Connect two sockets */
+error_t
+S_socket_connect2 (struct sock_user *user1, struct sock_user *user2)
+{
+ if (!user1 || !user2)
+ return EOPNOTSUPP;
+ return sock_connect (user1->sock, user2->sock);
+}
+
+/* Make sure we have a queue to listen on. */
+static error_t
+ensure_listenq (struct sock *sock)
+{
+ error_t err = 0;
+ mutex_lock (&sock->lock);
+ if (!sock->listenq)
+ err = listenq_create (0, &sock->listenq);
+ mutex_unlock (&sock->lock);
+ return err;
+}
+
+/* Return a new connection from a socket previously listened. */
+error_t
+S_socket_accept (struct sock_user *user,
+ mach_port_t *port, mach_msg_type_name_t *port_type,
+ mach_port_t *peer_addr, mach_msg_type_name_t *peer_addr_type)
+{
+ error_t err;
+
+ if (!user)
+ return EOPNOTSUPP;
+
+ err = ensure_listenq (sock);
+ if (!err)
+ {
+ struct listenq_request *request;
+ struct sock *peer_sock;
+
+ err =
+ listenq_listen (sock->listenq, sock->modes & O_NONBLOCK,
+ &peer_sock, &request);
+ if (!err)
+ {
+ struct sock *conn_sock;
+
+ err = sock_clone (sock, &conn_sock);
+ if (!err)
+ {
+ err = sock_connect (conn_sock, peer_sock);
+ if (!err)
+ {
+ err = sock_create_port (conn_sock, port, port_type);
+ if (!err)
+ {
+ *addr = ports_get_right (peer_sock->addr);
+ *addr_type = MACH_MSG_MAKE_SEND;
+ }
+ else
+ /* TEAR DOWN THE CONNECTION XXX */;
+ }
+ if (err)
+ sock_free (conn_sock);
+ }
+
+ /* Send back any error to the connecting thread. */
+ listenq_request_complete (request, err);
+ }
+ }
+
+ return err;
+}
+
+/* Prepare a socket of appropriate type for future accept operations. */
+error_t
+S_socket_listen (struct sock_user *user, int queue_limit)
+{
+ error_t err;
+ if (!user)
+ return EOPNOTSUPP;
+ err = ensure_listenq (sock);
+ if (!err)
+ err = listenq_set_length (sock->listenq, queue_limit);
+ return err;
+}
+
+error_t
+S_socket_connect (struct sock_user *user, struct addr *addr)
+{
+ if (!user)
+ return EOPNOTSUPP;
+ if (!addr)
+ return EADDRNOTAVAIL;
+
+}