1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
/* activation.c Activation of services
4
* Copyright (C) 2003 CodeFactory AB
5
* Copyright (C) 2003 Red Hat, Inc.
6
* Copyright (C) 2004 Imendio HB
8
* Licensed under the Academic Free License version 2.1
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27
#include "activation.h"
28
#include "activation-exit-codes.h"
29
#include "desktop-file.h"
34
#include <dbus/dbus-internals.h>
35
#include <dbus/dbus-hash.h>
36
#include <dbus/dbus-list.h>
37
#include <dbus/dbus-shell.h>
38
#include <dbus/dbus-spawn.h>
39
#include <dbus/dbus-timeout.h>
40
#include <dbus/dbus-sysdeps.h>
48
DBusHashTable *entries;
49
DBusHashTable *pending_activations;
52
int n_pending_activations; /**< This is in fact the number of BusPendingActivationEntry,
53
* i.e. number of pending activation requests, not pending
56
DBusHashTable *directories;
57
DBusHashTable *environment;
64
DBusHashTable *entries;
65
} BusServiceDirectory;
73
char *systemd_service;
75
BusServiceDirectory *s_dir;
77
unsigned int upstart_job : 1;
80
typedef struct BusPendingActivationEntry BusPendingActivationEntry;
82
struct BusPendingActivationEntry
84
DBusMessage *activation_message;
85
DBusConnection *connection;
87
dbus_bool_t auto_activation;
93
BusActivation *activation;
96
char *systemd_service;
99
DBusBabysitter *babysitter;
100
DBusTimeout *timeout;
101
unsigned int timeout_added : 1;
102
unsigned int upstart_job : 1;
103
} BusPendingActivation;
106
static BusServiceDirectory *
107
bus_service_directory_ref (BusServiceDirectory *dir)
109
_dbus_assert (dir->refcount);
118
bus_service_directory_unref (BusServiceDirectory *dir)
123
_dbus_assert (dir->refcount > 0);
126
if (dir->refcount > 0)
130
_dbus_hash_table_unref (dir->entries);
132
dbus_free (dir->dir_c);
137
bus_pending_activation_entry_free (BusPendingActivationEntry *entry)
139
if (entry->activation_message)
140
dbus_message_unref (entry->activation_message);
142
if (entry->connection)
143
dbus_connection_unref (entry->connection);
149
handle_timeout_callback (DBusTimeout *timeout,
152
BusPendingActivation *pending_activation = data;
154
while (!dbus_timeout_handle (pending_activation->timeout))
155
_dbus_wait_for_memory ();
158
static BusPendingActivation *
159
bus_pending_activation_ref (BusPendingActivation *pending_activation)
161
_dbus_assert (pending_activation->refcount > 0);
162
pending_activation->refcount += 1;
164
return pending_activation;
168
bus_pending_activation_unref (BusPendingActivation *pending_activation)
172
if (pending_activation == NULL) /* hash table requires this */
175
_dbus_assert (pending_activation->refcount > 0);
176
pending_activation->refcount -= 1;
178
if (pending_activation->refcount > 0)
181
if (pending_activation->timeout_added)
183
_dbus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context),
184
pending_activation->timeout,
185
handle_timeout_callback, pending_activation);
186
pending_activation->timeout_added = FALSE;
189
if (pending_activation->timeout)
190
_dbus_timeout_unref (pending_activation->timeout);
192
if (pending_activation->babysitter)
194
if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
196
pending_activation->babysitter,
198
_dbus_assert_not_reached ("setting watch functions to NULL failed");
200
_dbus_babysitter_unref (pending_activation->babysitter);
203
dbus_free (pending_activation->service_name);
204
dbus_free (pending_activation->exec);
205
dbus_free (pending_activation->systemd_service);
207
link = _dbus_list_get_first_link (&pending_activation->entries);
211
BusPendingActivationEntry *entry = link->data;
213
bus_pending_activation_entry_free (entry);
215
link = _dbus_list_get_next_link (&pending_activation->entries, link);
217
_dbus_list_clear (&pending_activation->entries);
219
pending_activation->activation->n_pending_activations -=
220
pending_activation->n_entries;
222
_dbus_assert (pending_activation->activation->n_pending_activations >= 0);
224
dbus_free (pending_activation);
227
static BusActivationEntry *
228
bus_activation_entry_ref (BusActivationEntry *entry)
230
_dbus_assert (entry->refcount > 0);
237
bus_activation_entry_unref (BusActivationEntry *entry)
239
if (entry == NULL) /* hash table requires this */
242
_dbus_assert (entry->refcount > 0);
245
if (entry->refcount > 0)
248
dbus_free (entry->name);
249
dbus_free (entry->exec);
250
dbus_free (entry->user);
251
dbus_free (entry->filename);
252
dbus_free (entry->systemd_service);
258
update_desktop_file_entry (BusActivation *activation,
259
BusServiceDirectory *s_dir,
260
DBusString *filename,
261
BusDesktopFile *desktop_file,
264
char *name, *exec, *user, *exec_tmp, *systemd_service;
265
const char *upstart_job_raw;
267
BusActivationEntry *entry;
269
DBusString file_path;
272
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
279
systemd_service = NULL;
280
upstart_job_raw = NULL;
283
dbus_error_init (&tmp_error);
285
if (!_dbus_string_init (&file_path))
291
if (!_dbus_string_append (&file_path, s_dir->dir_c) ||
292
!_dbus_concat_dir_and_file (&file_path, filename))
298
if (!_dbus_stat (&file_path, &stat_buf, NULL))
300
dbus_set_error (error, DBUS_ERROR_FAILED,
301
"Can't stat the service file\n");
305
if (!bus_desktop_file_get_string (desktop_file,
306
DBUS_SERVICE_SECTION,
312
if (!bus_desktop_file_get_string (desktop_file,
313
DBUS_SERVICE_SECTION,
319
/* user is not _required_ unless we are using system activation */
320
if (!bus_desktop_file_get_string (desktop_file,
321
DBUS_SERVICE_SECTION,
325
_DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
326
/* if we got OOM, then exit */
327
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
329
dbus_move_error (&tmp_error, error);
334
/* if we have error because we didn't find anything then continue */
335
dbus_error_free (&tmp_error);
340
_DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
342
/* systemd service is never required */
343
if (!bus_desktop_file_get_string (desktop_file,
344
DBUS_SERVICE_SECTION,
345
DBUS_SERVICE_SYSTEMD_SERVICE,
346
&systemd_service, &tmp_error))
348
_DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
349
/* if we got OOM, then exit */
350
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
352
dbus_move_error (&tmp_error, error);
357
/* if we have error because we didn't find anything then continue */
358
dbus_error_free (&tmp_error);
359
dbus_free (systemd_service);
360
systemd_service = NULL;
364
/* upstart job is never required */
365
if (bus_desktop_file_get_raw (desktop_file,
366
DBUS_SERVICE_SECTION,
367
DBUS_SERVICE_UPSTART_JOB,
370
if (strchr ("YyTt", upstart_job_raw[0]))
374
_DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
376
entry = _dbus_hash_table_lookup_string (s_dir->entries,
377
_dbus_string_get_const_data (filename));
379
exec = strdup (_dbus_replace_install_prefix (exec_tmp));
381
if (entry == NULL) /* New file */
383
/* FIXME we need a better-defined algorithm for which service file to
384
* pick than "whichever one is first in the directory listing"
386
if (_dbus_hash_table_lookup_string (activation->entries, name))
388
dbus_set_error (error, DBUS_ERROR_FAILED,
389
"Service %s already exists in activation entry list\n", name);
393
entry = dbus_new0 (BusActivationEntry, 1);
403
entry->systemd_service = systemd_service;
404
entry->upstart_job = upstart_job;
407
entry->s_dir = s_dir;
408
entry->filename = _dbus_strdup (_dbus_string_get_const_data (filename));
409
if (!entry->filename)
415
if (!_dbus_hash_table_insert_string (activation->entries, entry->name, bus_activation_entry_ref (entry)))
421
if (!_dbus_hash_table_insert_string (s_dir->entries, entry->filename, bus_activation_entry_ref (entry)))
423
/* Revert the insertion in the entries table */
424
_dbus_hash_table_remove_string (activation->entries, entry->name);
429
_dbus_verbose ("Added \"%s\" to list of services\n", entry->name);
431
else /* Just update the entry */
433
bus_activation_entry_ref (entry);
434
_dbus_hash_table_remove_string (activation->entries, entry->name);
436
if (_dbus_hash_table_lookup_string (activation->entries, name))
438
_dbus_verbose ("The new service name \"%s\" of service file \"%s\" already in cache, ignoring\n",
439
name, _dbus_string_get_const_data (&file_path));
443
dbus_free (entry->name);
444
dbus_free (entry->exec);
445
dbus_free (entry->user);
446
dbus_free (entry->systemd_service);
447
entry->systemd_service = systemd_service;
448
entry->upstart_job = upstart_job;
452
if (!_dbus_hash_table_insert_string (activation->entries,
453
entry->name, bus_activation_entry_ref(entry)))
456
/* Also remove path to entries hash since we want this in sync with
457
* the entries hash table */
458
_dbus_hash_table_remove_string (entry->s_dir->entries,
460
bus_activation_entry_unref (entry);
465
entry->mtime = stat_buf.mtime;
467
_dbus_string_free (&file_path);
468
bus_activation_entry_unref (entry);
474
dbus_free (exec_tmp);
476
dbus_free (systemd_service);
477
_dbus_string_free (&file_path);
480
bus_activation_entry_unref (entry);
486
check_service_file (BusActivation *activation,
487
BusActivationEntry *entry,
488
BusActivationEntry **updated_entry,
493
BusActivationEntry *tmp_entry;
494
DBusString file_path;
500
_dbus_string_init_const (&filename, entry->filename);
502
if (!_dbus_string_init (&file_path))
508
if (!_dbus_string_append (&file_path, entry->s_dir->dir_c) ||
509
!_dbus_concat_dir_and_file (&file_path, &filename))
516
if (!_dbus_stat (&file_path, &stat_buf, NULL))
518
_dbus_verbose ("****** Can't stat file \"%s\", removing from cache\n",
519
_dbus_string_get_const_data (&file_path));
521
_dbus_hash_table_remove_string (activation->entries, entry->name);
522
_dbus_hash_table_remove_string (entry->s_dir->entries, entry->filename);
530
if (stat_buf.mtime > entry->mtime)
532
BusDesktopFile *desktop_file;
535
dbus_error_init (&tmp_error);
537
desktop_file = bus_desktop_file_load (&file_path, &tmp_error);
538
if (desktop_file == NULL)
540
_dbus_verbose ("Could not load %s: %s\n",
541
_dbus_string_get_const_data (&file_path),
543
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
545
dbus_move_error (&tmp_error, error);
549
dbus_error_free (&tmp_error);
554
/* @todo We can return OOM or a DBUS_ERROR_FAILED error
555
* Handle these both better
557
if (!update_desktop_file_entry (activation, entry->s_dir, &filename, desktop_file, &tmp_error))
559
bus_desktop_file_free (desktop_file);
560
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
562
dbus_move_error (&tmp_error, error);
566
dbus_error_free (&tmp_error);
571
bus_desktop_file_free (desktop_file);
577
_dbus_string_free (&file_path);
579
if (updated_entry != NULL)
580
*updated_entry = tmp_entry;
585
/* warning: this doesn't fully "undo" itself on failure, i.e. doesn't strip
586
* hash entries it already added.
589
update_directory (BusActivation *activation,
590
BusServiceDirectory *s_dir,
594
DBusString dir, filename;
595
BusDesktopFile *desktop_file;
598
BusActivationEntry *entry;
599
DBusString full_path;
601
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
606
_dbus_string_init_const (&dir, s_dir->dir_c);
608
if (!_dbus_string_init (&filename))
614
if (!_dbus_string_init (&full_path))
617
_dbus_string_free (&filename);
623
/* from this point it's safe to "goto out" */
625
iter = _dbus_directory_open (&dir, error);
628
_dbus_verbose ("Failed to open directory %s: %s\n",
630
error ? error->message : "unknown");
634
/* Now read the files */
635
dbus_error_init (&tmp_error);
636
while (_dbus_directory_get_next_file (iter, &filename, &tmp_error))
638
_dbus_assert (!dbus_error_is_set (&tmp_error));
640
_dbus_string_set_length (&full_path, 0);
642
if (!_dbus_string_ends_with_c_str (&filename, ".service"))
644
_dbus_verbose ("Skipping non-.service file %s\n",
645
_dbus_string_get_const_data (&filename));
649
entry = _dbus_hash_table_lookup_string (s_dir->entries, _dbus_string_get_const_data (&filename));
650
if (entry) /* Already has this service file in the cache */
652
if (!check_service_file (activation, entry, NULL, error))
658
if (!_dbus_string_append (&full_path, s_dir->dir_c) ||
659
!_dbus_concat_dir_and_file (&full_path, &filename))
666
desktop_file = bus_desktop_file_load (&full_path, &tmp_error);
667
if (desktop_file == NULL)
669
_dbus_verbose ("Could not load %s: %s\n",
670
_dbus_string_get_const_data (&full_path),
673
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
675
dbus_move_error (&tmp_error, error);
679
dbus_error_free (&tmp_error);
683
/* @todo We can return OOM or a DBUS_ERROR_FAILED error
684
* Handle these both better
686
if (!update_desktop_file_entry (activation, s_dir, &filename, desktop_file, &tmp_error))
688
bus_desktop_file_free (desktop_file);
691
_dbus_verbose ("Could not add %s to activation entry list: %s\n",
692
_dbus_string_get_const_data (&full_path), tmp_error.message);
694
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
696
dbus_move_error (&tmp_error, error);
700
dbus_error_free (&tmp_error);
705
bus_desktop_file_free (desktop_file);
711
if (dbus_error_is_set (&tmp_error))
713
dbus_move_error (&tmp_error, error);
721
_DBUS_ASSERT_ERROR_IS_SET (error);
723
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
726
_dbus_directory_close (iter);
727
_dbus_string_free (&filename);
728
_dbus_string_free (&full_path);
734
populate_environment (BusActivation *activation)
740
dbus_bool_t retval = FALSE;
742
environment = _dbus_get_environment ();
744
if (environment == NULL)
747
if (!_dbus_string_init (&key))
749
dbus_free_string_array (environment);
753
if (!_dbus_string_init (&value))
755
_dbus_string_free (&key);
756
dbus_free_string_array (environment);
760
for (i = 0; environment[i] != NULL; i++)
762
if (!_dbus_string_append (&key, environment[i]))
765
if (_dbus_string_split_on_byte (&key, '=', &value))
767
char *hash_key, *hash_value;
769
if (!_dbus_string_steal_data (&key, &hash_key))
772
if (!_dbus_string_steal_data (&value, &hash_value))
775
if (!_dbus_hash_table_insert_string (activation->environment,
776
hash_key, hash_value))
779
_dbus_string_set_length (&key, 0);
780
_dbus_string_set_length (&value, 0);
783
if (environment[i] != NULL)
789
_dbus_string_free (&key);
790
_dbus_string_free (&value);
791
dbus_free_string_array (environment);
797
bus_activation_reload (BusActivation *activation,
798
const DBusString *address,
799
DBusList **directories,
805
if (activation->server_address != NULL)
806
dbus_free (activation->server_address);
807
if (!_dbus_string_copy_data (address, &activation->server_address))
813
if (activation->entries != NULL)
814
_dbus_hash_table_unref (activation->entries);
815
activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
816
(DBusFreeFunction)bus_activation_entry_unref);
817
if (activation->entries == NULL)
823
if (activation->directories != NULL)
824
_dbus_hash_table_unref (activation->directories);
825
activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
826
(DBusFreeFunction)bus_service_directory_unref);
828
if (activation->directories == NULL)
834
link = _dbus_list_get_first_link (directories);
837
BusServiceDirectory *s_dir;
839
dir = _dbus_strdup ((const char *) link->data);
846
s_dir = dbus_new0 (BusServiceDirectory, 1);
857
s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
858
(DBusFreeFunction)bus_activation_entry_unref);
862
bus_service_directory_unref (s_dir);
867
if (!_dbus_hash_table_insert_string (activation->directories, s_dir->dir_c, s_dir))
869
bus_service_directory_unref (s_dir);
874
/* only fail on OOM, it is ok if we can't read the directory */
875
if (!update_directory (activation, s_dir, error))
877
if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
880
dbus_error_free (error);
883
link = _dbus_list_get_next_link (directories, link);
892
bus_activation_new (BusContext *context,
893
const DBusString *address,
894
DBusList **directories,
897
BusActivation *activation;
901
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
903
activation = dbus_new0 (BusActivation, 1);
904
if (activation == NULL)
910
activation->refcount = 1;
911
activation->context = context;
912
activation->n_pending_activations = 0;
914
if (!bus_activation_reload (activation, address, directories, error))
917
/* Initialize this hash table once, we don't want to lose pending
918
* activations on reload. */
919
activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
920
(DBusFreeFunction)bus_pending_activation_unref);
922
if (activation->pending_activations == NULL)
928
activation->environment = _dbus_hash_table_new (DBUS_HASH_STRING,
929
(DBusFreeFunction) dbus_free,
930
(DBusFreeFunction) dbus_free);
932
if (activation->environment == NULL)
938
if (!populate_environment (activation))
947
bus_activation_unref (activation);
952
bus_activation_ref (BusActivation *activation)
954
_dbus_assert (activation->refcount > 0);
956
activation->refcount += 1;
962
bus_activation_unref (BusActivation *activation)
964
_dbus_assert (activation->refcount > 0);
966
activation->refcount -= 1;
968
if (activation->refcount > 0)
971
dbus_free (activation->server_address);
972
if (activation->entries)
973
_dbus_hash_table_unref (activation->entries);
974
if (activation->pending_activations)
975
_dbus_hash_table_unref (activation->pending_activations);
976
if (activation->directories)
977
_dbus_hash_table_unref (activation->directories);
978
if (activation->environment)
979
_dbus_hash_table_unref (activation->environment);
981
dbus_free (activation);
985
add_bus_environment (BusActivation *activation,
990
if (!bus_activation_set_environment_variable (activation,
991
"DBUS_STARTER_ADDRESS",
992
activation->server_address,
996
type = bus_context_get_type (activation->context);
999
if (!bus_activation_set_environment_variable (activation,
1000
"DBUS_STARTER_BUS_TYPE", type,
1004
if (strcmp (type, "session") == 0)
1006
if (!bus_activation_set_environment_variable (activation,
1007
"DBUS_SESSION_BUS_ADDRESS",
1008
activation->server_address,
1012
else if (strcmp (type, "system") == 0)
1014
if (!bus_activation_set_environment_variable (activation,
1015
"DBUS_SYSTEM_BUS_ADDRESS",
1016
activation->server_address,
1027
BusPendingActivation *pending_activation;
1028
DBusPreallocatedHash *hash_entry;
1029
} RestorePendingData;
1032
restore_pending (void *data)
1034
RestorePendingData *d = data;
1036
_dbus_assert (d->pending_activation != NULL);
1037
_dbus_assert (d->hash_entry != NULL);
1039
_dbus_verbose ("Restoring pending activation for service %s, has timeout = %d\n",
1040
d->pending_activation->service_name,
1041
d->pending_activation->timeout_added);
1043
_dbus_hash_table_insert_string_preallocated (d->pending_activation->activation->pending_activations,
1045
d->pending_activation->service_name, d->pending_activation);
1047
bus_pending_activation_ref (d->pending_activation);
1049
d->hash_entry = NULL;
1053
free_pending_restore_data (void *data)
1055
RestorePendingData *d = data;
1058
_dbus_hash_table_free_preallocated_entry (d->pending_activation->activation->pending_activations,
1061
bus_pending_activation_unref (d->pending_activation);
1067
add_restore_pending_to_transaction (BusTransaction *transaction,
1068
BusPendingActivation *pending_activation)
1070
RestorePendingData *d;
1072
d = dbus_new (RestorePendingData, 1);
1076
d->pending_activation = pending_activation;
1077
d->hash_entry = _dbus_hash_table_preallocate_entry (d->pending_activation->activation->pending_activations);
1079
bus_pending_activation_ref (d->pending_activation);
1081
if (d->hash_entry == NULL ||
1082
!bus_transaction_add_cancel_hook (transaction, restore_pending, d,
1083
free_pending_restore_data))
1085
free_pending_restore_data (d);
1089
_dbus_verbose ("Saved pending activation to be restored if the transaction fails\n");
1095
bus_activation_service_created (BusActivation *activation,
1096
const char *service_name,
1097
BusTransaction *transaction,
1100
BusPendingActivation *pending_activation;
1101
DBusMessage *message;
1104
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
1106
/* Check if it's a pending activation */
1107
pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
1109
if (!pending_activation)
1112
link = _dbus_list_get_first_link (&pending_activation->entries);
1113
while (link != NULL)
1115
BusPendingActivationEntry *entry = link->data;
1116
DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
1118
if (dbus_connection_get_is_connected (entry->connection))
1120
/* Only send activation replies to regular activation requests. */
1121
if (!entry->auto_activation)
1123
dbus_uint32_t result;
1125
message = dbus_message_new_method_return (entry->activation_message);
1128
BUS_SET_OOM (error);
1132
result = DBUS_START_REPLY_SUCCESS;
1134
if (!dbus_message_append_args (message,
1135
DBUS_TYPE_UINT32, &result,
1138
dbus_message_unref (message);
1139
BUS_SET_OOM (error);
1143
if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
1145
dbus_message_unref (message);
1146
BUS_SET_OOM (error);
1150
dbus_message_unref (message);
1164
bus_activation_send_pending_auto_activation_messages (BusActivation *activation,
1165
BusService *service,
1166
BusTransaction *transaction,
1169
BusPendingActivation *pending_activation;
1172
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
1174
/* Check if it's a pending activation */
1175
pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations,
1176
bus_service_get_name (service));
1178
if (!pending_activation)
1181
link = _dbus_list_get_first_link (&pending_activation->entries);
1182
while (link != NULL)
1184
BusPendingActivationEntry *entry = link->data;
1185
DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
1187
if (entry->auto_activation && dbus_connection_get_is_connected (entry->connection))
1189
DBusConnection *addressed_recipient;
1191
addressed_recipient = bus_service_get_primary_owners_connection (service);
1193
/* Resume dispatching where we left off in bus_dispatch() */
1194
if (!bus_dispatch_matches (transaction,
1196
addressed_recipient,
1197
entry->activation_message, error))
1204
if (!add_restore_pending_to_transaction (transaction, pending_activation))
1206
_dbus_verbose ("Could not add cancel hook to transaction to revert removing pending activation\n");
1207
BUS_SET_OOM (error);
1211
_dbus_hash_table_remove_string (activation->pending_activations, bus_service_get_name (service));
1220
* FIXME @todo the error messages here would ideally be preallocated
1221
* so we don't need to allocate memory to send them.
1222
* Using the usual tactic, prealloc an OOM message, then
1223
* if we can't alloc the real error send the OOM error instead.
1226
try_send_activation_failure (BusPendingActivation *pending_activation,
1227
const DBusError *how)
1229
BusActivation *activation;
1231
BusTransaction *transaction;
1233
activation = pending_activation->activation;
1235
transaction = bus_transaction_new (activation->context);
1236
if (transaction == NULL)
1239
link = _dbus_list_get_first_link (&pending_activation->entries);
1240
while (link != NULL)
1242
BusPendingActivationEntry *entry = link->data;
1243
DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
1245
if (dbus_connection_get_is_connected (entry->connection))
1247
if (!bus_transaction_send_error_reply (transaction,
1250
entry->activation_message))
1257
bus_transaction_execute_and_free (transaction);
1263
bus_transaction_cancel_and_free (transaction);
1268
* Free the pending activation and send an error message to all the
1269
* connections that were waiting for it.
1272
pending_activation_failed (BusPendingActivation *pending_activation,
1273
const DBusError *how)
1275
/* FIXME use preallocated OOM messages instead of bus_wait_for_memory() */
1276
while (!try_send_activation_failure (pending_activation, how))
1277
_dbus_wait_for_memory ();
1279
/* Destroy this pending activation */
1280
_dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
1281
pending_activation->service_name);
1285
* Depending on the exit code of the helper, set the error accordingly
1288
handle_servicehelper_exit_error (int exit_code,
1293
case BUS_SPAWN_EXIT_CODE_NO_MEMORY:
1294
dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1295
"Launcher could not run (out of memory)");
1297
case BUS_SPAWN_EXIT_CODE_SETUP_FAILED:
1298
dbus_set_error (error, DBUS_ERROR_SPAWN_SETUP_FAILED,
1299
"Failed to setup environment correctly");
1301
case BUS_SPAWN_EXIT_CODE_NAME_INVALID:
1302
dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_INVALID,
1303
"Bus name is not valid or missing");
1305
case BUS_SPAWN_EXIT_CODE_SERVICE_NOT_FOUND:
1306
dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND,
1307
"Bus name not found in system service directory");
1309
case BUS_SPAWN_EXIT_CODE_PERMISSIONS_INVALID:
1310
dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID,
1311
"The permission of the setuid helper is not correct");
1313
case BUS_SPAWN_EXIT_CODE_FILE_INVALID:
1314
dbus_set_error (error, DBUS_ERROR_SPAWN_PERMISSIONS_INVALID,
1315
"The service file is incorrect or does not have all required attributes");
1317
case BUS_SPAWN_EXIT_CODE_EXEC_FAILED:
1318
dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
1319
"Cannot launch daemon, file not found or permissions invalid");
1321
case BUS_SPAWN_EXIT_CODE_INVALID_ARGS:
1322
dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
1323
"Invalid arguments to command line");
1325
case BUS_SPAWN_EXIT_CODE_CHILD_SIGNALED:
1326
dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED,
1327
"Launched child was signaled, it probably crashed");
1330
dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_EXITED,
1331
"Launch helper exited with unknown return code %i", exit_code);
1337
babysitter_watch_callback (DBusWatch *watch,
1338
unsigned int condition,
1341
BusPendingActivation *pending_activation = data;
1343
DBusBabysitter *babysitter;
1344
dbus_bool_t uses_servicehelper;
1346
babysitter = pending_activation->babysitter;
1348
_dbus_babysitter_ref (babysitter);
1350
retval = dbus_watch_handle (watch, condition);
1352
/* There are two major cases here; are we the system bus or the session? Here this
1353
* is distinguished by whether or not we use a setuid helper launcher. With the launch helper,
1354
* some process exit codes are meaningful, processed by handle_servicehelper_exit_error.
1356
* In both cases though, just ignore when a process exits with status 0; it's possible for
1357
* a program to (misguidedly) "daemonize", and that appears to us as an exit. This closes a race
1358
* condition between this code and the child process claiming the bus name.
1360
uses_servicehelper = bus_context_get_servicehelper (pending_activation->activation->context) != NULL;
1362
/* FIXME this is broken in the same way that
1363
* connection watches used to be; there should be
1364
* a separate callback for status change, instead
1365
* of doing "if we handled a watch status might
1368
* Fixing this lets us move dbus_watch_handle
1369
* calls into dbus-mainloop.c
1371
if (_dbus_babysitter_get_child_exited (babysitter))
1375
dbus_bool_t activation_failed;
1378
dbus_error_init (&error);
1380
_dbus_babysitter_set_child_exit_error (babysitter, &error);
1382
/* Explicitly check for SPAWN_CHILD_EXITED to avoid overwriting an
1384
if (dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)
1385
&& _dbus_babysitter_get_child_exit_status (babysitter, &exit_code))
1387
activation_failed = exit_code != 0;
1389
dbus_error_free(&error);
1391
if (activation_failed)
1393
if (uses_servicehelper)
1394
handle_servicehelper_exit_error (exit_code, &error);
1396
_dbus_babysitter_set_child_exit_error (babysitter, &error);
1401
activation_failed = TRUE;
1404
if (activation_failed)
1406
/* Destroy all pending activations with the same exec */
1407
_dbus_hash_iter_init (pending_activation->activation->pending_activations,
1409
while (_dbus_hash_iter_next (&iter))
1411
BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
1413
if (p != pending_activation && strcmp (p->exec, pending_activation->exec) == 0)
1414
pending_activation_failed (p, &error);
1417
/* Destroys the pending activation */
1418
pending_activation_failed (pending_activation, &error);
1420
dbus_error_free (&error);
1424
_dbus_babysitter_unref (babysitter);
1430
add_babysitter_watch (DBusWatch *watch,
1433
BusPendingActivation *pending_activation = data;
1435
return _dbus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context),
1436
watch, babysitter_watch_callback, pending_activation,
1441
remove_babysitter_watch (DBusWatch *watch,
1444
BusPendingActivation *pending_activation = data;
1446
_dbus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context),
1447
watch, babysitter_watch_callback, pending_activation);
1451
pending_activation_timed_out (void *data)
1453
BusPendingActivation *pending_activation = data;
1456
/* Kill the spawned process, since it sucks
1457
* (not sure this is what we want to do, but
1458
* may as well try it for now)
1460
if (pending_activation->babysitter)
1461
_dbus_babysitter_kill_child (pending_activation->babysitter);
1463
dbus_error_init (&error);
1465
dbus_set_error (&error, DBUS_ERROR_TIMED_OUT,
1466
"Activation of %s timed out",
1467
pending_activation->service_name);
1469
pending_activation_failed (pending_activation, &error);
1471
dbus_error_free (&error);
1477
cancel_pending (void *data)
1479
BusPendingActivation *pending_activation = data;
1481
_dbus_verbose ("Canceling pending activation of %s\n",
1482
pending_activation->service_name);
1484
if (pending_activation->babysitter)
1485
_dbus_babysitter_kill_child (pending_activation->babysitter);
1487
_dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
1488
pending_activation->service_name);
1492
free_pending_cancel_data (void *data)
1494
BusPendingActivation *pending_activation = data;
1496
bus_pending_activation_unref (pending_activation);
1500
add_cancel_pending_to_transaction (BusTransaction *transaction,
1501
BusPendingActivation *pending_activation)
1503
if (!bus_transaction_add_cancel_hook (transaction, cancel_pending,
1505
free_pending_cancel_data))
1508
bus_pending_activation_ref (pending_activation);
1510
_dbus_verbose ("Saved pending activation to be canceled if the transaction fails\n");
1516
update_service_cache (BusActivation *activation, DBusError *error)
1520
_dbus_hash_iter_init (activation->directories, &iter);
1521
while (_dbus_hash_iter_next (&iter))
1523
DBusError tmp_error;
1524
BusServiceDirectory *s_dir;
1526
s_dir = _dbus_hash_iter_get_value (&iter);
1528
dbus_error_init (&tmp_error);
1529
if (!update_directory (activation, s_dir, &tmp_error))
1531
if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
1533
dbus_move_error (&tmp_error, error);
1537
dbus_error_free (&tmp_error);
1545
static BusActivationEntry *
1546
activation_find_entry (BusActivation *activation,
1547
const char *service_name,
1550
BusActivationEntry *entry;
1552
entry = _dbus_hash_table_lookup_string (activation->entries, service_name);
1555
if (!update_service_cache (activation, error))
1558
entry = _dbus_hash_table_lookup_string (activation->entries,
1563
BusActivationEntry *updated_entry;
1565
if (!check_service_file (activation, entry, &updated_entry, error))
1568
entry = updated_entry;
1573
dbus_set_error (error, DBUS_ERROR_SERVICE_UNKNOWN,
1574
"The name %s was not provided by any .service files",
1583
bus_activation_get_environment (BusActivation *activation)
1590
length = _dbus_hash_table_get_n_entries (activation->environment);
1592
environment = dbus_new0 (char *, length + 1);
1594
if (environment == NULL)
1598
_dbus_hash_iter_init (activation->environment, &iter);
1600
if (!_dbus_string_init (&entry))
1602
dbus_free_string_array (environment);
1606
while (_dbus_hash_iter_next (&iter))
1608
const char *key, *value;
1610
key = (const char *) _dbus_hash_iter_get_string_key (&iter);
1611
value = (const char *) _dbus_hash_iter_get_value (&iter);
1613
if (!_dbus_string_append_printf (&entry, "%s=%s", key, value))
1616
if (!_dbus_string_steal_data (&entry, environment + i))
1621
_dbus_string_free (&entry);
1625
dbus_free_string_array (environment);
1633
bus_activation_set_environment_variable (BusActivation *activation,
1645
hash_key = _dbus_strdup (key);
1647
if (hash_key == NULL)
1650
hash_value = _dbus_strdup (value);
1652
if (hash_value == NULL)
1655
if (!_dbus_hash_table_insert_string (activation->environment,
1656
hash_key, hash_value))
1661
if (retval == FALSE)
1663
dbus_free (hash_key);
1664
dbus_free (hash_value);
1665
BUS_SET_OOM (error);
1672
bus_activation_activate_service (BusActivation *activation,
1673
DBusConnection *connection,
1674
BusTransaction *transaction,
1675
dbus_bool_t auto_activation,
1676
DBusMessage *activation_message,
1677
const char *service_name,
1680
BusActivationEntry *entry;
1681
BusPendingActivation *pending_activation;
1682
BusPendingActivationEntry *pending_activation_entry;
1683
DBusMessage *message;
1684
DBusString service_str;
1685
const char *servicehelper;
1691
dbus_bool_t activated;
1696
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
1698
if (activation->n_pending_activations >=
1699
bus_context_get_max_pending_activations (activation->context))
1701
dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1702
"The maximum number of pending activations has been reached, activation of %s failed",
1707
entry = activation_find_entry (activation, service_name, error);
1711
/* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
1712
* call us if the service is already active.
1714
if (!auto_activation)
1716
/* Check if the service is active */
1717
_dbus_string_init_const (&service_str, service_name);
1718
if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
1720
dbus_uint32_t result;
1722
_dbus_verbose ("Service \"%s\" is already active\n", service_name);
1724
message = dbus_message_new_method_return (activation_message);
1728
_dbus_verbose ("No memory to create reply to activate message\n");
1729
BUS_SET_OOM (error);
1733
result = DBUS_START_REPLY_ALREADY_RUNNING;
1735
if (!dbus_message_append_args (message,
1736
DBUS_TYPE_UINT32, &result,
1739
_dbus_verbose ("No memory to set args of reply to activate message\n");
1740
BUS_SET_OOM (error);
1741
dbus_message_unref (message);
1745
retval = bus_transaction_send_from_driver (transaction, connection, message);
1746
dbus_message_unref (message);
1749
_dbus_verbose ("Failed to send reply\n");
1750
BUS_SET_OOM (error);
1757
pending_activation_entry = dbus_new0 (BusPendingActivationEntry, 1);
1758
if (!pending_activation_entry)
1760
_dbus_verbose ("Failed to create pending activation entry\n");
1761
BUS_SET_OOM (error);
1765
pending_activation_entry->auto_activation = auto_activation;
1767
pending_activation_entry->activation_message = activation_message;
1768
dbus_message_ref (activation_message);
1769
pending_activation_entry->connection = connection;
1770
dbus_connection_ref (connection);
1772
/* Check if the service is being activated */
1773
pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
1774
if (pending_activation)
1776
if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
1778
_dbus_verbose ("Failed to append a new entry to pending activation\n");
1780
BUS_SET_OOM (error);
1781
bus_pending_activation_entry_free (pending_activation_entry);
1785
pending_activation->n_entries += 1;
1786
pending_activation->activation->n_pending_activations += 1;
1790
pending_activation = dbus_new0 (BusPendingActivation, 1);
1791
if (!pending_activation)
1793
_dbus_verbose ("Failed to create pending activation\n");
1795
BUS_SET_OOM (error);
1796
bus_pending_activation_entry_free (pending_activation_entry);
1800
pending_activation->activation = activation;
1801
pending_activation->refcount = 1;
1803
pending_activation->service_name = _dbus_strdup (service_name);
1804
if (!pending_activation->service_name)
1806
_dbus_verbose ("Failed to copy service name for pending activation\n");
1808
BUS_SET_OOM (error);
1809
bus_pending_activation_unref (pending_activation);
1810
bus_pending_activation_entry_free (pending_activation_entry);
1814
pending_activation->exec = _dbus_strdup (entry->exec);
1815
if (!pending_activation->exec)
1817
_dbus_verbose ("Failed to copy service exec for pending activation\n");
1818
BUS_SET_OOM (error);
1819
bus_pending_activation_unref (pending_activation);
1820
bus_pending_activation_entry_free (pending_activation_entry);
1824
if (entry->systemd_service)
1826
pending_activation->systemd_service = _dbus_strdup (entry->systemd_service);
1827
if (!pending_activation->systemd_service)
1829
_dbus_verbose ("Failed to copy systemd service for pending activation\n");
1830
BUS_SET_OOM (error);
1831
bus_pending_activation_unref (pending_activation);
1832
bus_pending_activation_entry_free (pending_activation_entry);
1837
pending_activation->upstart_job = entry->upstart_job;
1839
pending_activation->timeout =
1840
_dbus_timeout_new (bus_context_get_activation_timeout (activation->context),
1841
pending_activation_timed_out,
1844
if (!pending_activation->timeout)
1846
_dbus_verbose ("Failed to create timeout for pending activation\n");
1848
BUS_SET_OOM (error);
1849
bus_pending_activation_unref (pending_activation);
1850
bus_pending_activation_entry_free (pending_activation_entry);
1854
if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
1855
pending_activation->timeout,
1856
handle_timeout_callback,
1860
_dbus_verbose ("Failed to add timeout for pending activation\n");
1862
BUS_SET_OOM (error);
1863
bus_pending_activation_unref (pending_activation);
1864
bus_pending_activation_entry_free (pending_activation_entry);
1868
pending_activation->timeout_added = TRUE;
1870
if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
1872
_dbus_verbose ("Failed to add entry to just-created pending activation\n");
1874
BUS_SET_OOM (error);
1875
bus_pending_activation_unref (pending_activation);
1876
bus_pending_activation_entry_free (pending_activation_entry);
1880
pending_activation->n_entries += 1;
1881
pending_activation->activation->n_pending_activations += 1;
1884
_dbus_hash_iter_init (activation->pending_activations, &iter);
1885
while (_dbus_hash_iter_next (&iter))
1887
BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
1889
if (strcmp (p->exec, entry->exec) == 0)
1896
if (!_dbus_hash_table_insert_string (activation->pending_activations,
1897
pending_activation->service_name,
1898
pending_activation))
1900
_dbus_verbose ("Failed to put pending activation in hash table\n");
1902
BUS_SET_OOM (error);
1903
bus_pending_activation_unref (pending_activation);
1908
if (!add_cancel_pending_to_transaction (transaction, pending_activation))
1910
_dbus_verbose ("Failed to add pending activation cancel hook to transaction\n");
1911
BUS_SET_OOM (error);
1912
_dbus_hash_table_remove_string (activation->pending_activations,
1913
pending_activation->service_name);
1921
if (bus_context_get_activation_type (activation->context) == ACTIVATION_SYSTEMD)
1923
if (strcmp (service_name, "org.freedesktop.systemd1") == 0)
1924
/* systemd itself is missing apparently. That can happen
1925
only during early startup. Let's just wait until systemd
1926
connects to us and do nothing. */
1929
if (entry->systemd_service)
1931
BusTransaction *activation_transaction;
1932
DBusString service_string;
1933
BusService *service;
1934
BusRegistry *registry;
1936
/* OK, we have a systemd service configured for this entry,
1937
hence let's enqueue an activation request message. This
1938
is implemented as a directed signal, not a method call,
1939
for three reasons: 1) we don't expect a response on
1940
success, where we just expect a name appearing on the
1941
bus; 2) at this time the systemd service might not yet
1942
have connected, so we wouldn't know the message serial at
1943
this point to set up a pending call; 3) it is ugly if the
1944
bus suddenly becomes the caller of a remote method. */
1946
message = dbus_message_new_signal (DBUS_PATH_DBUS,
1947
"org.freedesktop.systemd1.Activator",
1948
"ActivationRequest");
1951
_dbus_verbose ("No memory to create activation message\n");
1952
BUS_SET_OOM (error);
1956
if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) ||
1957
!dbus_message_set_destination (message, "org.freedesktop.systemd1") ||
1958
!dbus_message_append_args (message,
1959
DBUS_TYPE_STRING, &entry->systemd_service,
1962
_dbus_verbose ("No memory to set args of activation message\n");
1963
dbus_message_unref (message);
1964
BUS_SET_OOM (error);
1968
/* Create our transaction */
1969
activation_transaction = bus_transaction_new (activation->context);
1970
if (activation_transaction == NULL)
1972
_dbus_verbose ("No memory to create activation transaction\n");
1973
dbus_message_unref (message);
1974
BUS_SET_OOM (error);
1978
/* Check whether systemd is already connected */
1979
registry = bus_connection_get_registry (connection);
1980
_dbus_string_init_const (&service_string, "org.freedesktop.systemd1");
1981
service = bus_registry_lookup (registry, &service_string);
1983
if (service != NULL)
1984
/* Wonderful, systemd is connected, let's just send the msg */
1985
retval = bus_dispatch_matches (activation_transaction, NULL, bus_service_get_primary_owners_connection (service),
1988
/* systemd is not around, let's "activate" it. */
1989
retval = bus_activation_activate_service (activation, connection, activation_transaction, TRUE,
1990
message, "org.freedesktop.systemd1", error);
1992
dbus_message_unref (message);
1996
_DBUS_ASSERT_ERROR_IS_SET (error);
1997
_dbus_verbose ("failed to send activation message: %s\n", error->name);
1998
bus_transaction_cancel_and_free (activation_transaction);
2002
bus_transaction_execute_and_free (activation_transaction);
2006
/* OK, we have no configured systemd service, hence let's
2007
proceed with traditional activation. */
2010
/* use command as system and session different */
2011
if (!_dbus_string_init (&command))
2013
BUS_SET_OOM (error);
2017
/* does the bus use a helper? */
2018
servicehelper = bus_context_get_servicehelper (activation->context);
2019
if (servicehelper != NULL)
2021
if (entry->user == NULL)
2023
_dbus_string_free (&command);
2024
dbus_set_error (error, DBUS_ERROR_SPAWN_FILE_INVALID,
2025
"Cannot do system-bus activation with no user\n");
2029
/* join the helper path and the service name */
2030
if (!_dbus_string_append (&command, servicehelper))
2032
_dbus_string_free (&command);
2033
BUS_SET_OOM (error);
2036
if (!_dbus_string_append (&command, " "))
2038
_dbus_string_free (&command);
2039
BUS_SET_OOM (error);
2042
if (!_dbus_string_append (&command, service_name))
2044
_dbus_string_free (&command);
2045
BUS_SET_OOM (error);
2051
/* the bus does not use a helper, so we can append arguments with the exec line */
2052
if (!_dbus_string_append (&command, entry->exec))
2054
_dbus_string_free (&command);
2055
BUS_SET_OOM (error);
2060
/* convert command into arguments */
2061
if (!_dbus_shell_parse_argv (_dbus_string_get_const_data (&command), &argc, &argv, error))
2063
_dbus_verbose ("Failed to parse command line: %s\n", entry->exec);
2064
_DBUS_ASSERT_ERROR_IS_SET (error);
2066
_dbus_hash_table_remove_string (activation->pending_activations,
2067
pending_activation->service_name);
2069
_dbus_string_free (&command);
2072
_dbus_string_free (&command);
2074
if (!add_bus_environment (activation, error))
2076
_DBUS_ASSERT_ERROR_IS_SET (error);
2077
dbus_free_string_array (argv);
2081
envp = bus_activation_get_environment (activation);
2085
BUS_SET_OOM (error);
2086
dbus_free_string_array (argv);
2090
_dbus_verbose ("Spawning %s ...\n", argv[0]);
2091
if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
2096
_dbus_verbose ("Failed to spawn child\n");
2097
_DBUS_ASSERT_ERROR_IS_SET (error);
2098
dbus_free_string_array (argv);
2099
dbus_free_string_array (envp);
2104
dbus_free_string_array (argv);
2107
_dbus_assert (pending_activation->babysitter != NULL);
2109
if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
2110
add_babysitter_watch,
2111
remove_babysitter_watch,
2116
BUS_SET_OOM (error);
2117
_dbus_verbose ("Failed to set babysitter watch functions\n");
2125
bus_activation_list_services (BusActivation *activation,
2133
len = _dbus_hash_table_get_n_entries (activation->entries);
2134
retval = dbus_new (char *, len + 1);
2139
_dbus_hash_iter_init (activation->entries, &iter);
2141
while (_dbus_hash_iter_next (&iter))
2143
BusActivationEntry *entry = _dbus_hash_iter_get_value (&iter);
2145
retval[i] = _dbus_strdup (entry->name);
2146
if (retval[i] == NULL)
2161
for (j = 0; j < i; j++)
2162
dbus_free (retval[i]);
2169
dbus_activation_systemd_failure (BusActivation *activation,
2170
DBusMessage *message)
2173
const char *code, *str, *unit = NULL;
2175
dbus_error_init(&error);
2177
/* This is called whenever the systemd activator sent us a
2178
response. We'll invalidate all pending activations that match the
2181
if (dbus_message_get_args (message, &error,
2182
DBUS_TYPE_STRING, &unit,
2183
DBUS_TYPE_STRING, &code,
2184
DBUS_TYPE_STRING, &str,
2186
dbus_set_error(&error, code, str);
2192
_dbus_hash_iter_init (activation->pending_activations,
2195
while (_dbus_hash_iter_next (&iter))
2197
BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
2199
if (p->systemd_service && strcmp (p->systemd_service, unit) == 0)
2200
pending_activation_failed(p, &error);
2204
dbus_error_free(&error);
2209
#ifdef DBUS_BUILD_TESTS
2213
#define SERVICE_NAME_1 "MyService1"
2214
#define SERVICE_NAME_2 "MyService2"
2215
#define SERVICE_NAME_3 "MyService3"
2217
#define SERVICE_FILE_1 "service-1.service"
2218
#define SERVICE_FILE_2 "service-2.service"
2219
#define SERVICE_FILE_3 "service-3.service"
2222
test_create_service_file (DBusString *dir,
2223
const char *filename,
2227
DBusString file_name, full_path;
2229
dbus_bool_t ret_val;
2232
_dbus_string_init_const (&file_name, filename);
2234
if (!_dbus_string_init (&full_path))
2237
if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
2238
!_dbus_concat_dir_and_file (&full_path, &file_name))
2244
file = fopen (_dbus_string_get_const_data (&full_path), "w");
2251
fprintf (file, "[D-BUS Service]\nName=%s\nExec=%s\n", name, exec);
2255
_dbus_string_free (&full_path);
2260
test_remove_service_file (DBusString *dir, const char *filename)
2262
DBusString file_name, full_path;
2263
dbus_bool_t ret_val;
2267
_dbus_string_init_const (&file_name, filename);
2269
if (!_dbus_string_init (&full_path))
2272
if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
2273
!_dbus_concat_dir_and_file (&full_path, &file_name))
2279
if (!_dbus_delete_file (&full_path, NULL))
2286
_dbus_string_free (&full_path);
2291
test_remove_directory (DBusString *dir)
2294
DBusString filename, full_path;
2295
dbus_bool_t ret_val;
2299
if (!_dbus_string_init (&filename))
2302
if (!_dbus_string_init (&full_path))
2304
_dbus_string_free (&filename);
2308
iter = _dbus_directory_open (dir, NULL);
2315
while (_dbus_directory_get_next_file (iter, &filename, NULL))
2317
if (!test_remove_service_file (dir, _dbus_string_get_const_data (&filename)))
2323
_dbus_directory_close (iter);
2325
if (!_dbus_delete_directory (dir, NULL))
2332
_dbus_string_free (&filename);
2333
_dbus_string_free (&full_path);
2339
init_service_reload_test (DBusString *dir)
2343
if (!_dbus_stat (dir, &stat_buf, NULL))
2345
if (!_dbus_create_directory (dir, NULL))
2350
if (!test_remove_directory (dir))
2353
if (!_dbus_create_directory (dir, NULL))
2357
/* Create one initial file */
2358
if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_1, "exec-1"))
2365
cleanup_service_reload_test (DBusString *dir)
2367
if (!test_remove_directory (dir))
2375
BusActivation *activation;
2376
const char *service_name;
2377
dbus_bool_t expecting_find;
2381
check_func (void *data)
2384
BusActivationEntry *entry;
2386
dbus_bool_t ret_val;
2391
dbus_error_init (&error);
2393
entry = activation_find_entry (d->activation, d->service_name, &error);
2396
if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2402
if (d->expecting_find)
2406
dbus_error_free (&error);
2410
if (!d->expecting_find)
2418
do_test (const char *description, dbus_bool_t oom_test, CheckData *data)
2423
err = !_dbus_test_oom_handling (description, check_func, data);
2425
err = !check_func (data);
2428
_dbus_assert_not_reached ("Test failed");
2434
do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
2436
BusActivation *activation;
2438
DBusList *directories;
2442
_dbus_string_init_const (&address, "");
2444
if (!_dbus_list_append (&directories, _dbus_string_get_data (dir)))
2447
activation = bus_activation_new (NULL, &address, &directories, NULL);
2451
d.activation = activation;
2453
/* Check for existing service file */
2454
d.expecting_find = TRUE;
2455
d.service_name = SERVICE_NAME_1;
2457
if (!do_test ("Existing service file", oom_test, &d))
2460
/* Check for non-existing service file */
2461
d.expecting_find = FALSE;
2462
d.service_name = SERVICE_NAME_3;
2464
if (!do_test ("Nonexisting service file", oom_test, &d))
2467
/* Check for added service file */
2468
if (!test_create_service_file (dir, SERVICE_FILE_2, SERVICE_NAME_2, "exec-2"))
2471
d.expecting_find = TRUE;
2472
d.service_name = SERVICE_NAME_2;
2474
if (!do_test ("Added service file", oom_test, &d))
2477
/* Check for removed service file */
2478
if (!test_remove_service_file (dir, SERVICE_FILE_2))
2481
d.expecting_find = FALSE;
2482
d.service_name = SERVICE_FILE_2;
2484
if (!do_test ("Removed service file", oom_test, &d))
2487
/* Check for updated service file */
2489
_dbus_sleep_milliseconds (1000); /* Sleep a second to make sure the mtime is updated */
2491
if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_3, "exec-3"))
2494
d.expecting_find = TRUE;
2495
d.service_name = SERVICE_NAME_3;
2497
if (!do_test ("Updated service file, part 1", oom_test, &d))
2500
d.expecting_find = FALSE;
2501
d.service_name = SERVICE_NAME_1;
2503
if (!do_test ("Updated service file, part 2", oom_test, &d))
2506
bus_activation_unref (activation);
2507
_dbus_list_clear (&directories);
2513
bus_activation_service_reload_test (const DBusString *test_data_dir)
2515
DBusString directory;
2517
if (!_dbus_string_init (&directory))
2520
if (!_dbus_string_append (&directory, _dbus_get_tmpdir()))
2523
if (!_dbus_string_append (&directory, "/dbus-reload-test-") ||
2524
!_dbus_generate_random_ascii (&directory, 6))
2529
/* Do normal tests */
2530
if (!init_service_reload_test (&directory))
2531
_dbus_assert_not_reached ("could not initiate service reload test");
2533
if (!do_service_reload_test (&directory, FALSE))
2537
if (!init_service_reload_test (&directory))
2538
_dbus_assert_not_reached ("could not initiate service reload test");
2540
if (!do_service_reload_test (&directory, TRUE))
2543
/* Cleanup test directory */
2544
if (!cleanup_service_reload_test (&directory))
2547
_dbus_string_free (&directory);
2552
#endif /* DBUS_BUILD_TESTS */