along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <time.h>
#include <string.h>
-#include <sys/timex.h>
#include <sys/timerfd.h>
+#include <sys/timex.h>
-#include "util.h"
-#include "time-util.h"
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
+#include "parse-util.h"
#include "path-util.h"
+#include "string-util.h"
#include "strv.h"
+#include "time-util.h"
+#include "util.h"
usec_t now(clockid_t clock_id) {
struct timespec ts;
return timespec_load(&ts);
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
nsec_t now_nsec(clockid_t clock_id) {
struct timespec ts;
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
- ts->monotonic = now(CLOCK_MONOTONIC);
-
- if ((int64_t) ts->monotonic > delta)
- ts->monotonic -= delta;
- else
- ts->monotonic = 0;
+ ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
return ts;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) {
int64_t delta;
assert(ts);
ts->monotonic = u;
delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
-
- ts->realtime = now(CLOCK_REALTIME);
- if ((int64_t) ts->realtime > delta)
- ts->realtime -= delta;
- else
- ts->realtime = 0;
+ ts->realtime = usec_sub(now(CLOCK_REALTIME), delta);
return ts;
}
ts->realtime = ts->monotonic = USEC_INFINITY;
return ts;
}
- ts->realtime = now(CLOCK_REALTIME);
- ts->monotonic = now(CLOCK_MONOTONIC);
+ dual_timestamp_get(ts);
delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
-
- if ((int64_t) ts->realtime > delta)
- ts->realtime -= delta;
- else
- ts->realtime = 0;
-
- if ((int64_t) ts->monotonic > delta)
- ts->monotonic -= delta;
- else
- ts->monotonic = 0;
+ ts->realtime = usec_sub(ts->realtime, delta);
+ ts->monotonic = usec_sub(ts->monotonic, delta);
return ts;
}
return NULL;
sec = (time_t) (t / USEC_PER_SEC);
+ localtime_or_gmtime_r(&sec, &tm, utc);
- if (utc)
- gmtime_r(&sec, &tm);
- else
- localtime_r(&sec, &tm);
if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm) <= 0)
return NULL;
return format_timestamp_internal(buf, l, t, false);
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
char *format_timestamp_utc(char *buf, size_t l, usec_t t) {
return format_timestamp_internal(buf, l, t, true);
}
return NULL;
sec = (time_t) (t / USEC_PER_SEC);
- if (utc)
- gmtime_r(&sec, &tm);
- else
- localtime_r(&sec, &tm);
+ localtime_or_gmtime_r(&sec, &tm, utc);
if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0)
return NULL;
return format_timestamp_internal_us(buf, l, t, false);
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) {
return format_timestamp_internal_us(buf, l, t, true);
}
return buf;
}
-/// UNNEEDED by elogind
-#if 0
+#if 0 /// UNNEEDED by elogind
void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
assert(f);
};
const char *k;
- bool utc;
+ const char *utc;
struct tm tm, copy;
time_t x;
usec_t x_usec, plus = 0, minus = 0, ret;
goto finish;
- } else if (endswith(t, " ago")) {
- t = strndupa(t, strlen(t) - strlen(" ago"));
+ } else if ((k = endswith(t, " ago"))) {
+ t = strndupa(t, k - t);
r = parse_sec(t, &minus);
if (r < 0)
goto finish;
- } else if (endswith(t, " left")) {
- t = strndupa(t, strlen(t) - strlen(" left"));
+ } else if ((k = endswith(t, " left"))) {
+ t = strndupa(t, k - t);
r = parse_sec(t, &plus);
if (r < 0)
utc = endswith_no_case(t, " UTC");
if (utc)
- t = strndupa(t, strlen(t) - strlen(" UTC"));
+ t = strndupa(t, utc - t);
x = ret / USEC_PER_SEC;
x_usec = 0;
parse_usec:
{
- char *end;
- unsigned long long val;
- size_t l;
+ unsigned add;
k++;
- if (*k < '0' || *k > '9')
+ r = parse_fractional_part_u(&k, 6, &add);
+ if (r < 0)
return -EINVAL;
- /* base 10 instead of base 0, .09 is not base 8 */
- errno = 0;
- val = strtoull(k, &end, 10);
- if (*end || errno)
+ if (*k)
return -EINVAL;
- l = end-k;
+ x_usec = add;
- /* val has l digits, make them 6 */
- for (; l < 6; l++)
- val *= 10;
- for (; l > 6; l--)
- val /= 10;
-
- x_usec = val;
}
from_tm:
}
#endif // 0
-int parse_sec(const char *t, usec_t *usec) {
+int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
+
static const struct {
const char *suffix;
usec_t usec;
{ "min", USEC_PER_MINUTE },
{ "months", USEC_PER_MONTH },
{ "month", USEC_PER_MONTH },
+ { "M", USEC_PER_MONTH },
{ "msec", USEC_PER_MSEC },
{ "ms", USEC_PER_MSEC },
{ "m", USEC_PER_MINUTE },
{ "y", USEC_PER_YEAR },
{ "usec", 1ULL },
{ "us", 1ULL },
- { "", USEC_PER_SEC }, /* default is sec */
};
const char *p, *s;
assert(t);
assert(usec);
+ assert(default_unit > 0);
p = t;
long long l, z = 0;
char *e;
unsigned i, n = 0;
+ usec_t multiplier, k;
p += strspn(p, WHITESPACE);
for (i = 0; i < ELEMENTSOF(table); i++)
if (startswith(e, table[i].suffix)) {
- usec_t k = (usec_t) z * table[i].usec;
-
- for (; n > 0; n--)
- k /= 10;
-
- r += (usec_t) l * table[i].usec + k;
+ multiplier = table[i].usec;
p = e + strlen(table[i].suffix);
-
- something = true;
break;
}
- if (i >= ELEMENTSOF(table))
- return -EINVAL;
+ if (i >= ELEMENTSOF(table)) {
+ multiplier = default_unit;
+ p = e;
+ }
+
+ something = true;
+ k = (usec_t) z * multiplier;
+
+ for (; n > 0; n--)
+ k /= 10;
+
+ r += (usec_t) l * multiplier + k;
}
*usec = r;
return 0;
}
-/// UNNEEDED by elogind
-#if 0
+int parse_sec(const char *t, usec_t *usec) {
+ return parse_time(t, usec, USEC_PER_SEC);
+}
+
+#if 0 /// UNNEEDED by elogind
int parse_nsec(const char *t, nsec_t *nsec) {
static const struct {
const char *suffix;
*tz = z;
return 0;
}
+
+time_t mktime_or_timegm(struct tm *tm, bool utc) {
+ return utc ? timegm(tm) : mktime(tm);
+}
+#endif // 0
+
+struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc) {
+ return utc ? gmtime_r(t, tm) : localtime_r(t, tm);
+}
+
+#if 0 /// UNNEEDED by elogind
+unsigned long usec_to_jiffies(usec_t u) {
+ static thread_local unsigned long hz = 0;
+ long r;
+
+ if (hz == 0) {
+ r = sysconf(_SC_CLK_TCK);
+
+ assert(r > 0);
+ hz = (unsigned long) r;
+ }
+
+ return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
+}
#endif // 0