2 * Copyright © 2012 Canonical Limited
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 * Author: Ryan Lortie <desrt@desrt.ca>
22 #include "dconf-blame.h"
24 #include "dconf-generated.h"
30 typedef DConfDBusServiceInfoSkeletonClass DConfBlameClass
;
33 DConfDBusServiceInfoSkeleton parent_instance
;
38 static void dconf_blame_iface_init (DConfDBusServiceInfoIface
*iface
);
39 G_DEFINE_TYPE_WITH_CODE (DConfBlame
, dconf_blame
, DCONF_DBUS_TYPE_SERVICE_INFO_SKELETON
,
40 G_IMPLEMENT_INTERFACE (DCONF_DBUS_TYPE_SERVICE_INFO
, dconf_blame_iface_init
))
42 #include "../common/dconf-changeset.h"
43 #include "dconf-writer.h"
46 dconf_blame_record (GDBusMethodInvocation
*invocation
)
48 DConfBlame
*blame
= dconf_blame_get ();
57 if (blame
->blame_info
->len
)
58 g_string_append (blame
->blame_info
, "\n====================================================================\n");
60 info
= blame
->blame_info
;
62 g_string_append_printf (info
, "Sender: %s\n", g_dbus_method_invocation_get_sender (invocation
));
63 g_string_append_printf (info
, "Object path: %s\n", g_dbus_method_invocation_get_object_path (invocation
));
64 g_string_append_printf (info
, "Method: %s\n", g_dbus_method_invocation_get_method_name (invocation
));
66 if ((parameters
= g_dbus_method_invocation_get_parameters (invocation
)))
70 tmp
= g_variant_print (parameters
, FALSE
);
71 g_string_append_printf (info
, "Parameters: %s\n", tmp
);
75 reply
= g_dbus_connection_call_sync (g_dbus_method_invocation_get_connection (invocation
),
76 "org.freedesktop.DBus", "/", "org.freedesktop.DBus",
77 "GetConnectionUnixProcessID",
78 g_variant_new ("(s)", g_dbus_method_invocation_get_sender (invocation
)),
79 G_VARIANT_TYPE ("(u)"), G_DBUS_CALL_FLAGS_NONE
, -1, NULL
, &error
);
85 g_variant_get (reply
, "(u)", &pid
);
86 g_string_append_printf (info
, "PID: %u\n", pid
);
87 g_variant_unref (reply
);
91 g_string_append_printf (info
, "Unable to acquire PID: %s\n", error
->message
);
96 const gchar
* const ps_fx
[] = { "ps", "fx", NULL
};
101 if (g_spawn_sync (NULL
, (gchar
**) ps_fx
, NULL
, G_SPAWN_SEARCH_PATH
, NULL
, NULL
,
102 &result_out
, &result_err
, &status
, &error
))
104 g_string_append (info
, "\n=== Process table from time of call follows ('ps fx') ===\n");
105 g_string_append (info
, result_out
);
106 g_string_append (info
, result_err
);
107 g_string_append_printf (info
, "\nps exit status: %u\n", status
);
111 g_string_append_printf (info
, "\nUnable to spawn 'ps fx': %s\n", error
->message
);
112 g_error_free (error
);
118 dconf_blame_handle_blame (DConfDBusServiceInfo
*info
,
119 GDBusMethodInvocation
*invocation
)
121 DConfBlame
*blame
= DCONF_BLAME (info
);
123 dconf_blame_record (invocation
);
125 g_dbus_method_invocation_return_value (invocation
, g_variant_new ("(s)", blame
->blame_info
->str
));
131 dconf_blame_init (DConfBlame
*blame
)
133 blame
->blame_info
= g_string_new (NULL
);
137 dconf_blame_class_init (DConfBlameClass
*class)
142 dconf_blame_iface_init (DConfDBusServiceInfoIface
*iface
)
144 iface
->handle_blame
= dconf_blame_handle_blame
;
148 dconf_blame_enabled (void)
152 if (getenv ("DCONF_BLAME"))
155 fd
= open ("/proc/cmdline", O_RDONLY
);
161 s
= read (fd
, buffer
, sizeof buffer
- 1);
164 if (0 < s
&& s
< sizeof buffer
)
167 if (strstr (buffer
, "DCONF_BLAME"))
176 dconf_blame_get (void)
178 static DConfBlame
*blame
;
179 static gboolean checked
;
183 if (dconf_blame_enabled ())
184 blame
= g_object_new (DCONF_TYPE_BLAME
, NULL
);