Home | History | Annotate | Download | only in bus
      1 /* -*- mode: C; c-file-style: "gnu" -*- */
      2 /* activation.c  Activation of services
      3  *
      4  * Copyright (C) 2003  CodeFactory AB
      5  * Copyright (C) 2003  Red Hat, Inc.
      6  * Copyright (C) 2004  Imendio HB
      7  *
      8  * Licensed under the Academic Free License version 2.1
      9  *
     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.
     14  *
     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.
     19  *
     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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     23  *
     24  */
     25 #include "activation.h"
     26 #include "desktop-file.h"
     27 #include "services.h"
     28 #include "test.h"
     29 #include "utils.h"
     30 #include <dbus/dbus-internals.h>
     31 #include <dbus/dbus-hash.h>
     32 #include <dbus/dbus-list.h>
     33 #include <dbus/dbus-shell.h>
     34 #include <dbus/dbus-spawn.h>
     35 #include <dbus/dbus-timeout.h>
     36 #include <dbus/dbus-sysdeps.h>
     37 #include <dirent.h>
     38 #include <errno.h>
     39 
     40 #define DBUS_SERVICE_SECTION "D-BUS Service"
     41 #define DBUS_SERVICE_NAME "Name"
     42 #define DBUS_SERVICE_EXEC "Exec"
     43 
     44 struct BusActivation
     45 {
     46   int refcount;
     47   DBusHashTable *entries;
     48   DBusHashTable *pending_activations;
     49   char *server_address;
     50   BusContext *context;
     51   int n_pending_activations; /**< This is in fact the number of BusPendingActivationEntry,
     52                               * i.e. number of pending activation requests, not pending
     53                               * activations per se
     54                               */
     55   DBusHashTable *directories;
     56 };
     57 
     58 typedef struct
     59 {
     60   int refcount;
     61   char *dir_c;
     62   DBusHashTable *entries;
     63 } BusServiceDirectory;
     64 
     65 typedef struct
     66 {
     67   int refcount;
     68   char *name;
     69   char *exec;
     70   unsigned long mtime;
     71   BusServiceDirectory *s_dir;
     72   char *filename;
     73 } BusActivationEntry;
     74 
     75 typedef struct BusPendingActivationEntry BusPendingActivationEntry;
     76 
     77 struct BusPendingActivationEntry
     78 {
     79   DBusMessage *activation_message;
     80   DBusConnection *connection;
     81 
     82   dbus_bool_t auto_activation;
     83 };
     84 
     85 typedef struct
     86 {
     87   int refcount;
     88   BusActivation *activation;
     89   char *service_name;
     90   char *exec;
     91   DBusList *entries;
     92   int n_entries;
     93   DBusBabysitter *babysitter;
     94   DBusTimeout *timeout;
     95   unsigned int timeout_added : 1;
     96 } BusPendingActivation;
     97 
     98 #if 0
     99 static BusServiceDirectory *
    100 bus_service_directory_ref (BusServiceDirectory *dir)
    101 {
    102   _dbus_assert (dir->refcount);
    103 
    104   dir->refcount++;
    105 
    106   return dir;
    107 }
    108 #endif
    109 
    110 static void
    111 bus_service_directory_unref (BusServiceDirectory *dir)
    112 {
    113   if (dir == NULL)
    114     return;
    115 
    116   _dbus_assert (dir->refcount > 0);
    117   dir->refcount--;
    118 
    119   if (dir->refcount > 0)
    120     return;
    121 
    122   if (dir->entries)
    123     _dbus_hash_table_unref (dir->entries);
    124 
    125   dbus_free (dir->dir_c);
    126   dbus_free (dir);
    127 }
    128 
    129 static void
    130 bus_pending_activation_entry_free (BusPendingActivationEntry *entry)
    131 {
    132   if (entry->activation_message)
    133     dbus_message_unref (entry->activation_message);
    134 
    135   if (entry->connection)
    136     dbus_connection_unref (entry->connection);
    137 
    138   dbus_free (entry);
    139 }
    140 
    141 static void
    142 handle_timeout_callback (DBusTimeout   *timeout,
    143                          void          *data)
    144 {
    145   BusPendingActivation *pending_activation = data;
    146 
    147   while (!dbus_timeout_handle (pending_activation->timeout))
    148     _dbus_wait_for_memory ();
    149 }
    150 
    151 static BusPendingActivation *
    152 bus_pending_activation_ref (BusPendingActivation *pending_activation)
    153 {
    154   _dbus_assert (pending_activation->refcount > 0);
    155   pending_activation->refcount += 1;
    156 
    157   return pending_activation;
    158 }
    159 
    160 static void
    161 bus_pending_activation_unref (BusPendingActivation *pending_activation)
    162 {
    163   DBusList *link;
    164 
    165   if (pending_activation == NULL) /* hash table requires this */
    166     return;
    167 
    168   _dbus_assert (pending_activation->refcount > 0);
    169   pending_activation->refcount -= 1;
    170 
    171   if (pending_activation->refcount > 0)
    172     return;
    173 
    174   if (pending_activation->timeout_added)
    175     {
    176       _dbus_loop_remove_timeout (bus_context_get_loop (pending_activation->activation->context),
    177                                  pending_activation->timeout,
    178                                  handle_timeout_callback, pending_activation);
    179       pending_activation->timeout_added = FALSE;
    180     }
    181 
    182   if (pending_activation->timeout)
    183     _dbus_timeout_unref (pending_activation->timeout);
    184 
    185   if (pending_activation->babysitter)
    186     {
    187       if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
    188                                                  NULL, NULL, NULL,
    189                                                  pending_activation->babysitter,
    190                                                  NULL))
    191         _dbus_assert_not_reached ("setting watch functions to NULL failed");
    192 
    193       _dbus_babysitter_unref (pending_activation->babysitter);
    194     }
    195 
    196   dbus_free (pending_activation->service_name);
    197   dbus_free (pending_activation->exec);
    198 
    199   link = _dbus_list_get_first_link (&pending_activation->entries);
    200 
    201   while (link != NULL)
    202     {
    203       BusPendingActivationEntry *entry = link->data;
    204 
    205       bus_pending_activation_entry_free (entry);
    206 
    207       link = _dbus_list_get_next_link (&pending_activation->entries, link);
    208     }
    209   _dbus_list_clear (&pending_activation->entries);
    210 
    211   pending_activation->activation->n_pending_activations -=
    212     pending_activation->n_entries;
    213 
    214   _dbus_assert (pending_activation->activation->n_pending_activations >= 0);
    215 
    216   dbus_free (pending_activation);
    217 }
    218 
    219 static BusActivationEntry *
    220 bus_activation_entry_ref (BusActivationEntry *entry)
    221 {
    222   _dbus_assert (entry->refcount > 0);
    223   entry->refcount++;
    224 
    225   return entry;
    226 }
    227 
    228 static void
    229 bus_activation_entry_unref (BusActivationEntry *entry)
    230 {
    231   if (entry == NULL) /* hash table requires this */
    232     return;
    233 
    234   _dbus_assert (entry->refcount > 0);
    235   entry->refcount--;
    236 
    237   if (entry->refcount > 0)
    238     return;
    239 
    240   dbus_free (entry->name);
    241   dbus_free (entry->exec);
    242   dbus_free (entry->filename);
    243 
    244   dbus_free (entry);
    245 }
    246 
    247 static dbus_bool_t
    248 update_desktop_file_entry (BusActivation       *activation,
    249                            BusServiceDirectory *s_dir,
    250                            DBusString          *filename,
    251                            BusDesktopFile      *desktop_file,
    252                            DBusError           *error)
    253 {
    254   char *name, *exec;
    255   BusActivationEntry *entry;
    256   DBusStat stat_buf;
    257   DBusString file_path;
    258 
    259   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    260 
    261   name = NULL;
    262   exec = NULL;
    263   entry = NULL;
    264 
    265   if (!_dbus_string_init (&file_path))
    266     {
    267       BUS_SET_OOM (error);
    268       return FALSE;
    269     }
    270 
    271   if (!_dbus_string_append (&file_path, s_dir->dir_c) ||
    272       !_dbus_concat_dir_and_file (&file_path, filename))
    273     {
    274       BUS_SET_OOM (error);
    275       goto failed;
    276     }
    277 
    278   if (!_dbus_stat (&file_path, &stat_buf, NULL))
    279     {
    280       dbus_set_error (error, DBUS_ERROR_FAILED,
    281                       "Can't stat the service file\n");
    282       goto failed;
    283     }
    284 
    285   if (!bus_desktop_file_get_string (desktop_file,
    286                                     DBUS_SERVICE_SECTION,
    287                                     DBUS_SERVICE_NAME,
    288                                     &name,
    289                                     error))
    290     goto failed;
    291 
    292   if (!bus_desktop_file_get_string (desktop_file,
    293                                     DBUS_SERVICE_SECTION,
    294                                     DBUS_SERVICE_EXEC,
    295                                     &exec,
    296                                     error))
    297     goto failed;
    298 
    299   entry = _dbus_hash_table_lookup_string (s_dir->entries,
    300                                           _dbus_string_get_const_data (filename));
    301   if (entry == NULL) /* New file */
    302     {
    303       /* FIXME we need a better-defined algorithm for which service file to
    304        * pick than "whichever one is first in the directory listing"
    305        */
    306       if (_dbus_hash_table_lookup_string (activation->entries, name))
    307         {
    308           dbus_set_error (error, DBUS_ERROR_FAILED,
    309                           "Service %s already exists in activation entry list\n", name);
    310           goto failed;
    311         }
    312 
    313       entry = dbus_new0 (BusActivationEntry, 1);
    314       if (entry == NULL)
    315         {
    316           BUS_SET_OOM (error);
    317           goto failed;
    318         }
    319 
    320       entry->name = name;
    321       entry->exec = exec;
    322       entry->refcount = 1;
    323 
    324       entry->s_dir = s_dir;
    325       entry->filename = _dbus_strdup (_dbus_string_get_const_data (filename));
    326       if (!entry->filename)
    327         {
    328           BUS_SET_OOM (error);
    329           goto failed;
    330         }
    331 
    332       if (!_dbus_hash_table_insert_string (activation->entries, entry->name, bus_activation_entry_ref (entry)))
    333         {
    334           BUS_SET_OOM (error);
    335           goto failed;
    336         }
    337 
    338       if (!_dbus_hash_table_insert_string (s_dir->entries, entry->filename, bus_activation_entry_ref (entry)))
    339         {
    340           /* Revert the insertion in the entries table */
    341           _dbus_hash_table_remove_string (activation->entries, entry->name);
    342           BUS_SET_OOM (error);
    343           goto failed;
    344         }
    345 
    346       _dbus_verbose ("Added \"%s\" to list of services\n", entry->name);
    347     }
    348   else /* Just update the entry */
    349     {
    350       bus_activation_entry_ref (entry);
    351       _dbus_hash_table_remove_string (activation->entries, entry->name);
    352 
    353       if (_dbus_hash_table_lookup_string (activation->entries, name))
    354         {
    355           _dbus_verbose ("The new service name \"%s\" of service file \"%s\" already in cache, ignoring\n",
    356                          name, _dbus_string_get_const_data (&file_path));
    357           goto failed;
    358         }
    359 
    360       dbus_free (entry->name);
    361       dbus_free (entry->exec);
    362       entry->name = name;
    363       entry->exec = exec;
    364       if (!_dbus_hash_table_insert_string (activation->entries,
    365                                            entry->name, bus_activation_entry_ref(entry)))
    366         {
    367           BUS_SET_OOM (error);
    368           /* Also remove path to entries hash since we want this in sync with
    369            * the entries hash table */
    370           _dbus_hash_table_remove_string (entry->s_dir->entries,
    371                                           entry->filename);
    372           bus_activation_entry_unref (entry);
    373           return FALSE;
    374         }
    375     }
    376 
    377   entry->mtime = stat_buf.mtime;
    378 
    379   _dbus_string_free (&file_path);
    380   bus_activation_entry_unref (entry);
    381 
    382   return TRUE;
    383 
    384 failed:
    385   dbus_free (name);
    386   dbus_free (exec);
    387   _dbus_string_free (&file_path);
    388 
    389   if (entry)
    390     bus_activation_entry_unref (entry);
    391 
    392   return FALSE;
    393 }
    394 
    395 static dbus_bool_t
    396 check_service_file (BusActivation       *activation,
    397                     BusActivationEntry  *entry,
    398                     BusActivationEntry **updated_entry,
    399                     DBusError           *error)
    400 {
    401   DBusStat stat_buf;
    402   dbus_bool_t retval;
    403   BusActivationEntry *tmp_entry;
    404   DBusString file_path;
    405   DBusString filename;
    406 
    407   retval = TRUE;
    408   tmp_entry = entry;
    409 
    410   _dbus_string_init_const (&filename, entry->filename);
    411 
    412   if (!_dbus_string_init (&file_path))
    413     {
    414       BUS_SET_OOM (error);
    415       return FALSE;
    416     }
    417 
    418   if (!_dbus_string_append (&file_path, entry->s_dir->dir_c) ||
    419       !_dbus_concat_dir_and_file (&file_path, &filename))
    420     {
    421       BUS_SET_OOM (error);
    422       retval = FALSE;
    423       goto out;
    424     }
    425 
    426   if (!_dbus_stat (&file_path, &stat_buf, NULL))
    427     {
    428       _dbus_verbose ("****** Can't stat file \"%s\", removing from cache\n",
    429                      _dbus_string_get_const_data (&file_path));
    430 
    431       _dbus_hash_table_remove_string (activation->entries, entry->name);
    432       _dbus_hash_table_remove_string (entry->s_dir->entries, entry->filename);
    433 
    434       tmp_entry = NULL;
    435       retval = TRUE;
    436       goto out;
    437     }
    438   else
    439     {
    440       if (stat_buf.mtime > entry->mtime)
    441         {
    442           BusDesktopFile *desktop_file;
    443           DBusError tmp_error;
    444 
    445           dbus_error_init (&tmp_error);
    446 
    447           desktop_file = bus_desktop_file_load (&file_path, &tmp_error);
    448           if (desktop_file == NULL)
    449             {
    450               _dbus_verbose ("Could not load %s: %s\n",
    451                              _dbus_string_get_const_data (&file_path),
    452                              tmp_error.message);
    453               if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    454                 {
    455                   dbus_move_error (&tmp_error, error);
    456                   retval = FALSE;
    457                   goto out;
    458                 }
    459               dbus_error_free (&tmp_error);
    460               retval = TRUE;
    461               goto out;
    462             }
    463 
    464           /* @todo We can return OOM or a DBUS_ERROR_FAILED error
    465            *       Handle these both better
    466            */
    467           if (!update_desktop_file_entry (activation, entry->s_dir, &filename, desktop_file, &tmp_error))
    468             {
    469               bus_desktop_file_free (desktop_file);
    470               if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    471                 {
    472                   dbus_move_error (&tmp_error, error);
    473                   retval = FALSE;
    474                   goto out;
    475                 }
    476               dbus_error_free (&tmp_error);
    477               retval = TRUE;
    478               goto out;
    479             }
    480 
    481           bus_desktop_file_free (desktop_file);
    482           retval = TRUE;
    483         }
    484     }
    485 
    486 out:
    487   _dbus_string_free (&file_path);
    488 
    489   if (updated_entry != NULL)
    490     *updated_entry = tmp_entry;
    491   return retval;
    492 }
    493 
    494 
    495 /* warning: this doesn't fully "undo" itself on failure, i.e. doesn't strip
    496  * hash entries it already added.
    497  */
    498 static dbus_bool_t
    499 update_directory (BusActivation       *activation,
    500                   BusServiceDirectory *s_dir,
    501                   DBusError           *error)
    502 {
    503   DBusDirIter *iter;
    504   DBusString dir, filename;
    505   BusDesktopFile *desktop_file;
    506   DBusError tmp_error;
    507   dbus_bool_t retval;
    508   BusActivationEntry *entry;
    509   DBusString full_path;
    510 
    511   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    512 
    513   iter = NULL;
    514   desktop_file = NULL;
    515 
    516   _dbus_string_init_const (&dir, s_dir->dir_c);
    517 
    518   if (!_dbus_string_init (&filename))
    519     {
    520       BUS_SET_OOM (error);
    521       return FALSE;
    522     }
    523 
    524   if (!_dbus_string_init (&full_path))
    525     {
    526       BUS_SET_OOM (error);
    527       _dbus_string_free (&filename);
    528       return FALSE;
    529     }
    530 
    531   retval = FALSE;
    532 
    533   /* from this point it's safe to "goto out" */
    534 
    535   iter = _dbus_directory_open (&dir, error);
    536   if (iter == NULL)
    537     {
    538       _dbus_verbose ("Failed to open directory %s: %s\n",
    539                      s_dir->dir_c,
    540                      error ? error->message : "unknown");
    541       goto out;
    542     }
    543 
    544   /* Now read the files */
    545   dbus_error_init (&tmp_error);
    546   while (_dbus_directory_get_next_file (iter, &filename, &tmp_error))
    547     {
    548       _dbus_assert (!dbus_error_is_set (&tmp_error));
    549 
    550       _dbus_string_set_length (&full_path, 0);
    551 
    552       if (!_dbus_string_ends_with_c_str (&filename, ".service"))
    553         {
    554           _dbus_verbose ("Skipping non-.service file %s\n",
    555                          _dbus_string_get_const_data (&filename));
    556           continue;
    557         }
    558 
    559       entry = _dbus_hash_table_lookup_string (s_dir->entries, _dbus_string_get_const_data (&filename));
    560       if (entry) /* Already has this service file in the cache */
    561         {
    562           if (!check_service_file (activation, entry, NULL, error))
    563             goto out;
    564 
    565           continue;
    566         }
    567 
    568       if (!_dbus_string_append (&full_path, s_dir->dir_c) ||
    569           !_dbus_concat_dir_and_file (&full_path, &filename))
    570         {
    571           BUS_SET_OOM (error);
    572           goto out;
    573         }
    574 
    575       /* New file */
    576       desktop_file = bus_desktop_file_load (&full_path, &tmp_error);
    577       if (desktop_file == NULL)
    578         {
    579           _dbus_verbose ("Could not load %s: %s\n",
    580                          _dbus_string_get_const_data (&full_path),
    581                          tmp_error.message);
    582 
    583           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    584             {
    585               dbus_move_error (&tmp_error, error);
    586               goto out;
    587             }
    588 
    589           dbus_error_free (&tmp_error);
    590           continue;
    591         }
    592 
    593       /* @todo We can return OOM or a DBUS_ERROR_FAILED error
    594        *       Handle these both better
    595        */
    596       if (!update_desktop_file_entry (activation, s_dir, &filename, desktop_file, &tmp_error))
    597         {
    598           bus_desktop_file_free (desktop_file);
    599           desktop_file = NULL;
    600 
    601           _dbus_verbose ("Could not add %s to activation entry list: %s\n",
    602                          _dbus_string_get_const_data (&full_path), tmp_error.message);
    603 
    604           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
    605             {
    606               dbus_move_error (&tmp_error, error);
    607               goto out;
    608             }
    609 
    610           dbus_error_free (&tmp_error);
    611           continue;
    612         }
    613       else
    614         {
    615           bus_desktop_file_free (desktop_file);
    616           desktop_file = NULL;
    617           continue;
    618         }
    619     }
    620 
    621   if (dbus_error_is_set (&tmp_error))
    622     {
    623       dbus_move_error (&tmp_error, error);
    624       goto out;
    625     }
    626 
    627   retval = TRUE;
    628 
    629  out:
    630   if (!retval)
    631     _DBUS_ASSERT_ERROR_IS_SET (error);
    632   else
    633     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    634 
    635   if (iter != NULL)
    636     _dbus_directory_close (iter);
    637   _dbus_string_free (&filename);
    638   _dbus_string_free (&full_path);
    639 
    640   return retval;
    641 }
    642 
    643 BusActivation*
    644 bus_activation_new (BusContext        *context,
    645                     const DBusString  *address,
    646                     DBusList         **directories,
    647                     DBusError         *error)
    648 {
    649   BusActivation *activation;
    650   DBusList      *link;
    651   char          *dir;
    652 
    653   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    654 
    655   activation = dbus_new0 (BusActivation, 1);
    656   if (activation == NULL)
    657     {
    658       BUS_SET_OOM (error);
    659       return NULL;
    660     }
    661 
    662   activation->refcount = 1;
    663   activation->context = context;
    664   activation->n_pending_activations = 0;
    665 
    666   if (!_dbus_string_copy_data (address, &activation->server_address))
    667     {
    668       BUS_SET_OOM (error);
    669       goto failed;
    670     }
    671 
    672   activation->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    673                                              (DBusFreeFunction)bus_activation_entry_unref);
    674   if (activation->entries == NULL)
    675     {
    676       BUS_SET_OOM (error);
    677       goto failed;
    678     }
    679 
    680   activation->pending_activations = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    681                                                           (DBusFreeFunction)bus_pending_activation_unref);
    682 
    683   if (activation->pending_activations == NULL)
    684     {
    685       BUS_SET_OOM (error);
    686       goto failed;
    687     }
    688 
    689   activation->directories = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    690                                                   (DBusFreeFunction)bus_service_directory_unref);
    691 
    692   if (activation->directories == NULL)
    693     {
    694       BUS_SET_OOM (error);
    695       goto failed;
    696     }
    697 
    698   /* Load service files */
    699   link = _dbus_list_get_first_link (directories);
    700   while (link != NULL)
    701     {
    702       BusServiceDirectory *s_dir;
    703 
    704       dir = _dbus_strdup ((const char *) link->data);
    705       if (!dir)
    706         {
    707           BUS_SET_OOM (error);
    708           goto failed;
    709         }
    710 
    711       s_dir = dbus_new0 (BusServiceDirectory, 1);
    712       if (!s_dir)
    713         {
    714           dbus_free (dir);
    715           BUS_SET_OOM (error);
    716           goto failed;
    717         }
    718 
    719       s_dir->refcount = 1;
    720       s_dir->dir_c = dir;
    721 
    722       s_dir->entries = _dbus_hash_table_new (DBUS_HASH_STRING, NULL,
    723                                              (DBusFreeFunction)bus_activation_entry_unref);
    724 
    725       if (!s_dir->entries)
    726         {
    727           bus_service_directory_unref (s_dir);
    728           BUS_SET_OOM (error);
    729           goto failed;
    730         }
    731 
    732       if (!_dbus_hash_table_insert_string (activation->directories, s_dir->dir_c, s_dir))
    733         {
    734           bus_service_directory_unref (s_dir);
    735           BUS_SET_OOM (error);
    736           goto failed;
    737         }
    738 
    739       /* only fail on OOM, it is ok if we can't read the directory */
    740       if (!update_directory (activation, s_dir, error))
    741         {
    742           if (dbus_error_has_name (error, DBUS_ERROR_NO_MEMORY))
    743             goto failed;
    744           else
    745             dbus_error_free (error);
    746         }
    747 
    748       link = _dbus_list_get_next_link (directories, link);
    749     }
    750 
    751   return activation;
    752 
    753  failed:
    754   bus_activation_unref (activation);
    755   return NULL;
    756 }
    757 
    758 BusActivation *
    759 bus_activation_ref (BusActivation *activation)
    760 {
    761   _dbus_assert (activation->refcount > 0);
    762 
    763   activation->refcount += 1;
    764 
    765   return activation;
    766 }
    767 
    768 void
    769 bus_activation_unref (BusActivation *activation)
    770 {
    771   _dbus_assert (activation->refcount > 0);
    772 
    773   activation->refcount -= 1;
    774 
    775   if (activation->refcount > 0)
    776     return;
    777 
    778   dbus_free (activation->server_address);
    779   if (activation->entries)
    780     _dbus_hash_table_unref (activation->entries);
    781   if (activation->pending_activations)
    782     _dbus_hash_table_unref (activation->pending_activations);
    783   if (activation->directories)
    784     _dbus_hash_table_unref (activation->directories);
    785 
    786   dbus_free (activation);
    787 }
    788 
    789 static void
    790 child_setup (void *data)
    791 {
    792   BusActivation *activation = data;
    793   const char *type;
    794 
    795   /* If no memory, we simply have the child exit, so it won't try
    796    * to connect to the wrong thing.
    797    */
    798   if (!_dbus_setenv ("DBUS_STARTER_ADDRESS", activation->server_address))
    799     _dbus_exit (1);
    800 
    801   type = bus_context_get_type (activation->context);
    802   if (type != NULL)
    803     {
    804       if (!_dbus_setenv ("DBUS_STARTER_BUS_TYPE", type))
    805         _dbus_exit (1);
    806 
    807       if (strcmp (type, "session") == 0)
    808         {
    809           if (!_dbus_setenv ("DBUS_SESSION_BUS_ADDRESS",
    810                              activation->server_address))
    811             _dbus_exit (1);
    812         }
    813       else if (strcmp (type, "system") == 0)
    814         {
    815           if (!_dbus_setenv ("DBUS_SYSTEM_BUS_ADDRESS",
    816                              activation->server_address))
    817             _dbus_exit (1);
    818         }
    819     }
    820 }
    821 
    822 typedef struct
    823 {
    824   BusPendingActivation *pending_activation;
    825   DBusPreallocatedHash *hash_entry;
    826 } RestorePendingData;
    827 
    828 static void
    829 restore_pending (void *data)
    830 {
    831   RestorePendingData *d = data;
    832 
    833   _dbus_assert (d->pending_activation != NULL);
    834   _dbus_assert (d->hash_entry != NULL);
    835 
    836   _dbus_verbose ("Restoring pending activation for service %s, has timeout = %d\n",
    837                  d->pending_activation->service_name,
    838                  d->pending_activation->timeout_added);
    839 
    840   _dbus_hash_table_insert_string_preallocated (d->pending_activation->activation->pending_activations,
    841                                                d->hash_entry,
    842                                                d->pending_activation->service_name, d->pending_activation);
    843 
    844   bus_pending_activation_ref (d->pending_activation);
    845 
    846   d->hash_entry = NULL;
    847 }
    848 
    849 static void
    850 free_pending_restore_data (void *data)
    851 {
    852   RestorePendingData *d = data;
    853 
    854   if (d->hash_entry)
    855     _dbus_hash_table_free_preallocated_entry (d->pending_activation->activation->pending_activations,
    856                                               d->hash_entry);
    857 
    858   bus_pending_activation_unref (d->pending_activation);
    859 
    860   dbus_free (d);
    861 }
    862 
    863 static dbus_bool_t
    864 add_restore_pending_to_transaction (BusTransaction       *transaction,
    865                                     BusPendingActivation *pending_activation)
    866 {
    867   RestorePendingData *d;
    868 
    869   d = dbus_new (RestorePendingData, 1);
    870   if (d == NULL)
    871     return FALSE;
    872 
    873   d->pending_activation = pending_activation;
    874   d->hash_entry = _dbus_hash_table_preallocate_entry (d->pending_activation->activation->pending_activations);
    875 
    876   bus_pending_activation_ref (d->pending_activation);
    877 
    878   if (d->hash_entry == NULL ||
    879       !bus_transaction_add_cancel_hook (transaction, restore_pending, d,
    880                                         free_pending_restore_data))
    881     {
    882       free_pending_restore_data (d);
    883       return FALSE;
    884     }
    885 
    886   _dbus_verbose ("Saved pending activation to be restored if the transaction fails\n");
    887 
    888   return TRUE;
    889 }
    890 
    891 dbus_bool_t
    892 bus_activation_service_created (BusActivation  *activation,
    893                                 const char     *service_name,
    894                                 BusTransaction *transaction,
    895                                 DBusError      *error)
    896 {
    897   BusPendingActivation *pending_activation;
    898   DBusMessage *message;
    899   DBusList *link;
    900 
    901   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    902 
    903   /* Check if it's a pending activation */
    904   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
    905 
    906   if (!pending_activation)
    907     return TRUE;
    908 
    909   link = _dbus_list_get_first_link (&pending_activation->entries);
    910   while (link != NULL)
    911     {
    912       BusPendingActivationEntry *entry = link->data;
    913       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
    914 
    915       if (dbus_connection_get_is_connected (entry->connection))
    916         {
    917           /* Only send activation replies to regular activation requests. */
    918           if (!entry->auto_activation)
    919             {
    920               dbus_uint32_t result;
    921 
    922               message = dbus_message_new_method_return (entry->activation_message);
    923               if (!message)
    924                 {
    925                   BUS_SET_OOM (error);
    926                   goto error;
    927                 }
    928 
    929               result = DBUS_START_REPLY_SUCCESS;
    930 
    931               if (!dbus_message_append_args (message,
    932                                              DBUS_TYPE_UINT32, &result,
    933                                              DBUS_TYPE_INVALID))
    934                 {
    935                   dbus_message_unref (message);
    936                   BUS_SET_OOM (error);
    937                   goto error;
    938                 }
    939 
    940               if (!bus_transaction_send_from_driver (transaction, entry->connection, message))
    941                 {
    942                   dbus_message_unref (message);
    943                   BUS_SET_OOM (error);
    944                   goto error;
    945                 }
    946 
    947               dbus_message_unref (message);
    948             }
    949         }
    950 
    951       link = next;
    952     }
    953 
    954   return TRUE;
    955 
    956  error:
    957   return FALSE;
    958 }
    959 
    960 dbus_bool_t
    961 bus_activation_send_pending_auto_activation_messages (BusActivation  *activation,
    962                                                       BusService     *service,
    963                                                       BusTransaction *transaction,
    964                                                       DBusError      *error)
    965 {
    966   BusPendingActivation *pending_activation;
    967   DBusList *link;
    968 
    969   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    970 
    971   /* Check if it's a pending activation */
    972   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations,
    973                                                        bus_service_get_name (service));
    974 
    975   if (!pending_activation)
    976     return TRUE;
    977 
    978   link = _dbus_list_get_first_link (&pending_activation->entries);
    979   while (link != NULL)
    980     {
    981       BusPendingActivationEntry *entry = link->data;
    982       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
    983 
    984       if (entry->auto_activation && dbus_connection_get_is_connected (entry->connection))
    985         {
    986           DBusConnection *addressed_recipient;
    987 
    988           addressed_recipient = bus_service_get_primary_owners_connection (service);
    989 
    990           /* Check the security policy, which has the side-effect of adding an
    991            * expected pending reply.
    992            */
    993           if (!bus_context_check_security_policy (activation->context, transaction,
    994                                                   entry->connection,
    995                                                   addressed_recipient,
    996                                                   addressed_recipient,
    997                                                   entry->activation_message, error))
    998             goto error;
    999 
   1000           if (!bus_transaction_send (transaction, addressed_recipient, entry->activation_message))
   1001             {
   1002               BUS_SET_OOM (error);
   1003               goto error;
   1004             }
   1005         }
   1006 
   1007       link = next;
   1008     }
   1009 
   1010   if (!add_restore_pending_to_transaction (transaction, pending_activation))
   1011     {
   1012       _dbus_verbose ("Could not add cancel hook to transaction to revert removing pending activation\n");
   1013       BUS_SET_OOM (error);
   1014       goto error;
   1015     }
   1016 
   1017   _dbus_hash_table_remove_string (activation->pending_activations, bus_service_get_name (service));
   1018 
   1019   return TRUE;
   1020 
   1021  error:
   1022   return FALSE;
   1023 }
   1024 
   1025 /**
   1026  * FIXME @todo the error messages here would ideally be preallocated
   1027  * so we don't need to allocate memory to send them.
   1028  * Using the usual tactic, prealloc an OOM message, then
   1029  * if we can't alloc the real error send the OOM error instead.
   1030  */
   1031 static dbus_bool_t
   1032 try_send_activation_failure (BusPendingActivation *pending_activation,
   1033                              const DBusError      *how)
   1034 {
   1035   BusActivation *activation;
   1036   DBusList *link;
   1037   BusTransaction *transaction;
   1038 
   1039   activation = pending_activation->activation;
   1040 
   1041   transaction = bus_transaction_new (activation->context);
   1042   if (transaction == NULL)
   1043     return FALSE;
   1044 
   1045   link = _dbus_list_get_first_link (&pending_activation->entries);
   1046   while (link != NULL)
   1047     {
   1048       BusPendingActivationEntry *entry = link->data;
   1049       DBusList *next = _dbus_list_get_next_link (&pending_activation->entries, link);
   1050 
   1051       if (dbus_connection_get_is_connected (entry->connection))
   1052         {
   1053           if (!bus_transaction_send_error_reply (transaction,
   1054                                                  entry->connection,
   1055                                                  how,
   1056                                                  entry->activation_message))
   1057             goto error;
   1058         }
   1059 
   1060       link = next;
   1061     }
   1062 
   1063   bus_transaction_execute_and_free (transaction);
   1064 
   1065   return TRUE;
   1066 
   1067  error:
   1068   if (transaction)
   1069     bus_transaction_cancel_and_free (transaction);
   1070   return FALSE;
   1071 }
   1072 
   1073 /**
   1074  * Free the pending activation and send an error message to all the
   1075  * connections that were waiting for it.
   1076  */
   1077 static void
   1078 pending_activation_failed (BusPendingActivation *pending_activation,
   1079                            const DBusError      *how)
   1080 {
   1081   /* FIXME use preallocated OOM messages instead of bus_wait_for_memory() */
   1082   while (!try_send_activation_failure (pending_activation, how))
   1083     _dbus_wait_for_memory ();
   1084 
   1085   /* Destroy this pending activation */
   1086   _dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
   1087                                   pending_activation->service_name);
   1088 }
   1089 
   1090 static dbus_bool_t
   1091 babysitter_watch_callback (DBusWatch     *watch,
   1092                            unsigned int   condition,
   1093                            void          *data)
   1094 {
   1095   BusPendingActivation *pending_activation = data;
   1096   dbus_bool_t retval;
   1097   DBusBabysitter *babysitter;
   1098 
   1099   babysitter = pending_activation->babysitter;
   1100 
   1101   _dbus_babysitter_ref (babysitter);
   1102 
   1103   retval = dbus_watch_handle (watch, condition);
   1104 
   1105   /* FIXME this is broken in the same way that
   1106    * connection watches used to be; there should be
   1107    * a separate callback for status change, instead
   1108    * of doing "if we handled a watch status might
   1109    * have changed"
   1110    *
   1111    * Fixing this lets us move dbus_watch_handle
   1112    * calls into dbus-mainloop.c
   1113    */
   1114 
   1115   if (_dbus_babysitter_get_child_exited (babysitter))
   1116     {
   1117       DBusError error;
   1118       DBusHashIter iter;
   1119 
   1120       dbus_error_init (&error);
   1121       _dbus_babysitter_set_child_exit_error (babysitter, &error);
   1122 
   1123       /* Destroy all pending activations with the same exec */
   1124       _dbus_hash_iter_init (pending_activation->activation->pending_activations,
   1125                             &iter);
   1126       while (_dbus_hash_iter_next (&iter))
   1127         {
   1128           BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
   1129 
   1130           if (p != pending_activation && strcmp (p->exec, pending_activation->exec) == 0)
   1131             pending_activation_failed (p, &error);
   1132         }
   1133 
   1134       /* Destroys the pending activation */
   1135       pending_activation_failed (pending_activation, &error);
   1136 
   1137       dbus_error_free (&error);
   1138     }
   1139 
   1140   _dbus_babysitter_unref (babysitter);
   1141 
   1142   return retval;
   1143 }
   1144 
   1145 static dbus_bool_t
   1146 add_babysitter_watch (DBusWatch      *watch,
   1147                       void           *data)
   1148 {
   1149   BusPendingActivation *pending_activation = data;
   1150 
   1151   return _dbus_loop_add_watch (bus_context_get_loop (pending_activation->activation->context),
   1152                                watch, babysitter_watch_callback, pending_activation,
   1153                                NULL);
   1154 }
   1155 
   1156 static void
   1157 remove_babysitter_watch (DBusWatch      *watch,
   1158                          void           *data)
   1159 {
   1160   BusPendingActivation *pending_activation = data;
   1161 
   1162   _dbus_loop_remove_watch (bus_context_get_loop (pending_activation->activation->context),
   1163                            watch, babysitter_watch_callback, pending_activation);
   1164 }
   1165 
   1166 static dbus_bool_t
   1167 pending_activation_timed_out (void *data)
   1168 {
   1169   BusPendingActivation *pending_activation = data;
   1170   DBusError error;
   1171 
   1172   /* Kill the spawned process, since it sucks
   1173    * (not sure this is what we want to do, but
   1174    * may as well try it for now)
   1175    */
   1176   if (pending_activation->babysitter)
   1177     _dbus_babysitter_kill_child (pending_activation->babysitter);
   1178 
   1179   dbus_error_init (&error);
   1180 
   1181   dbus_set_error (&error, DBUS_ERROR_TIMED_OUT,
   1182                   "Activation of %s timed out",
   1183                   pending_activation->service_name);
   1184 
   1185   pending_activation_failed (pending_activation, &error);
   1186 
   1187   dbus_error_free (&error);
   1188 
   1189   return TRUE;
   1190 }
   1191 
   1192 static void
   1193 cancel_pending (void *data)
   1194 {
   1195   BusPendingActivation *pending_activation = data;
   1196 
   1197   _dbus_verbose ("Canceling pending activation of %s\n",
   1198                  pending_activation->service_name);
   1199 
   1200   if (pending_activation->babysitter)
   1201     _dbus_babysitter_kill_child (pending_activation->babysitter);
   1202 
   1203   _dbus_hash_table_remove_string (pending_activation->activation->pending_activations,
   1204                                   pending_activation->service_name);
   1205 }
   1206 
   1207 static void
   1208 free_pending_cancel_data (void *data)
   1209 {
   1210   BusPendingActivation *pending_activation = data;
   1211 
   1212   bus_pending_activation_unref (pending_activation);
   1213 }
   1214 
   1215 static dbus_bool_t
   1216 add_cancel_pending_to_transaction (BusTransaction       *transaction,
   1217                                    BusPendingActivation *pending_activation)
   1218 {
   1219   if (!bus_transaction_add_cancel_hook (transaction, cancel_pending,
   1220                                         pending_activation,
   1221                                         free_pending_cancel_data))
   1222     return FALSE;
   1223 
   1224   bus_pending_activation_ref (pending_activation);
   1225 
   1226   _dbus_verbose ("Saved pending activation to be canceled if the transaction fails\n");
   1227 
   1228   return TRUE;
   1229 }
   1230 
   1231 static dbus_bool_t
   1232 update_service_cache (BusActivation *activation, DBusError *error)
   1233 {
   1234   DBusHashIter iter;
   1235 
   1236   _dbus_hash_iter_init (activation->directories, &iter);
   1237   while (_dbus_hash_iter_next (&iter))
   1238     {
   1239       DBusError tmp_error;
   1240       BusServiceDirectory *s_dir;
   1241 
   1242       s_dir = _dbus_hash_iter_get_value (&iter);
   1243 
   1244       dbus_error_init (&tmp_error);
   1245       if (!update_directory (activation, s_dir, &tmp_error))
   1246         {
   1247           if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY))
   1248             {
   1249               dbus_move_error (&tmp_error, error);
   1250               return FALSE;
   1251             }
   1252 
   1253           dbus_error_free (&tmp_error);
   1254           continue;
   1255         }
   1256     }
   1257 
   1258   return TRUE;
   1259 }
   1260 
   1261 static BusActivationEntry *
   1262 activation_find_entry (BusActivation *activation,
   1263                        const char    *service_name,
   1264                        DBusError     *error)
   1265 {
   1266   BusActivationEntry *entry;
   1267 
   1268   entry = _dbus_hash_table_lookup_string (activation->entries, service_name);
   1269   if (!entry)
   1270     {
   1271       if (!update_service_cache (activation, error))
   1272         return NULL;
   1273 
   1274       entry = _dbus_hash_table_lookup_string (activation->entries,
   1275                                               service_name);
   1276     }
   1277   else
   1278     {
   1279       BusActivationEntry *updated_entry;
   1280 
   1281       if (!check_service_file (activation, entry, &updated_entry, error))
   1282         return NULL;
   1283 
   1284       entry = updated_entry;
   1285     }
   1286 
   1287   if (!entry)
   1288     {
   1289       dbus_set_error (error, DBUS_ERROR_SERVICE_UNKNOWN,
   1290                       "The name %s was not provided by any .service files",
   1291                       service_name);
   1292       return NULL;
   1293     }
   1294 
   1295   return entry;
   1296 }
   1297 
   1298 dbus_bool_t
   1299 bus_activation_activate_service (BusActivation  *activation,
   1300                                  DBusConnection *connection,
   1301                                  BusTransaction *transaction,
   1302                                  dbus_bool_t     auto_activation,
   1303                                  DBusMessage    *activation_message,
   1304                                  const char     *service_name,
   1305                                  DBusError      *error)
   1306 {
   1307   BusActivationEntry *entry;
   1308   BusPendingActivation *pending_activation;
   1309   BusPendingActivationEntry *pending_activation_entry;
   1310   DBusMessage *message;
   1311   DBusString service_str;
   1312   char **argv;
   1313   int argc;
   1314   dbus_bool_t retval;
   1315   DBusHashIter iter;
   1316   dbus_bool_t activated;
   1317 
   1318   activated = TRUE;
   1319 
   1320   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1321 
   1322   if (activation->n_pending_activations >=
   1323       bus_context_get_max_pending_activations (activation->context))
   1324     {
   1325       dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
   1326                       "The maximum number of pending activations has been reached, activation of %s failed",
   1327                       service_name);
   1328       return FALSE;
   1329     }
   1330 
   1331   entry = activation_find_entry (activation, service_name, error);
   1332   if (!entry)
   1333     return FALSE;
   1334 
   1335   /* Bypass the registry lookup if we're auto-activating, bus_dispatch would not
   1336    * call us if the service is already active.
   1337    */
   1338   if (!auto_activation)
   1339     {
   1340       /* Check if the service is active */
   1341       _dbus_string_init_const (&service_str, service_name);
   1342       if (bus_registry_lookup (bus_context_get_registry (activation->context), &service_str) != NULL)
   1343         {
   1344           dbus_uint32_t result;
   1345 
   1346           _dbus_verbose ("Service \"%s\" is already active\n", service_name);
   1347 
   1348           message = dbus_message_new_method_return (activation_message);
   1349 
   1350           if (!message)
   1351             {
   1352               _dbus_verbose ("No memory to create reply to activate message\n");
   1353               BUS_SET_OOM (error);
   1354               return FALSE;
   1355             }
   1356 
   1357           result = DBUS_START_REPLY_ALREADY_RUNNING;
   1358 
   1359           if (!dbus_message_append_args (message,
   1360                                          DBUS_TYPE_UINT32, &result,
   1361                                          DBUS_TYPE_INVALID))
   1362             {
   1363               _dbus_verbose ("No memory to set args of reply to activate message\n");
   1364               BUS_SET_OOM (error);
   1365               dbus_message_unref (message);
   1366               return FALSE;
   1367             }
   1368 
   1369           retval = bus_transaction_send_from_driver (transaction, connection, message);
   1370           dbus_message_unref (message);
   1371           if (!retval)
   1372             {
   1373               _dbus_verbose ("Failed to send reply\n");
   1374               BUS_SET_OOM (error);
   1375             }
   1376 
   1377           return retval;
   1378         }
   1379     }
   1380 
   1381   pending_activation_entry = dbus_new0 (BusPendingActivationEntry, 1);
   1382   if (!pending_activation_entry)
   1383     {
   1384       _dbus_verbose ("Failed to create pending activation entry\n");
   1385       BUS_SET_OOM (error);
   1386       return FALSE;
   1387     }
   1388 
   1389   pending_activation_entry->auto_activation = auto_activation;
   1390 
   1391   pending_activation_entry->activation_message = activation_message;
   1392   dbus_message_ref (activation_message);
   1393   pending_activation_entry->connection = connection;
   1394   dbus_connection_ref (connection);
   1395 
   1396   /* Check if the service is being activated */
   1397   pending_activation = _dbus_hash_table_lookup_string (activation->pending_activations, service_name);
   1398   if (pending_activation)
   1399     {
   1400       if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
   1401         {
   1402           _dbus_verbose ("Failed to append a new entry to pending activation\n");
   1403 
   1404           BUS_SET_OOM (error);
   1405           bus_pending_activation_entry_free (pending_activation_entry);
   1406           return FALSE;
   1407         }
   1408 
   1409       pending_activation->n_entries += 1;
   1410       pending_activation->activation->n_pending_activations += 1;
   1411     }
   1412   else
   1413     {
   1414       pending_activation = dbus_new0 (BusPendingActivation, 1);
   1415       if (!pending_activation)
   1416         {
   1417           _dbus_verbose ("Failed to create pending activation\n");
   1418 
   1419           BUS_SET_OOM (error);
   1420           bus_pending_activation_entry_free (pending_activation_entry);
   1421           return FALSE;
   1422         }
   1423 
   1424       pending_activation->activation = activation;
   1425       pending_activation->refcount = 1;
   1426 
   1427       pending_activation->service_name = _dbus_strdup (service_name);
   1428       if (!pending_activation->service_name)
   1429         {
   1430           _dbus_verbose ("Failed to copy service name for pending activation\n");
   1431 
   1432           BUS_SET_OOM (error);
   1433           bus_pending_activation_unref (pending_activation);
   1434           bus_pending_activation_entry_free (pending_activation_entry);
   1435           return FALSE;
   1436         }
   1437 
   1438       pending_activation->exec = _dbus_strdup (entry->exec);
   1439       if (!pending_activation->exec)
   1440         {
   1441           _dbus_verbose ("Failed to copy service exec for pending activation\n");
   1442           BUS_SET_OOM (error);
   1443           bus_pending_activation_unref (pending_activation);
   1444           bus_pending_activation_entry_free (pending_activation_entry);
   1445           return FALSE;
   1446         }
   1447 
   1448       pending_activation->timeout =
   1449         _dbus_timeout_new (bus_context_get_activation_timeout (activation->context),
   1450                            pending_activation_timed_out,
   1451                            pending_activation,
   1452                            NULL);
   1453       if (!pending_activation->timeout)
   1454         {
   1455           _dbus_verbose ("Failed to create timeout for pending activation\n");
   1456 
   1457           BUS_SET_OOM (error);
   1458           bus_pending_activation_unref (pending_activation);
   1459           bus_pending_activation_entry_free (pending_activation_entry);
   1460           return FALSE;
   1461         }
   1462 
   1463       if (!_dbus_loop_add_timeout (bus_context_get_loop (activation->context),
   1464                                    pending_activation->timeout,
   1465                                    handle_timeout_callback,
   1466                                    pending_activation,
   1467                                    NULL))
   1468         {
   1469           _dbus_verbose ("Failed to add timeout for pending activation\n");
   1470 
   1471           BUS_SET_OOM (error);
   1472           bus_pending_activation_unref (pending_activation);
   1473           bus_pending_activation_entry_free (pending_activation_entry);
   1474           return FALSE;
   1475         }
   1476 
   1477       pending_activation->timeout_added = TRUE;
   1478 
   1479       if (!_dbus_list_append (&pending_activation->entries, pending_activation_entry))
   1480         {
   1481           _dbus_verbose ("Failed to add entry to just-created pending activation\n");
   1482 
   1483           BUS_SET_OOM (error);
   1484           bus_pending_activation_unref (pending_activation);
   1485           bus_pending_activation_entry_free (pending_activation_entry);
   1486           return FALSE;
   1487         }
   1488 
   1489       pending_activation->n_entries += 1;
   1490       pending_activation->activation->n_pending_activations += 1;
   1491 
   1492       activated = FALSE;
   1493       _dbus_hash_iter_init (activation->pending_activations, &iter);
   1494       while (_dbus_hash_iter_next (&iter))
   1495         {
   1496           BusPendingActivation *p = _dbus_hash_iter_get_value (&iter);
   1497 
   1498           if (strcmp (p->exec, entry->exec) == 0)
   1499             {
   1500               activated = TRUE;
   1501               break;
   1502             }
   1503         }
   1504 
   1505       if (!_dbus_hash_table_insert_string (activation->pending_activations,
   1506                                            pending_activation->service_name,
   1507                                            pending_activation))
   1508         {
   1509           _dbus_verbose ("Failed to put pending activation in hash table\n");
   1510 
   1511           BUS_SET_OOM (error);
   1512           bus_pending_activation_unref (pending_activation);
   1513           return FALSE;
   1514         }
   1515     }
   1516 
   1517   if (!add_cancel_pending_to_transaction (transaction, pending_activation))
   1518     {
   1519       _dbus_verbose ("Failed to add pending activation cancel hook to transaction\n");
   1520       BUS_SET_OOM (error);
   1521       _dbus_hash_table_remove_string (activation->pending_activations,
   1522                                       pending_activation->service_name);
   1523 
   1524       return FALSE;
   1525     }
   1526 
   1527   if (activated)
   1528     return TRUE;
   1529 
   1530   /* Now try to spawn the process */
   1531   if (!_dbus_shell_parse_argv (entry->exec, &argc, &argv, error))
   1532     {
   1533       _dbus_verbose ("Failed to parse command line: %s\n", entry->exec);
   1534       _DBUS_ASSERT_ERROR_IS_SET (error);
   1535 
   1536       _dbus_hash_table_remove_string (activation->pending_activations,
   1537                                       pending_activation->service_name);
   1538 
   1539       return FALSE;
   1540     }
   1541 
   1542   _dbus_verbose ("Spawning %s ...\n", argv[0]);
   1543   if (!_dbus_spawn_async_with_babysitter (&pending_activation->babysitter, argv,
   1544                                           child_setup, activation,
   1545                                           error))
   1546     {
   1547       _dbus_verbose ("Failed to spawn child\n");
   1548       _DBUS_ASSERT_ERROR_IS_SET (error);
   1549       dbus_free_string_array (argv);
   1550 
   1551       return FALSE;
   1552     }
   1553 
   1554   dbus_free_string_array (argv);
   1555 
   1556   _dbus_assert (pending_activation->babysitter != NULL);
   1557 
   1558   if (!_dbus_babysitter_set_watch_functions (pending_activation->babysitter,
   1559                                              add_babysitter_watch,
   1560                                              remove_babysitter_watch,
   1561                                              NULL,
   1562                                              pending_activation,
   1563                                              NULL))
   1564     {
   1565       BUS_SET_OOM (error);
   1566       _dbus_verbose ("Failed to set babysitter watch functions\n");
   1567       return FALSE;
   1568     }
   1569 
   1570   return TRUE;
   1571 }
   1572 
   1573 dbus_bool_t
   1574 bus_activation_list_services (BusActivation *activation,
   1575 			      char        ***listp,
   1576 			      int           *array_len)
   1577 {
   1578   int i, j, len;
   1579   char **retval;
   1580   DBusHashIter iter;
   1581 
   1582   len = _dbus_hash_table_get_n_entries (activation->entries);
   1583   retval = dbus_new (char *, len + 1);
   1584 
   1585   if (retval == NULL)
   1586     return FALSE;
   1587 
   1588   _dbus_hash_iter_init (activation->entries, &iter);
   1589   i = 0;
   1590   while (_dbus_hash_iter_next (&iter))
   1591     {
   1592       BusActivationEntry *entry = _dbus_hash_iter_get_value (&iter);
   1593 
   1594       retval[i] = _dbus_strdup (entry->name);
   1595       if (retval[i] == NULL)
   1596 	goto error;
   1597 
   1598       i++;
   1599     }
   1600 
   1601   retval[i] = NULL;
   1602 
   1603   if (array_len)
   1604     *array_len = len;
   1605 
   1606   *listp = retval;
   1607   return TRUE;
   1608 
   1609  error:
   1610   for (j = 0; j < i; j++)
   1611     dbus_free (retval[i]);
   1612   dbus_free (retval);
   1613 
   1614   return FALSE;
   1615 }
   1616 
   1617 
   1618 #ifdef DBUS_BUILD_TESTS
   1619 
   1620 #include <stdio.h>
   1621 
   1622 #define SERVICE_NAME_1 "MyService1"
   1623 #define SERVICE_NAME_2 "MyService2"
   1624 #define SERVICE_NAME_3 "MyService3"
   1625 
   1626 #define SERVICE_FILE_1 "service-1.service"
   1627 #define SERVICE_FILE_2 "service-2.service"
   1628 #define SERVICE_FILE_3 "service-3.service"
   1629 
   1630 static dbus_bool_t
   1631 test_create_service_file (DBusString *dir,
   1632                           const char *filename,
   1633                           const char *name,
   1634                           const char *exec)
   1635 {
   1636   DBusString  file_name, full_path;
   1637   FILE        *file;
   1638   dbus_bool_t  ret_val;
   1639 
   1640   ret_val = TRUE;
   1641   _dbus_string_init_const (&file_name, filename);
   1642 
   1643   if (!_dbus_string_init (&full_path))
   1644     return FALSE;
   1645 
   1646   if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
   1647       !_dbus_concat_dir_and_file (&full_path, &file_name))
   1648     {
   1649       ret_val = FALSE;
   1650       goto out;
   1651     }
   1652 
   1653   file = fopen (_dbus_string_get_const_data (&full_path), "w");
   1654   if (!file)
   1655     {
   1656       ret_val = FALSE;
   1657       goto out;
   1658     }
   1659 
   1660   fprintf (file, "[D-BUS Service]\nName=%s\nExec=%s\n", name, exec);
   1661   fclose (file);
   1662 
   1663 out:
   1664   _dbus_string_free (&full_path);
   1665   return ret_val;
   1666 }
   1667 
   1668 static dbus_bool_t
   1669 test_remove_service_file (DBusString *dir, const char *filename)
   1670 {
   1671   DBusString  file_name, full_path;
   1672   dbus_bool_t ret_val;
   1673 
   1674   ret_val = TRUE;
   1675 
   1676   _dbus_string_init_const (&file_name, filename);
   1677 
   1678   if (!_dbus_string_init (&full_path))
   1679     return FALSE;
   1680 
   1681   if (!_dbus_string_append (&full_path, _dbus_string_get_const_data (dir)) ||
   1682       !_dbus_concat_dir_and_file (&full_path, &file_name))
   1683     {
   1684       ret_val = FALSE;
   1685       goto out;
   1686     }
   1687 
   1688   if (!_dbus_delete_file (&full_path, NULL))
   1689     {
   1690       ret_val = FALSE;
   1691       goto out;
   1692     }
   1693 
   1694 out:
   1695   _dbus_string_free (&full_path);
   1696   return ret_val;
   1697 }
   1698 
   1699 static dbus_bool_t
   1700 test_remove_directory (DBusString *dir)
   1701 {
   1702   DBusDirIter *iter;
   1703   DBusString   filename, full_path;
   1704   dbus_bool_t  ret_val;
   1705 
   1706   ret_val = TRUE;
   1707 
   1708   if (!_dbus_string_init (&filename))
   1709     return FALSE;
   1710 
   1711   if (!_dbus_string_init (&full_path))
   1712     {
   1713       _dbus_string_free (&filename);
   1714       return FALSE;
   1715     }
   1716 
   1717   iter = _dbus_directory_open (dir, NULL);
   1718   if (iter == NULL)
   1719     {
   1720       ret_val = FALSE;
   1721       goto out;
   1722     }
   1723 
   1724   while (_dbus_directory_get_next_file (iter, &filename, NULL))
   1725     {
   1726       if (!test_remove_service_file (dir, _dbus_string_get_const_data (&filename)))
   1727         {
   1728           ret_val = FALSE;
   1729           goto out;
   1730         }
   1731     }
   1732   _dbus_directory_close (iter);
   1733 
   1734   if (!_dbus_delete_directory (dir, NULL))
   1735     {
   1736       ret_val = FALSE;
   1737       goto out;
   1738     }
   1739 
   1740 out:
   1741   _dbus_string_free (&filename);
   1742   _dbus_string_free (&full_path);
   1743 
   1744   return ret_val;
   1745 }
   1746 
   1747 static dbus_bool_t
   1748 init_service_reload_test (DBusString *dir)
   1749 {
   1750   DBusStat stat_buf;
   1751 
   1752   if (!_dbus_stat (dir, &stat_buf, NULL))
   1753     {
   1754       if (!_dbus_create_directory (dir, NULL))
   1755         return FALSE;
   1756     }
   1757   else
   1758     {
   1759       if (!test_remove_directory (dir))
   1760         return FALSE;
   1761 
   1762       if (!_dbus_create_directory (dir, NULL))
   1763         return FALSE;
   1764     }
   1765 
   1766   /* Create one initial file */
   1767   if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_1, "exec-1"))
   1768     return FALSE;
   1769 
   1770   return TRUE;
   1771 }
   1772 
   1773 static dbus_bool_t
   1774 cleanup_service_reload_test (DBusString *dir)
   1775 {
   1776   if (!test_remove_directory (dir))
   1777     return FALSE;
   1778 
   1779   return TRUE;
   1780 }
   1781 
   1782 typedef struct
   1783 {
   1784   BusActivation *activation;
   1785   const char    *service_name;
   1786   dbus_bool_t    expecting_find;
   1787 } CheckData;
   1788 
   1789 static dbus_bool_t
   1790 check_func (void *data)
   1791 {
   1792   CheckData          *d;
   1793   BusActivationEntry *entry;
   1794   DBusError           error;
   1795   dbus_bool_t         ret_val;
   1796 
   1797   ret_val = TRUE;
   1798   d = data;
   1799 
   1800   dbus_error_init (&error);
   1801 
   1802   entry = activation_find_entry (d->activation, d->service_name, &error);
   1803   if (entry == NULL)
   1804     {
   1805       if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
   1806         {
   1807           ret_val = TRUE;
   1808         }
   1809       else
   1810         {
   1811           if (d->expecting_find)
   1812             ret_val = FALSE;
   1813         }
   1814 
   1815       dbus_error_free (&error);
   1816     }
   1817   else
   1818     {
   1819       if (!d->expecting_find)
   1820         ret_val = FALSE;
   1821     }
   1822 
   1823   return ret_val;
   1824 }
   1825 
   1826 static dbus_bool_t
   1827 do_test (const char *description, dbus_bool_t oom_test, CheckData *data)
   1828 {
   1829   dbus_bool_t err;
   1830 
   1831   if (oom_test)
   1832     err = !_dbus_test_oom_handling (description, check_func, data);
   1833   else
   1834     err = !check_func (data);
   1835 
   1836   if (err)
   1837     _dbus_assert_not_reached ("Test failed");
   1838 
   1839   return TRUE;
   1840 }
   1841 
   1842 static dbus_bool_t
   1843 do_service_reload_test (DBusString *dir, dbus_bool_t oom_test)
   1844 {
   1845   BusActivation *activation;
   1846   DBusString     address;
   1847   DBusList      *directories;
   1848   CheckData      d;
   1849 
   1850   directories = NULL;
   1851   _dbus_string_init_const (&address, "");
   1852 
   1853   if (!_dbus_list_append (&directories, _dbus_string_get_data (dir)))
   1854     return FALSE;
   1855 
   1856   activation = bus_activation_new (NULL, &address, &directories, NULL);
   1857   if (!activation)
   1858     return FALSE;
   1859 
   1860   d.activation = activation;
   1861 
   1862   /* Check for existing service file */
   1863   d.expecting_find = TRUE;
   1864   d.service_name = SERVICE_NAME_1;
   1865 
   1866   if (!do_test ("Existing service file", oom_test, &d))
   1867     return FALSE;
   1868 
   1869   /* Check for non-existing service file */
   1870   d.expecting_find = FALSE;
   1871   d.service_name = SERVICE_NAME_3;
   1872 
   1873   if (!do_test ("Nonexisting service file", oom_test, &d))
   1874     return FALSE;
   1875 
   1876   /* Check for added service file */
   1877   if (!test_create_service_file (dir, SERVICE_FILE_2, SERVICE_NAME_2, "exec-2"))
   1878     return FALSE;
   1879 
   1880   d.expecting_find = TRUE;
   1881   d.service_name = SERVICE_NAME_2;
   1882 
   1883   if (!do_test ("Added service file", oom_test, &d))
   1884     return FALSE;
   1885 
   1886   /* Check for removed service file */
   1887   if (!test_remove_service_file (dir, SERVICE_FILE_2))
   1888     return FALSE;
   1889 
   1890   d.expecting_find = FALSE;
   1891   d.service_name = SERVICE_FILE_2;
   1892 
   1893   if (!do_test ("Removed service file", oom_test, &d))
   1894     return FALSE;
   1895 
   1896   /* Check for updated service file */
   1897 
   1898   _dbus_sleep_milliseconds (1000); /* Sleep a second to make sure the mtime is updated */
   1899 
   1900   if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_3, "exec-3"))
   1901     return FALSE;
   1902 
   1903   d.expecting_find = TRUE;
   1904   d.service_name = SERVICE_NAME_3;
   1905 
   1906   if (!do_test ("Updated service file, part 1", oom_test, &d))
   1907     return FALSE;
   1908 
   1909   d.expecting_find = FALSE;
   1910   d.service_name = SERVICE_NAME_1;
   1911 
   1912   if (!do_test ("Updated service file, part 2", oom_test, &d))
   1913     return FALSE;
   1914 
   1915   bus_activation_unref (activation);
   1916   _dbus_list_clear (&directories);
   1917 
   1918   return TRUE;
   1919 }
   1920 
   1921 dbus_bool_t
   1922 bus_activation_service_reload_test (const DBusString *test_data_dir)
   1923 {
   1924   DBusString directory;
   1925 
   1926   if (!_dbus_string_init (&directory))
   1927     return FALSE;
   1928 
   1929   if (!_dbus_string_append (&directory, _dbus_get_tmpdir()))
   1930     return FALSE;
   1931 
   1932   if (!_dbus_string_append (&directory, "/dbus-reload-test-") ||
   1933       !_dbus_generate_random_ascii (&directory, 6))
   1934      {
   1935        return FALSE;
   1936      }
   1937 
   1938   /* Do normal tests */
   1939   if (!init_service_reload_test (&directory))
   1940     _dbus_assert_not_reached ("could not initiate service reload test");
   1941 
   1942   if (!do_service_reload_test (&directory, FALSE))
   1943     ; /* Do nothing? */
   1944 
   1945   /* Do OOM tests */
   1946   if (!init_service_reload_test (&directory))
   1947     _dbus_assert_not_reached ("could not initiate service reload test");
   1948 
   1949   if (!do_service_reload_test (&directory, TRUE))
   1950     ; /* Do nothing? */
   1951 
   1952   /* Cleanup test directory */
   1953   if (!cleanup_service_reload_test (&directory))
   1954     return FALSE;
   1955 
   1956   _dbus_string_free (&directory);
   1957 
   1958   return TRUE;
   1959 }
   1960 
   1961 #endif /* DBUS_BUILD_TESTS */
   1962