Asynchronous accepts now work, the rest should go smoothly :-)
[cascardo/gnio.git] / gnio / gsocket.c
index 9a61e11..f6c586e 100644 (file)
@@ -194,7 +194,7 @@ g_socket_set_blocking (GSocket  *socket,
   if ((arg = fcntl (socket->priv->fd, F_GETFL, NULL)) < 0)
     g_warning ("Error getting socket status flags: %s", g_strerror (errno));
 
-  arg = blocking ? arg | O_NONBLOCK : arg & ~O_NONBLOCK;
+  arg = blocking ? arg & ~O_NONBLOCK : arg | O_NONBLOCK;
 
   if (fcntl (socket->priv->fd, F_SETFL, arg) < 0)
     g_warning ("Error setting socket status flags: %s", g_strerror (errno));
@@ -299,9 +299,30 @@ accept_callback (AcceptData *data,
                  GIOCondition condition,
                  gint fd)
 {
+  GSocket *socket;
+  GSimpleAsyncResult *result;
+  gint ret;
+
+  socket = data->socket;
+
   if (condition & G_IO_IN)
     {
-      g_print ("WE COULD ACCEPT HERE\n");
+      if ((ret = accept (socket->priv->fd, NULL, 0)) < 0)
+        {
+          if (errno == EAGAIN)
+            return TRUE;
+
+          result = g_simple_async_result_new_error (G_OBJECT (socket), data->callback, data->user_data, G_IO_ERROR, g_io_error_from_errno (errno), "error accepting connection");
+        }
+      else
+        {
+          result = g_simple_async_result_new (G_OBJECT (socket), data->callback, data->user_data, g_socket_accept_async);
+
+          g_simple_async_result_set_op_res_gpointer (result, g_socket_new_from_fd (ret), g_object_unref);
+        }
+      g_simple_async_result_complete (result);
+
+      g_object_unref (result);
     }
 
   return FALSE;
@@ -360,7 +381,18 @@ g_socket_accept_finish (GSocket       *socket,
                         GAsyncResult  *result,
                         GError       **error)
 {
-  return NULL;
+  GSocket *new_socket;
+  GSimpleAsyncResult *simple;
+
+  g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
+
+  simple = G_SIMPLE_ASYNC_RESULT (result);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_accept_async);
+
+  new_socket = g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+
+  return new_socket;
 }
 
 gboolean