summaryrefslogtreecommitdiff
path: root/daemon/gvfsdaemonutils.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@src.gnome.org>2007-09-13 09:23:06 +0000
committerAlexander Larsson <alexl@src.gnome.org>2007-09-13 09:23:06 +0000
commit6bf04c8bba1ae0c423952268cbbbdf7fde04f27f (patch)
tree74a13d9473d20cd4ed8eec6cf4ca346a9a35d9aa /daemon/gvfsdaemonutils.c
parentfc23a9a11cbeb452f3a4d66d848e3e8725333650 (diff)
downloadgvfs-6bf04c8bba1ae0c423952268cbbbdf7fde04f27f.tar.gz
More work on daemon scheduling etc
Original git commit by Alexander Larsson <alex@localhost.localdomain> at 1161615951 +0200 svn path=/trunk/; revision=119
Diffstat (limited to 'daemon/gvfsdaemonutils.c')
-rw-r--r--daemon/gvfsdaemonutils.c164
1 files changed, 157 insertions, 7 deletions
diff --git a/daemon/gvfsdaemonutils.c b/daemon/gvfsdaemonutils.c
index 132bfd13..2dc3fa04 100644
--- a/daemon/gvfsdaemonutils.c
+++ b/daemon/gvfsdaemonutils.c
@@ -1,18 +1,168 @@
#include <config.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <glib/gthread.h>
+#include <glib/gi18n.h>
#include "gvfsdaemonutils.h"
+static gint32 extra_fd_slot = -1;
+static GStaticMutex extra_lock = G_STATIC_MUTEX_INIT;
+
+typedef struct {
+ int extra_fd;
+ int fd_count;
+} ConnectionExtra;
+
+/* We use _ for escaping, so its not valid */
+#define VALID_INITIAL_NAME_CHARACTER(c) \
+ ( ((c) >= 'A' && (c) <= 'Z') || \
+ ((c) >= 'a' && (c) <= 'z') )
+#define VALID_NAME_CHARACTER(c) \
+ ( ((c) >= '0' && (c) <= '9') || \
+ ((c) >= 'A' && (c) <= 'Z') || \
+ ((c) >= 'a' && (c) <= 'z'))
+
+
+static void
+append_escaped_name (GString *s,
+ const char *unescaped)
+{
+ char c;
+ gboolean first;
+ static const gchar hex[16] = "0123456789ABCDEF";
+
+ while ((c = *unescaped++) != 0)
+ {
+ if (first)
+ {
+ if (VALID_INITIAL_NAME_CHARACTER (c))
+ {
+ g_string_append_c (s, c);
+ continue;
+ }
+ }
+ else
+ {
+ if (VALID_NAME_CHARACTER (c))
+ {
+ g_string_append_c (s, c);
+ continue;
+ }
+ }
+
+ first = FALSE;
+ g_string_append_c (s, '_');
+ g_string_append_c (s, hex[((guchar)c) >> 4]);
+ g_string_append_c (s, hex[((guchar)c) & 0xf]);
+ }
+}
+
DBusMessage *
dbus_message_new_error_from_gerror (DBusMessage *message,
GError *error)
{
- char *error_name;
DBusMessage *reply;
-
- error_name = g_strdup_printf ("org.glib.GError.%s.%d",
- g_quark_to_string (error->domain),
- error->code);
- reply = dbus_message_new_error (message, error_name, error->message);
- g_free (error_name);
+ GString *str;
+
+ str = g_string_new ("org.glib.GError.");
+ append_escaped_name (str, g_quark_to_string (error->domain));
+ g_string_append_printf (str, ".c%d", error->code);
+ reply = dbus_message_new_error (message, str->str, error->message);
+ g_string_free (str, TRUE);
return reply;
}
+
+static void
+free_extra (gpointer p)
+{
+ ConnectionExtra *extra = p;
+ close (extra->extra_fd);
+ g_free (extra);
+}
+
+void
+dbus_connection_add_fd_send_fd (DBusConnection *connection,
+ int extra_fd)
+{
+ ConnectionExtra *extra;
+
+ if (extra_fd_slot == -1 &&
+ !dbus_connection_allocate_data_slot (&extra_fd_slot))
+ g_error ("Unable to allocate data slot");
+
+ extra = g_new0 (ConnectionExtra, 1);
+ extra->extra_fd = extra_fd;
+
+ if (!dbus_connection_set_data (connection, extra_fd_slot, extra, free_extra))
+ g_error ("Out of memory");
+}
+
+static int
+send_fd (int connection_fd,
+ int fd)
+{
+ struct msghdr msg;
+ struct iovec vec;
+ char buf[1] = {'x'};
+ char ccmsg[CMSG_SPACE (sizeof (fd))];
+ struct cmsghdr *cmsg;
+ int ret;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+
+ vec.iov_base = buf;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_control = ccmsg;
+ msg.msg_controllen = sizeof (ccmsg);
+ cmsg = CMSG_FIRSTHDR (&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN (sizeof(fd));
+ *(int*)CMSG_DATA (cmsg) = fd;
+ msg.msg_controllen = cmsg->cmsg_len;
+ msg.msg_flags = 0;
+
+ ret = sendmsg (connection_fd, &msg, 0);
+ g_print ("sendmesg ret: %d\n", ret);
+ return ret;
+}
+
+gboolean
+dbus_connection_send_fd (DBusConnection *connection,
+ int fd,
+ int *fd_id,
+ GError **error)
+{
+ ConnectionExtra *extra;
+
+ g_assert (extra_fd_slot != -1);
+
+ extra = dbus_connection_get_data (connection, extra_fd_slot);
+
+ g_assert (extra != NULL);
+
+ g_static_mutex_lock (&extra_lock);
+
+ if (send_fd (extra->extra_fd, fd) == -1)
+ {
+ g_set_error (error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ _("Error sending fd: %s"),
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ *fd_id = extra->fd_count++;
+
+ g_static_mutex_unlock (&extra_lock);
+
+ return TRUE;
+}