LCOV - code coverage report
Current view: top level - core - dbus-timer.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 168 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 8 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 168 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "alloc-util.h"
       4                 :            : #include "bus-util.h"
       5                 :            : #include "dbus-timer.h"
       6                 :            : #include "dbus-util.h"
       7                 :            : #include "strv.h"
       8                 :            : #include "timer.h"
       9                 :            : #include "unit.h"
      10                 :            : 
      11   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, timer_result, TimerResult);
                   #  # ]
      12                 :            : 
      13                 :          0 : static int property_get_monotonic_timers(
      14                 :            :                 sd_bus *bus,
      15                 :            :                 const char *path,
      16                 :            :                 const char *interface,
      17                 :            :                 const char *property,
      18                 :            :                 sd_bus_message *reply,
      19                 :            :                 void *userdata,
      20                 :            :                 sd_bus_error *error) {
      21                 :            : 
      22                 :          0 :         Timer *t = userdata;
      23                 :            :         TimerValue *v;
      24                 :            :         int r;
      25                 :            : 
      26         [ #  # ]:          0 :         assert(bus);
      27         [ #  # ]:          0 :         assert(reply);
      28         [ #  # ]:          0 :         assert(t);
      29                 :            : 
      30                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(stt)");
      31         [ #  # ]:          0 :         if (r < 0)
      32                 :          0 :                 return r;
      33                 :            : 
      34         [ #  # ]:          0 :         LIST_FOREACH(value, v, t->values) {
      35      [ #  #  # ]:          0 :                 _cleanup_free_ char *buf = NULL;
      36                 :            :                 const char *s;
      37                 :            :                 size_t l;
      38                 :            : 
      39         [ #  # ]:          0 :                 if (v->base == TIMER_CALENDAR)
      40                 :          0 :                         continue;
      41                 :            : 
      42                 :          0 :                 s = timer_base_to_string(v->base);
      43         [ #  # ]:          0 :                 assert(endswith(s, "Sec"));
      44                 :            : 
      45                 :            :                 /* s/Sec/USec/ */
      46                 :          0 :                 l = strlen(s);
      47                 :          0 :                 buf = new(char, l+2);
      48         [ #  # ]:          0 :                 if (!buf)
      49                 :          0 :                         return -ENOMEM;
      50                 :            : 
      51                 :          0 :                 memcpy(buf, s, l-3);
      52                 :          0 :                 memcpy(buf+l-3, "USec", 5);
      53                 :            : 
      54                 :          0 :                 r = sd_bus_message_append(reply, "(stt)", buf, v->value, v->next_elapse);
      55         [ #  # ]:          0 :                 if (r < 0)
      56                 :          0 :                         return r;
      57                 :            :         }
      58                 :            : 
      59                 :          0 :         return sd_bus_message_close_container(reply);
      60                 :            : }
      61                 :            : 
      62                 :          0 : static int property_get_calendar_timers(
      63                 :            :                 sd_bus *bus,
      64                 :            :                 const char *path,
      65                 :            :                 const char *interface,
      66                 :            :                 const char *property,
      67                 :            :                 sd_bus_message *reply,
      68                 :            :                 void *userdata,
      69                 :            :                 sd_bus_error *error) {
      70                 :            : 
      71                 :          0 :         Timer *t = userdata;
      72                 :            :         TimerValue *v;
      73                 :            :         int r;
      74                 :            : 
      75         [ #  # ]:          0 :         assert(bus);
      76         [ #  # ]:          0 :         assert(reply);
      77         [ #  # ]:          0 :         assert(t);
      78                 :            : 
      79                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(sst)");
      80         [ #  # ]:          0 :         if (r < 0)
      81                 :          0 :                 return r;
      82                 :            : 
      83         [ #  # ]:          0 :         LIST_FOREACH(value, v, t->values) {
      84      [ #  #  # ]:          0 :                 _cleanup_free_ char *buf = NULL;
      85                 :            : 
      86         [ #  # ]:          0 :                 if (v->base != TIMER_CALENDAR)
      87                 :          0 :                         continue;
      88                 :            : 
      89                 :          0 :                 r = calendar_spec_to_string(v->calendar_spec, &buf);
      90         [ #  # ]:          0 :                 if (r < 0)
      91                 :          0 :                         return r;
      92                 :            : 
      93                 :          0 :                 r = sd_bus_message_append(reply, "(sst)", timer_base_to_string(v->base), buf, v->next_elapse);
      94         [ #  # ]:          0 :                 if (r < 0)
      95                 :          0 :                         return r;
      96                 :            :         }
      97                 :            : 
      98                 :          0 :         return sd_bus_message_close_container(reply);
      99                 :            : }
     100                 :            : 
     101                 :          0 : static int property_get_next_elapse_monotonic(
     102                 :            :                 sd_bus *bus,
     103                 :            :                 const char *path,
     104                 :            :                 const char *interface,
     105                 :            :                 const char *property,
     106                 :            :                 sd_bus_message *reply,
     107                 :            :                 void *userdata,
     108                 :            :                 sd_bus_error *error) {
     109                 :            : 
     110                 :          0 :         Timer *t = userdata;
     111                 :            : 
     112         [ #  # ]:          0 :         assert(bus);
     113         [ #  # ]:          0 :         assert(reply);
     114         [ #  # ]:          0 :         assert(t);
     115                 :            : 
     116                 :          0 :         return sd_bus_message_append(reply, "t",
     117                 :          0 :                                      (uint64_t) usec_shift_clock(t->next_elapse_monotonic_or_boottime,
     118   [ #  #  #  # ]:          0 :                                                                  TIMER_MONOTONIC_CLOCK(t), CLOCK_MONOTONIC));
     119                 :            : }
     120                 :            : 
     121                 :            : const sd_bus_vtable bus_timer_vtable[] = {
     122                 :            :         SD_BUS_VTABLE_START(0),
     123                 :            :         SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     124                 :            :         SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
     125                 :            :         SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
     126                 :            :         SD_BUS_PROPERTY("OnClockChange", "b", bus_property_get_bool, offsetof(Timer, on_clock_change), SD_BUS_VTABLE_PROPERTY_CONST),
     127                 :            :         SD_BUS_PROPERTY("OnTimezoneChange", "b", bus_property_get_bool, offsetof(Timer, on_timezone_change), SD_BUS_VTABLE_PROPERTY_CONST),
     128                 :            :         SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
     129                 :            :         SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", property_get_next_elapse_monotonic, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
     130                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
     131                 :            :         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
     132                 :            :         SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
     133                 :            :         SD_BUS_PROPERTY("RandomizedDelayUSec", "t", bus_property_get_usec, offsetof(Timer, random_usec), SD_BUS_VTABLE_PROPERTY_CONST),
     134                 :            :         SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
     135                 :            :         SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
     136                 :            :         SD_BUS_PROPERTY("RemainAfterElapse", "b", bus_property_get_bool, offsetof(Timer, remain_after_elapse), SD_BUS_VTABLE_PROPERTY_CONST),
     137                 :            :         SD_BUS_VTABLE_END
     138                 :            : };
     139                 :            : 
     140                 :          0 : static int timer_add_one_monotonic_spec(
     141                 :            :                 Timer *t,
     142                 :            :                 const char *name,
     143                 :            :                 TimerBase base,
     144                 :            :                 UnitWriteFlags flags,
     145                 :            :                 usec_t usec,
     146                 :            :                 sd_bus_error *error) {
     147                 :            : 
     148         [ #  # ]:          0 :         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     149                 :            :                 char ts[FORMAT_TIMESPAN_MAX];
     150                 :            :                 TimerValue *v;
     151                 :            : 
     152         [ #  # ]:          0 :                 unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name,
     153                 :            :                                     "%s=%s",
     154                 :            :                                     timer_base_to_string(base),
     155                 :            :                                     format_timespan(ts, sizeof ts, usec, USEC_PER_MSEC));
     156                 :            : 
     157                 :          0 :                 v = new(TimerValue, 1);
     158         [ #  # ]:          0 :                 if (!v)
     159                 :          0 :                         return -ENOMEM;
     160                 :            : 
     161                 :          0 :                 *v = (TimerValue) {
     162                 :            :                         .base = base,
     163                 :            :                         .value = usec,
     164                 :            :                 };
     165                 :            : 
     166   [ #  #  #  # ]:          0 :                 LIST_PREPEND(value, t->values, v);
     167                 :            :         }
     168                 :            : 
     169                 :          0 :         return 1;
     170                 :            : }
     171                 :            : 
     172                 :          0 : static int timer_add_one_calendar_spec(
     173                 :            :                 Timer *t,
     174                 :            :                 const char *name,
     175                 :            :                 TimerBase base,
     176                 :            :                 UnitWriteFlags flags,
     177                 :            :                 const char *str,
     178                 :            :                 sd_bus_error *error) {
     179                 :            : 
     180                 :          0 :         _cleanup_(calendar_spec_freep) CalendarSpec *c = NULL;
     181                 :            :         int r;
     182                 :            : 
     183                 :          0 :         r = calendar_spec_from_string(str, &c);
     184         [ #  # ]:          0 :         if (r == -EINVAL)
     185                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid calendar spec");
     186         [ #  # ]:          0 :         if (r < 0)
     187                 :          0 :                 return r;
     188                 :            : 
     189         [ #  # ]:          0 :         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
     190         [ #  # ]:          0 :                 unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name,
     191                 :            :                                     "%s=%s", timer_base_to_string(base), str);
     192                 :            : 
     193                 :          0 :                 TimerValue *v = new(TimerValue, 1);
     194         [ #  # ]:          0 :                 if (!v)
     195                 :          0 :                         return -ENOMEM;
     196                 :            : 
     197                 :          0 :                 *v = (TimerValue) {
     198                 :            :                         .base = base,
     199                 :          0 :                         .calendar_spec = TAKE_PTR(c),
     200                 :            :                 };
     201                 :            : 
     202   [ #  #  #  # ]:          0 :                 LIST_PREPEND(value, t->values, v);
     203                 :            :         }
     204                 :            : 
     205                 :          0 :         return 1;
     206                 :            : };
     207                 :            : 
     208                 :          0 : static int bus_timer_set_transient_property(
     209                 :            :                 Timer *t,
     210                 :            :                 const char *name,
     211                 :            :                 sd_bus_message *message,
     212                 :            :                 UnitWriteFlags flags,
     213                 :            :                 sd_bus_error *error) {
     214                 :            : 
     215         [ #  # ]:          0 :         Unit *u = UNIT(t);
     216                 :            :         int r;
     217                 :            : 
     218         [ #  # ]:          0 :         assert(t);
     219         [ #  # ]:          0 :         assert(name);
     220         [ #  # ]:          0 :         assert(message);
     221                 :            : 
     222                 :          0 :         flags |= UNIT_PRIVATE;
     223                 :            : 
     224         [ #  # ]:          0 :         if (streq(name, "AccuracyUSec"))
     225                 :          0 :                 return bus_set_transient_usec(u, name, &t->accuracy_usec, message, flags, error);
     226                 :            : 
     227         [ #  # ]:          0 :         if (streq(name, "AccuracySec")) {
     228         [ #  # ]:          0 :                 log_notice("Client is using obsolete AccuracySec= transient property, please use AccuracyUSec= instead.");
     229                 :          0 :                 return bus_set_transient_usec(u, "AccuracyUSec", &t->accuracy_usec, message, flags, error);
     230                 :            :         }
     231                 :            : 
     232         [ #  # ]:          0 :         if (streq(name, "RandomizedDelayUSec"))
     233                 :          0 :                 return bus_set_transient_usec(u, name, &t->random_usec, message, flags, error);
     234                 :            : 
     235         [ #  # ]:          0 :         if (streq(name, "WakeSystem"))
     236                 :          0 :                 return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error);
     237                 :            : 
     238         [ #  # ]:          0 :         if (streq(name, "Persistent"))
     239                 :          0 :                 return bus_set_transient_bool(u, name, &t->persistent, message, flags, error);
     240                 :            : 
     241         [ #  # ]:          0 :         if (streq(name, "RemainAfterElapse"))
     242                 :          0 :                 return bus_set_transient_bool(u, name, &t->remain_after_elapse, message, flags, error);
     243                 :            : 
     244         [ #  # ]:          0 :         if (streq(name, "OnTimezoneChange"))
     245                 :          0 :                 return bus_set_transient_bool(u, name, &t->on_timezone_change, message, flags, error);
     246                 :            : 
     247         [ #  # ]:          0 :         if (streq(name, "OnClockChange"))
     248                 :          0 :                 return bus_set_transient_bool(u, name, &t->on_clock_change, message, flags, error);
     249                 :            : 
     250         [ #  # ]:          0 :         if (streq(name, "TimersMonotonic")) {
     251                 :            :                 const char *base_name;
     252                 :            :                 usec_t usec;
     253                 :          0 :                 bool empty = true;
     254                 :            : 
     255                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "(st)");
     256         [ #  # ]:          0 :                 if (r < 0)
     257                 :          0 :                         return r;
     258                 :            : 
     259         [ #  # ]:          0 :                 while ((r = sd_bus_message_read(message, "(st)", &base_name, &usec)) > 0) {
     260                 :            :                         TimerBase b;
     261                 :            : 
     262                 :          0 :                         b = timer_base_from_string(base_name);
     263   [ #  #  #  # ]:          0 :                         if (b < 0 || b == TIMER_CALENDAR)
     264                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     265                 :            :                                                          "Invalid timer base: %s", base_name);
     266                 :            : 
     267                 :          0 :                         r = timer_add_one_monotonic_spec(t, name, b, flags, usec, error);
     268         [ #  # ]:          0 :                         if (r < 0)
     269                 :          0 :                                 return r;
     270                 :            : 
     271                 :          0 :                         empty = false;
     272                 :            :                 }
     273         [ #  # ]:          0 :                 if (r < 0)
     274                 :          0 :                         return r;
     275                 :            : 
     276                 :          0 :                 r = sd_bus_message_exit_container(message);
     277         [ #  # ]:          0 :                 if (r < 0)
     278                 :          0 :                         return r;
     279                 :            : 
     280   [ #  #  #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
     281                 :          0 :                         timer_free_values(t);
     282                 :          0 :                         unit_write_setting(u, flags, name, "OnActiveSec=");
     283                 :            :                 }
     284                 :            : 
     285                 :          0 :                 return 1;
     286                 :            : 
     287         [ #  # ]:          0 :         } else if (streq(name, "TimersCalendar")) {
     288                 :            :                 const char *base_name, *str;
     289                 :          0 :                 bool empty = true;
     290                 :            : 
     291                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "(ss)");
     292         [ #  # ]:          0 :                 if (r < 0)
     293                 :          0 :                         return r;
     294                 :            : 
     295         [ #  # ]:          0 :                 while ((r = sd_bus_message_read(message, "(ss)", &base_name, &str)) > 0) {
     296                 :            :                         TimerBase b;
     297                 :            : 
     298                 :          0 :                         b = timer_base_from_string(base_name);
     299         [ #  # ]:          0 :                         if (b != TIMER_CALENDAR)
     300                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
     301                 :            :                                                          "Invalid timer base: %s", base_name);
     302                 :            : 
     303                 :          0 :                         r = timer_add_one_calendar_spec(t, name, b, flags, str, error);
     304         [ #  # ]:          0 :                         if (r < 0)
     305                 :          0 :                                 return r;
     306                 :            : 
     307                 :          0 :                         empty = false;
     308                 :            :                 }
     309         [ #  # ]:          0 :                 if (r < 0)
     310                 :          0 :                         return r;
     311                 :            : 
     312                 :          0 :                 r = sd_bus_message_exit_container(message);
     313         [ #  # ]:          0 :                 if (r < 0)
     314                 :          0 :                         return r;
     315                 :            : 
     316   [ #  #  #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
     317                 :          0 :                         timer_free_values(t);
     318                 :          0 :                         unit_write_setting(u, flags, name, "OnCalendar=");
     319                 :            :                 }
     320                 :            : 
     321                 :          0 :                 return 1;
     322                 :            : 
     323         [ #  # ]:          0 :         } else if (STR_IN_SET(name,
     324                 :            :                        "OnActiveSec",
     325                 :            :                        "OnBootSec",
     326                 :            :                        "OnStartupSec",
     327                 :            :                        "OnUnitActiveSec",
     328                 :            :                        "OnUnitInactiveSec")) {
     329                 :            : 
     330                 :            :                 TimerBase b;
     331                 :            :                 usec_t usec;
     332                 :            : 
     333         [ #  # ]:          0 :                 log_notice("Client is using obsolete %s= transient property, please use TimersMonotonic= instead.", name);
     334                 :            : 
     335                 :          0 :                 b = timer_base_from_string(name);
     336         [ #  # ]:          0 :                 if (b < 0)
     337                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown timer base");
     338                 :            : 
     339                 :          0 :                 r = sd_bus_message_read(message, "t", &usec);
     340         [ #  # ]:          0 :                 if (r < 0)
     341                 :          0 :                         return r;
     342                 :            : 
     343                 :          0 :                 return timer_add_one_monotonic_spec(t, name, b, flags, usec, error);
     344                 :            : 
     345         [ #  # ]:          0 :         } else if (streq(name, "OnCalendar")) {
     346                 :            : 
     347                 :            :                 const char *str;
     348                 :            : 
     349         [ #  # ]:          0 :                 log_notice("Client is using obsolete %s= transient property, please use TimersCalendar= instead.", name);
     350                 :            : 
     351                 :          0 :                 r = sd_bus_message_read(message, "s", &str);
     352         [ #  # ]:          0 :                 if (r < 0)
     353                 :          0 :                         return r;
     354                 :            : 
     355                 :          0 :                 return timer_add_one_calendar_spec(t, name, TIMER_CALENDAR, flags, str, error);
     356                 :            :         }
     357                 :            : 
     358                 :          0 :         return 0;
     359                 :            : }
     360                 :            : 
     361                 :          0 : int bus_timer_set_property(
     362                 :            :                 Unit *u,
     363                 :            :                 const char *name,
     364                 :            :                 sd_bus_message *message,
     365                 :            :                 UnitWriteFlags mode,
     366                 :            :                 sd_bus_error *error) {
     367                 :            : 
     368                 :          0 :         Timer *t = TIMER(u);
     369                 :            : 
     370         [ #  # ]:          0 :         assert(t);
     371         [ #  # ]:          0 :         assert(name);
     372         [ #  # ]:          0 :         assert(message);
     373                 :            : 
     374   [ #  #  #  # ]:          0 :         if (u->transient && u->load_state == UNIT_STUB)
     375                 :          0 :                 return bus_timer_set_transient_property(t, name, message, mode, error);
     376                 :            : 
     377                 :          0 :         return 0;
     378                 :            : }

Generated by: LCOV version 1.14