summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2009-11-08 10:40:51 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2009-11-08 10:40:51 +0800
commit3de77c9d1c5e103e0d63e8aa130ee9ec4255349e (patch)
tree5e4acaa5b66edb81004897e82b193ce5c3e96b6c
parent7e776646d3887d89633e00f669386de5f0814e5f (diff)
milkway: add a socket wrapper
-rw-r--r--milkway/Makefile.am8
-rw-r--r--milkway/mw-inet-address.h2
-rw-r--r--milkway/mw-inet-socket-address.h1
-rw-r--r--milkway/mw-net-types.h (renamed from milkway/mw-socket-family.h)4
-rw-r--r--milkway/mw-socket-address.h2
-rw-r--r--milkway/mw-socket.c581
-rw-r--r--milkway/mw-socket.h114
7 files changed, 704 insertions, 8 deletions
diff --git a/milkway/Makefile.am b/milkway/Makefile.am
index 0059fe7..55bd417 100644
--- a/milkway/Makefile.am
+++ b/milkway/Makefile.am
@@ -35,10 +35,11 @@ milkway_headers = \
mw-main-loop.h \
mw-timeout-source.h \
mw-idle-source.h \
- mw-socket-family.h \
+ mw-net-types.h \
mw-socket-address.h \
mw-inet-address.h \
- mw-inet-socket-address.h
+ mw-inet-socket-address.h \
+ mw-socket.h
libmilkway_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined
libmilkway_la_LIBADD = @DEP_LIBS@ $(PTHREAD_LIBS)
@@ -92,7 +93,8 @@ libmilkway_la_SOURCES = \
mw-network-private.h \
mw-socket-address.c \
mw-inet-address.c \
- mw-inet-socket-address.c
+ mw-inet-socket-address.c \
+ mw-socket.c
milkwayincludedir = $(includedir)/milkway/milkway
milkwayinclude_HEADERS = $(milkway_headers)
diff --git a/milkway/mw-inet-address.h b/milkway/mw-inet-address.h
index ca5b3b2..8080499 100644
--- a/milkway/mw-inet-address.h
+++ b/milkway/mw-inet-address.h
@@ -21,7 +21,7 @@
#define MW_INET_ADDRESS_H
#include <milkway/mw-object.h>
-#include <milkway/mw-socket-family.h>
+#include <milkway/mw-net-types.h>
typedef struct _mw_inet_address_type mw_inet_address_type_t;
typedef struct _mw_inet_address mw_inet_address_t;
diff --git a/milkway/mw-inet-socket-address.h b/milkway/mw-inet-socket-address.h
index 1c942fe..b06cd08 100644
--- a/milkway/mw-inet-socket-address.h
+++ b/milkway/mw-inet-socket-address.h
@@ -21,7 +21,6 @@
#define MW_INET_SOCKET_ADDRESS_H
#include <milkway/mw-socket-address.h>
-#include <milkway/mw-socket-family.h>
#include <milkway/mw-inet-address.h>
typedef struct _mw_inet_socket_address_type mw_inet_socket_address_type_t;
diff --git a/milkway/mw-socket-family.h b/milkway/mw-net-types.h
index 8ced9d3..ad0d8b9 100644
--- a/milkway/mw-socket-family.h
+++ b/milkway/mw-net-types.h
@@ -17,8 +17,8 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
-#ifndef MW_SOCKET_FAMILY_H
-#define MW_SOCKET_FAMILY_H
+#ifndef MW_NET_TYPES_H
+#define MW_NET_TYPES_H
typedef enum {
MW_SOCKET_FAMILY_INVALID,
diff --git a/milkway/mw-socket-address.h b/milkway/mw-socket-address.h
index d809bf6..ce0907e 100644
--- a/milkway/mw-socket-address.h
+++ b/milkway/mw-socket-address.h
@@ -20,7 +20,7 @@
#ifndef MW_SOCKET_ADDRESS_H
#define MW_SOCKET_ADDRESS_H
-#include <milkway/mw-socket-family.h>
+#include <milkway/mw-net-types.h>
#include <milkway/mw-object.h>
#include <milkway/mw-error.h>
diff --git a/milkway/mw-socket.c b/milkway/mw-socket.c
new file mode 100644
index 0000000..ad5bf1f
--- /dev/null
+++ b/milkway/mw-socket.c
@@ -0,0 +1,581 @@
+/* Milkway
+ *
+ * Copyright (C) 2008- Luo Jinghua <sunmoon1997@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "milkwayint.h"
+#include "milkway/mw-socket.h"
+#include "milkway/mw-network-private.h"
+
+#include <errno.h>
+#include <signal.h>
+
+#ifndef MW_OS_WINDOWS
+#include <unistd.h>
+#endif
+
+struct _mw_socket_priv {
+ unsigned int closed : 1;
+ unsigned int connected : 1;
+ unsigned int keepalive : 1;
+ unsigned int listening : 1;
+ unsigned int blocking : 1;
+
+ int backlog;
+
+ int fd;
+ mw_socket_family_t family;
+ mw_socket_type_t type;
+ mw_socket_proto_t proto;
+};
+
+#ifndef MW_OS_WINDOWS
+#define closesocket(fd) close(fd)
+#endif
+
+static int
+get_socket_errno (void)
+{
+#ifndef MW_OS_WINDOWS
+ return errno;
+#else
+ return WSAGetLastError ();
+#endif
+}
+
+static int
+get_socket_error (int err)
+{
+#ifndef MW_OS_WINDOWS
+ switch(err) {
+ case EADDRINUSE:
+ return MW_ADDRESS_IN_USE;
+ case EWOULDBLOCK:
+ return MW_WOULD_BLOCK;
+ case EBADF:
+ return MW_BADF;
+ case ENOTSOCK:
+ return MW_INVALID;
+ case EOPNOTSUPP:
+ case EPFNOSUPPORT:
+ case EAFNOSUPPORT:
+ return MW_NOT_SUPPORTED;
+ default:
+ return MW_INVALID;
+ }
+#else
+ switch (err) {
+ case WSAEADDRINUSE:
+ return MW_ADDRESS_IN_USE;
+ case WSAEWOULDBLOCK:
+ return MW_WOULD_BLOCK;
+ case WSAEACCES:
+ return MW_PERMISSION_DENIED;
+ case WSA_INVALID_HANDLE:
+ case WSA_INVALID_PARAMETER:
+ case WSAEBADF:
+ case WSAENOTSOCK:
+ return MW_INVALID_ARGUMENT;
+ case WSAEPROTONOSUPPORT:
+ return MW_NOT_SUPPORTED;
+ case WSAECANCELLED:
+ return MW_CANCELLED;
+ case WSAESOCKTNOSUPPORT:
+ case WSAEOPNOTSUPP:
+ case WSAEPFNOSUPPORT:
+ case WSAEAFNOSUPPORT:
+ return MW_NOT_SUPPORTED;
+ default:
+ return MW_UNKNOWN;
+ }
+#endif
+}
+
+static mw_socket_t*
+mw_socket_init(mw_socket_t *self)
+{
+ mw_socket_priv_t *priv;
+
+ if (!mw_object_init(&self->base))
+ return NULL;
+
+ priv = MW_GET_PRIV(self, MW_SOCKET_TYPE);
+ priv->closed = MW_FALSE;
+ priv->connected = MW_FALSE;
+ priv->keepalive = MW_FALSE;
+ priv->listening = MW_FALSE;
+ priv->blocking = MW_FALSE;
+ priv->backlog = 10;
+ priv->fd = -1;
+ priv->family = MW_SOCKET_FAMILY_INVALID;
+ priv->type = MW_SOCKET_FAMILY_INVALID;
+ priv->proto = MW_SOCKET_PROTO_UNKNOWN;
+ return self;
+}
+
+static mw_bool_t
+mw_socket_init_socket(mw_socket_t *self,
+ mw_error_t **reterr)
+{
+ int family, type, proto;
+
+ switch (self->priv->family) {
+ case MW_SOCKET_FAMILY_INET:
+ family = AF_INET;
+ break;
+ case MW_SOCKET_FAMILY_INET6:
+ family = AF_INET6;
+ break;
+ case MW_SOCKET_FAMILY_UNIX:
+#ifdef AF_UNIX
+ family = AF_UNIX;
+ break;
+#endif
+ case MW_SOCKET_FAMILY_INVALID:
+ mw_error_set(reterr, MW_ERROR_SOCKET, MW_NOT_SUPPORTED,
+ "Unsupported socket familly");
+ return MW_FALSE;
+ }
+
+ switch (self->priv->type) {
+ case MW_SOCKET_TYPE_STREAM:
+ type = SOCK_STREAM;
+ break;
+ case MW_SOCKET_TYPE_DATAGRAM:
+ type = SOCK_DGRAM;
+ break;
+ case MW_SOCKET_TYPE_SEQPACKET:
+ type = SOCK_SEQPACKET;
+ break;
+ case MW_SOCKET_TYPE_INVALID:
+ mw_error_set(reterr, MW_ERROR_SOCKET, MW_NOT_SUPPORTED,
+ "Unsupported socket type");
+ return MW_FALSE;
+ }
+ proto = self->priv->proto;
+
+ self->priv->fd = socket(family, type, proto);
+ if (self->priv->fd < 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Failed to create a socket");
+ return MW_FALSE;
+ }
+
+ return MW_TRUE;
+}
+
+static mw_bool_t
+mw_socket_init_info(mw_socket_t *self,
+ mw_error_t **reterr)
+{
+ struct sockaddr_storage address;
+ int fd;
+ unsigned int addrlen;
+ unsigned int optlen;
+ int value;
+#ifdef MW_OS_WINDOWS
+ BOOL bool_val;
+#else
+ int bool_val;
+#endif
+
+ fd = self->priv->fd;
+ optlen = sizeof(value);
+ if (getsockopt (fd, SOL_SOCKET, SO_TYPE, (void *)&value, &optlen) != 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Invalid socket");
+ return MW_FALSE;
+ }
+
+ switch (value) {
+ case SOCK_STREAM:
+ self->priv->type = MW_SOCKET_TYPE_STREAM;
+ break;
+ case SOCK_DGRAM:
+ self->priv->type = MW_SOCKET_TYPE_DATAGRAM;
+ break;
+ case SOCK_SEQPACKET:
+ self->priv->type = MW_SOCKET_TYPE_SEQPACKET;
+ break;
+ default:
+ self->priv->type = MW_SOCKET_TYPE_INVALID;
+ break;
+ }
+
+ addrlen = sizeof(address);
+ if (getsockname(fd, (struct sockaddr *) &address, &addrlen) != 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Invalid socket, failed to socket address");
+ return MW_FALSE;
+ }
+
+ switch (address.ss_family) {
+ case AF_INET:
+ self->priv->family = MW_SOCKET_FAMILY_INET;
+ case AF_INET6:
+ self->priv->family = MW_SOCKET_FAMILY_INET6;
+#ifdef AF_UNIX
+ case AF_UNIX:
+ self->priv->family = MW_SOCKET_FAMILY_UNIX;
+ break;
+#endif
+ default:
+ self->priv->family = MW_SOCKET_FAMILY_INVALID;
+ break;
+ }
+
+ if (self->priv->family != MW_SOCKET_FAMILY_INVALID) {
+ addrlen = sizeof(address);
+ if (getpeername (fd, (struct sockaddr *) &address, &addrlen) >= 0)
+ self->priv->connected = MW_TRUE;
+ }
+
+ optlen = sizeof(bool_val);
+ if (getsockopt (fd, SOL_SOCKET, SO_KEEPALIVE,
+ (void *)&bool_val, &optlen) == 0)
+ self->priv->keepalive = !!bool_val;
+ else
+ self->priv->keepalive = MW_FALSE;
+
+ return MW_TRUE;
+}
+
+mw_socket_t*
+mw_socket_new(mw_socket_family_t family,
+ mw_socket_type_t type,
+ mw_socket_proto_t proto,
+ mw_error_t **reterr)
+{
+ mw_socket_t *self;
+
+ self = mw_object_alloc(MW_SOCKET_TYPE);
+ if (!mw_socket_init(self)) {
+ mw_error_set(reterr, MW_ERROR_SOCKET, MW_OUT_OF_MEM,
+ "Failed to construct a socket object");
+ return NULL;
+ }
+
+ self->priv->family = family;
+ self->priv->type = type;
+ self->priv->proto = proto;
+ if (!mw_socket_init_socket(self, reterr)) {
+ MW_SUPER_FINALIZE(self, MW_SOCKET_TYPE)((mw_object_t*)self);
+ return NULL;
+ }
+ return self;
+}
+
+mw_socket_t*
+mw_socket_new_from_fd(int fd,
+ mw_error_t **reterr)
+{
+ mw_socket_t *self;
+
+ self = mw_object_alloc(MW_SOCKET_TYPE);
+ if (!mw_socket_init(self)) {
+ mw_error_set(reterr, MW_ERROR_SOCKET, MW_OUT_OF_MEM,
+ "Failed to construct a socket object");
+ return NULL;
+ }
+
+ self->priv->fd = fd;
+ if (!mw_socket_init_info(self, reterr)) {
+ MW_SUPER_FINALIZE(self, MW_SOCKET_TYPE)((mw_object_t*)self);
+ return NULL;
+ }
+ return self;
+}
+
+int
+mw_socket_get_fd(mw_socket_t *self)
+{
+ return self->priv->fd;
+}
+
+mw_socket_family_t
+mw_socket_get_family(mw_socket_t *self)
+{
+ return self->priv->family;
+}
+
+mw_socket_type_t
+mw_socket_get_type(mw_socket_t *self)
+{
+ return self->priv->type;
+}
+
+mw_socket_proto_t
+mw_socket_get_proto(mw_socket_t *self)
+{
+ return self->priv->proto;
+}
+
+mw_bool_t
+mw_socket_is_connected(mw_socket_t *self)
+{
+ return self->priv->connected;
+}
+
+mw_bool_t
+mw_socket_bind(mw_socket_t *self,
+ mw_socket_address_t *address,
+ mw_error_t **reterr)
+{
+ struct sockaddr_storage addr;
+ int fd = self->priv->fd;
+
+ if (!mw_socket_address_to_native(address, &addr,
+ sizeof(addr), reterr))
+ return MW_FALSE;
+ if (bind (fd, (const struct sockaddr*)&addr,
+ mw_socket_address_get_native_size(address)) < 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Failed to bind socket to a address");
+ return MW_FALSE;
+ }
+
+ return MW_TRUE;
+}
+
+mw_bool_t
+mw_socket_listen(mw_socket_t *self,
+ int backlog,
+ mw_error_t **reterr)
+{
+ int fd = self->priv->fd;
+
+ if (listen (fd, self->priv->backlog) < 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Failed to listen");
+ return MW_FALSE;
+ }
+
+ return MW_TRUE;
+}
+
+mw_bool_t
+mw_socket_connect(mw_socket_t *self,
+ mw_socket_address_t *address,
+ mw_error_t **reterr)
+{
+ struct sockaddr_storage addr;
+ int fd = self->priv->fd;
+
+ if (!mw_socket_address_to_native(address, &addr,
+ sizeof(addr), reterr))
+ return MW_FALSE;
+ if (connect (fd, (const struct sockaddr*)&addr,
+ mw_socket_address_get_native_size(address)) < 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Failed to connect to peer");
+ return MW_FALSE;
+ }
+
+ return MW_TRUE;
+}
+
+mw_socket_t*
+mw_socket_accept(mw_socket_t *self,
+ mw_error_t **reterr)
+{
+ int fd = self->priv->fd;
+ mw_socket_t *client;
+ int ret;
+
+#ifndef MW_OS_WINDOWS
+ do {
+ ret = accept (fd, NULL, 0);
+ } while (ret < 0 && errno != EINTR);
+#else
+ ret = accept (fd, NULL, 0);
+#endif
+ if (ret < 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Failed to connect to peer");
+ return MW_FALSE;
+ }
+
+#ifdef MW_OS_WINDOWS
+ /* The socket inherits the accepting sockets event mask and even object,
+ we need to remove that */
+ WSAEventSelect (ret, NULL, 0);
+#endif
+
+ client = mw_socket_new_from_fd (ret, reterr);
+ if (!client)
+ closesocket (ret);
+ else
+ client->priv->proto = self->priv->proto;
+
+ return client;
+}
+
+int
+mw_socket_recv(mw_socket_t *self,
+ void *buffer,
+ size_t size,
+ mw_error_t **reterr)
+{
+ int fd = self->priv->fd;
+ int ret;
+
+ do {
+ ret = recv(fd, buffer, size, 0);
+ if (ret < 0) {
+ int error = get_socket_errno ();
+
+ if (error == EINTR)
+ continue;
+
+ mw_error_set (reterr, MW_ERROR_SOCKET,
+ get_socket_error (error),
+ "Failed to send data");
+ return -1;
+ }
+ } while (0);
+
+ return ret;
+}
+
+int
+mw_socket_send(mw_socket_t *self,
+ const void *buffer,
+ size_t size,
+ mw_error_t **reterr)
+{
+ int fd = self->priv->fd;
+ int ret;
+
+ do {
+ ret = send(fd, buffer, size, 0);
+ if (ret < 0) {
+ int error = get_socket_errno ();
+
+ if (error == EINTR)
+ continue;
+
+ mw_error_set (reterr, MW_ERROR_SOCKET,
+ get_socket_error (error),
+ "Failed to send data");
+ return -1;
+ }
+ } while (0);
+
+ return ret;
+}
+
+mw_bool_t
+mw_socket_shutdown(mw_socket_t *self,
+ mw_bool_t shutdown_read,
+ mw_bool_t shutdown_write,
+ mw_error_t **reterr)
+{
+ int how;
+
+ if (!shutdown_read && !shutdown_write)
+ return MW_TRUE;
+
+#ifndef MW_OS_WINDOWS
+ if (shutdown_read && shutdown_write)
+ how = SHUT_RDWR;
+ else if (shutdown_read)
+ how = SHUT_RD;
+ else
+ how = SHUT_WR;
+#else
+ if (shutdown_read && shutdown_write)
+ how = SD_BOTH;
+ else if (shutdown_read)
+ how = SD_RECEIVE;
+ else
+ how = SD_SEND;
+#endif
+
+ if (shutdown (self->priv->fd, how) != 0) {
+ mw_error_set (reterr, MW_ERROR_SOCKET,
+ get_socket_error (get_socket_errno()),
+ "Failed to shutdown socket");
+ return MW_FALSE;
+ }
+
+ if (shutdown_read && shutdown_write)
+ self->priv->connected = MW_FALSE;
+
+ return MW_TRUE;
+}
+
+mw_bool_t
+mw_socket_close(mw_socket_t *self,
+ mw_error_t **reterr)
+{
+ mw_socket_priv_t *priv = self->priv;
+ int ret;
+
+ if (priv->closed)
+ return MW_TRUE;
+
+ for (;;) {
+#ifdef MW_OS_WINDOWS
+ ret = closesocket (priv->fd);
+#else
+ do {
+ ret = close (priv->fd);
+ } while (ret < 0 && errno != EINTR);
+#endif
+ if (ret < 0) {
+ mw_error_set(reterr, MW_ERROR_SOCKET,
+ get_socket_error(get_socket_errno()),
+ "Failed to close socket");
+ return MW_FALSE;
+ }
+ }
+
+ priv->closed = MW_TRUE;
+ priv->connected = MW_FALSE;
+ return MW_TRUE;
+}
+
+static void
+mw_socket_finalize(mw_object_t *super)
+{
+ mw_socket_t *self = (mw_socket_t*)super;
+
+ if (self->priv->fd > 0)
+ mw_socket_close(self, NULL);
+ MW_SUPER_FINALIZE(super, MW_SOCKET_TYPE)(super);
+}
+
+static void
+mw_socket__type_init(mw_socket__type_t *self)
+{
+#ifdef SIGPIPE
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ self->base.finalize = mw_socket_finalize;
+}
+
+typedef mw_socket_t mw_socket__t;
+MW_DEFINE_GET_TYPE(mw_socket_, mw_socket__type_t,
+ MW_OBJECT_TYPE, "MWSocket", sizeof (mw_socket_priv_t));
diff --git a/milkway/mw-socket.h b/milkway/mw-socket.h
new file mode 100644
index 0000000..17171e4
--- /dev/null
+++ b/milkway/mw-socket.h
@@ -0,0 +1,114 @@
+/* Milkway
+ *
+ * Copyright (C) 2008- Luo Jinghua <sunmoon1997@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef MW_SOCKET_H
+#define MW_SOCKET_H
+
+#include <milkway/mw-object.h>
+#include <milkway/mw-socket-address.h>
+#include <milkway/mw-net-types.h>
+
+typedef struct _mw_socket__type mw_socket__type_t;
+typedef struct _mw_socket mw_socket_t;
+typedef struct _mw_socket_priv mw_socket_priv_t;
+
+#define MW_SOCKET_TYPE mw_socket__get_type()
+#define MW_ERROR_SOCKET "MWSocketError"
+
+struct _mw_socket__type {
+ mw_object_type_t base;
+};
+
+struct _mw_socket {
+ mw_object_t base;
+
+ mw_socket_priv_t *priv;
+};
+
+mw_public mw_socket__type_t*
+mw_socket__get_type(void);
+
+mw_public mw_socket_t*
+mw_socket_new(mw_socket_family_t family,
+ mw_socket_type_t type,
+ mw_socket_proto_t proto,
+ mw_error_t **reterr);
+
+mw_public mw_socket_t*
+mw_socket_new_from_fd(int fd,
+ mw_error_t **reterr);
+
+mw_public int
+mw_socket_get_fd(mw_socket_t *self);
+
+mw_public mw_socket_family_t
+mw_socket_get_family(mw_socket_t *self);
+
+mw_public mw_socket_type_t
+mw_socket_get_type(mw_socket_t *self);
+
+mw_public mw_socket_proto_t
+mw_socket_get_proto(mw_socket_t *self);
+
+mw_public mw_bool_t
+mw_socket_is_connected(mw_socket_t *self);
+
+mw_public mw_bool_t
+mw_socket_bind(mw_socket_t *self,
+ mw_socket_address_t *address,
+ mw_error_t **reterr);
+
+mw_public mw_bool_t
+mw_socket_listen(mw_socket_t *self,
+ int backlog,
+ mw_error_t **reterr);
+
+mw_public mw_bool_t
+mw_socket_connect(mw_socket_t *self,
+ mw_socket_address_t *address,
+ mw_error_t **reterr);
+
+mw_socket_t*
+mw_socket_accept(mw_socket_t *self,
+ mw_error_t **reterr);
+
+mw_public int
+mw_socket_recv(mw_socket_t *self,
+ void *buffer,
+ size_t size,
+ mw_error_t **reterrr);
+
+mw_public int
+mw_socket_send(mw_socket_t *self,
+ const void *buffer,
+ size_t size,
+ mw_error_t **reterrr);
+
+mw_public mw_bool_t
+mw_socket_shutdown(mw_socket_t *self,
+ mw_bool_t read,
+ mw_bool_t write,
+ mw_error_t **reterr);
+
+mw_public mw_bool_t
+mw_socket_close(mw_socket_t *self,
+ mw_error_t **reterr);
+
+
+#endif