@@ -25,23 +25,36 @@ Q_LOGGING_CATEGORY(dsgApp, "dtk.core.dsg", QtInfoMsg)
2525
2626DCORE_BEGIN_NAMESPACE
2727
28+ // D-Bus resource deleters for RAII management
29+ static void dbusErrorDeleter (DBusError *error) {
30+ if (error) { dbus_error_free (error); delete error; }
31+ }
32+
33+ static void dbusConnectionDeleter (DBusConnection *conn) {
34+ if (conn) dbus_connection_unref (conn);
35+ }
36+
37+ static void dbusMessageDeleter (DBusMessage *msg) {
38+ if (msg) dbus_message_unref (msg);
39+ }
40+
2841// D-Bus utility functions using libdbus-1
2942static bool checkDBusServiceActivatable (const QString &service)
3043{
31- DBusError error;
32- dbus_error_init (& error);
44+ auto error = std::unique_ptr<DBusError, void (*)(DBusError*)>( new DBusError, dbusErrorDeleter) ;
45+ dbus_error_init (error. get () );
3346
34- DBusConnection *connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
35- if (dbus_error_is_set (&error)) {
36- qCWarning (dsgApp) << " Failed to connect to session bus:" << error.message ;
37- dbus_error_free (&error);
47+ DBusConnection *connection = dbus_bus_get (DBUS_BUS_SESSION, error.get ());
48+ if (dbus_error_is_set (error.get ())) {
49+ qCWarning (dsgApp) << " Failed to connect to session bus:" << error->message ;
3850 return false ;
3951 }
4052
4153 if (!connection) {
4254 qCWarning (dsgApp) << " Failed to get session bus connection" ;
4355 return false ;
4456 }
57+ auto connGuard = std::unique_ptr<DBusConnection, void (*)(DBusConnection*)>(connection, dbusConnectionDeleter);
4558
4659 // Create method call to check if service is registered
4760 DBusMessage *msg = dbus_message_new_method_call (
@@ -53,86 +66,71 @@ static bool checkDBusServiceActivatable(const QString &service)
5366
5467 if (!msg) {
5568 qCWarning (dsgApp) << " Failed to create D-Bus message" ;
56- dbus_connection_unref (connection);
5769 return false ;
5870 }
71+ auto msgGuard = std::unique_ptr<DBusMessage, void (*)(DBusMessage*)>(msg, dbusMessageDeleter);
5972
6073 const char *serviceName = service.toUtf8 ().constData ();
6174 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &serviceName, DBUS_TYPE_INVALID)) {
6275 qCWarning (dsgApp) << " Failed to append arguments to D-Bus message" ;
63- dbus_message_unref (msg);
64- dbus_connection_unref (connection);
6576 return false ;
6677 }
6778
6879 // Send message and get reply
69- DBusMessage *reply = dbus_connection_send_with_reply_and_block (connection, msg, 1000 , & error);
70- dbus_message_unref (msg);
80+ DBusMessage *reply = dbus_connection_send_with_reply_and_block (connection, msg, 1000 , error. get () );
81+ msgGuard. reset (); // msg is consumed by the call
7182
72- if (dbus_error_is_set (&error)) {
73- qCWarning (dsgApp) << " D-Bus call failed:" << error.message ;
74- dbus_error_free (&error);
75- dbus_connection_unref (connection);
83+ if (dbus_error_is_set (error.get ())) {
84+ qCWarning (dsgApp) << " D-Bus call failed:" << error->message ;
7685 return false ;
7786 }
7887
7988 if (!reply) {
8089 qCWarning (dsgApp) << " No reply received from D-Bus" ;
81- dbus_connection_unref (connection);
8290 return false ;
8391 }
92+ auto replyGuard = std::unique_ptr<DBusMessage, void (*)(DBusMessage*)>(reply, dbusMessageDeleter);
8493
8594 dbus_bool_t hasOwner = FALSE ;
86- if (!dbus_message_get_args (reply, &error, DBUS_TYPE_BOOLEAN, &hasOwner, DBUS_TYPE_INVALID)) {
87- qCWarning (dsgApp) << " Failed to parse D-Bus reply:" << error.message ;
88- dbus_error_free (&error);
89- dbus_message_unref (reply);
90- dbus_connection_unref (connection);
95+ if (!dbus_message_get_args (reply, error.get (), DBUS_TYPE_BOOLEAN, &hasOwner, DBUS_TYPE_INVALID)) {
96+ qCWarning (dsgApp) << " Failed to parse D-Bus reply:" << error->message ;
9197 return false ;
9298 }
9399
94- dbus_message_unref (reply);
95-
96100 if (!hasOwner) {
97- dbus_connection_unref (connection);
98101 return false ;
99102 }
100103
101104 // Check if service is activatable
102- msg = dbus_message_new_method_call (
105+ DBusMessage *msg2 = dbus_message_new_method_call (
103106 " org.freedesktop.DBus" ,
104107 " /org/freedesktop/DBus" ,
105108 " org.freedesktop.DBus" ,
106109 " ListActivatableNames"
107110 );
108111
109- if (!msg ) {
112+ if (!msg2 ) {
110113 qCWarning (dsgApp) << " Failed to create ListActivatableNames message" ;
111- dbus_connection_unref (connection);
112114 return false ;
113115 }
116+ auto msg2Guard = std::unique_ptr<DBusMessage, void (*)(DBusMessage*)>(msg2, dbusMessageDeleter);
114117
115- reply = dbus_connection_send_with_reply_and_block (connection, msg, 1000 , &error);
116- dbus_message_unref (msg);
118+ DBusMessage *reply2 = dbus_connection_send_with_reply_and_block (connection, msg2, 1000 , error.get ());
117119
118- if (dbus_error_is_set (&error)) {
119- qCWarning (dsgApp) << " ListActivatableNames call failed:" << error.message ;
120- dbus_error_free (&error);
121- dbus_connection_unref (connection);
120+ if (dbus_error_is_set (error.get ())) {
121+ qCWarning (dsgApp) << " ListActivatableNames call failed:" << error->message ;
122122 return false ;
123123 }
124124
125- if (!reply) {
126- dbus_connection_unref (connection);
125+ if (!reply2) {
127126 return false ;
128127 }
128+ auto reply2Guard = std::unique_ptr<DBusMessage, void (*)(DBusMessage*)>(reply2, dbusMessageDeleter);
129129
130130 DBusMessageIter iter, array_iter;
131- dbus_message_iter_init (reply , &iter);
131+ dbus_message_iter_init (reply2 , &iter);
132132
133133 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
134- dbus_message_unref (reply);
135- dbus_connection_unref (connection);
136134 return false ;
137135 }
138136
@@ -149,29 +147,25 @@ static bool checkDBusServiceActivatable(const QString &service)
149147 dbus_message_iter_next (&array_iter);
150148 }
151149
152- dbus_message_unref (reply);
153- dbus_connection_unref (connection);
154- dbus_error_free (&error);
155-
156150 return found;
157151}
158152
159153static QByteArray callDBusIdentifyMethod (const QString &service, const QString &path, const QString &interface, int pidfd)
160154{
161- DBusError error;
162- dbus_error_init (& error);
155+ auto error = std::unique_ptr<DBusError, void (*)(DBusError*)>( new DBusError, dbusErrorDeleter) ;
156+ dbus_error_init (error. get () );
163157
164- DBusConnection *connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
165- if (dbus_error_is_set (&error)) {
166- qCWarning (dsgApp) << " Failed to connect to session bus:" << error.message ;
167- dbus_error_free (&error);
158+ DBusConnection *connection = dbus_bus_get (DBUS_BUS_SESSION, error.get ());
159+ if (dbus_error_is_set (error.get ())) {
160+ qCWarning (dsgApp) << " Failed to connect to session bus:" << error->message ;
168161 return QByteArray ();
169162 }
170163
171164 if (!connection) {
172165 qCWarning (dsgApp) << " Failed to get session bus connection" ;
173166 return QByteArray ();
174167 }
168+ auto connGuard = std::unique_ptr<DBusConnection, void (*)(DBusConnection*)>(connection, dbusConnectionDeleter);
175169
176170 // Create method call
177171 DBusMessage *msg = dbus_message_new_method_call (
@@ -183,51 +177,40 @@ static QByteArray callDBusIdentifyMethod(const QString &service, const QString &
183177
184178 if (!msg) {
185179 qCWarning (dsgApp) << " Failed to create D-Bus message" ;
186- dbus_connection_unref (connection);
187180 return QByteArray ();
188181 }
182+ auto msgGuard = std::unique_ptr<DBusMessage, void (*)(DBusMessage*)>(msg, dbusMessageDeleter);
189183
190184 // Append Unix file descriptor
191185 if (!dbus_message_append_args (msg, DBUS_TYPE_UNIX_FD, &pidfd, DBUS_TYPE_INVALID)) {
192186 qCWarning (dsgApp) << " Failed to append Unix FD to D-Bus message" ;
193- dbus_message_unref (msg);
194- dbus_connection_unref (connection);
195187 return QByteArray ();
196188 }
197189
198190 // Send message and get reply
199- DBusMessage *reply = dbus_connection_send_with_reply_and_block (connection, msg, 5000 , & error);
200- dbus_message_unref (msg);
191+ DBusMessage *reply = dbus_connection_send_with_reply_and_block (connection, msg, 5000 , error. get () );
192+ msgGuard. reset (); // msg is consumed by the call
201193
202- if (dbus_error_is_set (&error)) {
203- qCWarning (dsgApp) << " Identify from AM failed:" << error.message ;
204- dbus_error_free (&error);
205- dbus_connection_unref (connection);
194+ if (dbus_error_is_set (error.get ())) {
195+ qCWarning (dsgApp) << " Identify from AM failed:" << error->message ;
206196 return QByteArray ();
207197 }
208198
209199 if (!reply) {
210200 qCWarning (dsgApp) << " No reply received from Identify method" ;
211- dbus_connection_unref (connection);
212201 return QByteArray ();
213202 }
203+ auto replyGuard = std::unique_ptr<DBusMessage, void (*)(DBusMessage*)>(reply, dbusMessageDeleter);
214204
215205 const char *result;
216- if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID)) {
217- qCWarning (dsgApp) << " Failed to parse Identify reply:" << error.message ;
218- dbus_error_free (&error);
219- dbus_message_unref (reply);
220- dbus_connection_unref (connection);
206+ if (!dbus_message_get_args (reply, error.get (), DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID)) {
207+ qCWarning (dsgApp) << " Failed to parse Identify reply:" << error->message ;
221208 return QByteArray ();
222209 }
223210
224211 QByteArray appId = QByteArray (result);
225212 qCInfo (dsgApp) << " AppId is fetched from AM, and value is " << appId;
226213
227- dbus_message_unref (reply);
228- dbus_connection_unref (connection);
229- dbus_error_free (&error);
230-
231214 return appId;
232215}
233216
@@ -286,6 +269,18 @@ QByteArray DSGApplication::id()
286269 return result;
287270}
288271
272+ /* *
273+ * Get application ID for a given process ID
274+ *
275+ * This function has been updated to use libdbus-1 instead of Qt D-Bus to fix
276+ * the bug(pms:BUG-278055) where calling this function before QCoreApplication
277+ * initialization would fail. This is particularly important when the service
278+ * is being started by D-Bus activation and DSGApplication::id() is called
279+ * during early startup.
280+ *
281+ * @param pid Process ID to get the application ID for
282+ * @return Application ID as QByteArray, or empty array on failure
283+ */
289284QByteArray DSGApplication::getId (qint64 pid)
290285{
291286 if (!isServiceActivatable (" org.desktopspec.ApplicationManager1" )) {
0 commit comments