static gboolean async_server_iofunc(GIOChannel *iochannel, GIOCondition c, gpointer data) { GUnixSocket *server = (GUnixSocket *) data; g_assert(server != NULL); if (c & G_IO_IN) { GUnixSocket *client = NULL; GIOChannel *client_iochannel = NULL; client_state *cs = NULL; client = gnet_unix_socket_server_accept(server); g_assert(client != NULL); client_iochannel = gnet_unix_socket_get_io_channel(client); g_assert(client_iochannel != NULL); cs = g_new0(client_state, 1); cs->socket = client; g_io_add_watch(client_iochannel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, async_client_iofunc, cs); } else { fprintf(stderr, "Server error %d\n", c); return FALSE; } return TRUE; }
void _odccm_connection_broker_take_connection (OdccmConnectionBroker *self, GConn *conn) { OdccmConnectionBrokerPrivate *priv = ODCCM_CONNECTION_BROKER_GET_PRIVATE (self); GRand *rnd; GIOChannel *chan; guint uid; g_assert (priv->conn == NULL); priv->conn = conn; rnd = g_rand_new (); priv->filename = g_strdup_printf ("/tmp/odccm-%08x%08x%08x%08x.sock", g_rand_int (rnd), g_rand_int (rnd), g_rand_int (rnd), g_rand_int (rnd)); g_rand_free (rnd); priv->server = gnet_unix_socket_server_new (priv->filename); _odccm_get_dbus_sender_uid (dbus_g_method_get_sender (priv->ctx), &uid); chmod (priv->filename, S_IRUSR | S_IWUSR); chown (priv->filename, uid, -1); chan = gnet_unix_socket_get_io_channel (priv->server); g_io_add_watch (chan, G_IO_IN, server_socket_readable_cb, self); dbus_g_method_return (priv->ctx, priv->filename); priv->ctx = NULL; }
static gboolean server_socket_readable_cb (GIOChannel *source, GIOCondition condition, gpointer user_data) { OdccmConnectionBroker *self = user_data; OdccmConnectionBrokerPrivate *priv = ODCCM_CONNECTION_BROKER_GET_PRIVATE (self); GUnixSocket *sock; gint dev_fd, fd, ret; struct msghdr msg = { 0, }; struct cmsghdr *cmsg; gchar cmsg_buf[CMSG_SPACE (sizeof (dev_fd))]; struct iovec iov; guchar dummy_byte = 0x7f; sock = gnet_unix_socket_server_accept_nonblock (priv->server); if (sock == NULL) { g_warning ("%s: client disconnected?", G_STRFUNC); return TRUE; } dev_fd = g_io_channel_unix_get_fd (priv->conn->iochannel); fd = g_io_channel_unix_get_fd (gnet_unix_socket_get_io_channel (sock)); msg.msg_control = cmsg_buf; msg.msg_controllen = sizeof (cmsg_buf); msg.msg_iov = &iov; msg.msg_iovlen = 1; cmsg = CMSG_FIRSTHDR (&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN (sizeof (dev_fd)); *((gint *) CMSG_DATA (cmsg)) = dev_fd; iov.iov_base = &dummy_byte; iov.iov_len = sizeof (dummy_byte); ret = sendmsg (fd, &msg, MSG_NOSIGNAL); if (ret != 1) { g_warning ("%s: sendmsg returned %d", G_STRFUNC, ret); } g_signal_emit (self, signals[DONE], 0); return FALSE; }
static void normal_echoserver(gchar *path, gboolean abstract) { GUnixSocket *client = NULL; gchar buffer[1024]; gsize n; GIOChannel *ioclient = NULL; GIOError e; g_assert(path != NULL); /* Create the server */ if (abstract) server = gnet_unix_socket_server_new_abstract(path); else server = gnet_unix_socket_server_new(path); g_assert(server != NULL); while ((client = gnet_unix_socket_server_accept(server)) != NULL) { ioclient = gnet_unix_socket_get_io_channel(client); g_assert(ioclient != NULL); while ((e = gnet_io_channel_readline(ioclient, buffer, sizeof(buffer), &n)) == G_IO_ERROR_NONE && (n > 0)) { e = gnet_io_channel_writen(ioclient, buffer, n, &n); if (e != G_IO_ERROR_NONE) break; if (fwrite(buffer, n, 1, stdout) != 1) { fprintf (stderr, "Error: fwrite to stdout failed: %s\n", g_strerror (errno)); } } if (e != G_IO_ERROR_NONE) fprintf(stderr, "\nRecieved error %d (closing socket).\n", e); gnet_unix_socket_delete (client); } }
static void async_echoserver(gchar *path, gboolean abstract) { GIOChannel *iochannel = NULL; GMainLoop *main_loop = NULL; g_assert(path != NULL); if (abstract) server = gnet_unix_socket_server_new_abstract(path); else server = gnet_unix_socket_server_new(path); g_assert(server != NULL); main_loop = g_main_new(FALSE); /* Add a watch for incoming clients */ iochannel = gnet_unix_socket_get_io_channel(server); g_io_add_watch(iochannel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, async_server_iofunc, server); /* Start the main loop */ g_main_run(main_loop); }