diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/escape.c | 28 | ||||
-rw-r--r-- | src/basic/escape.h | 1 | ||||
-rw-r--r-- | src/basic/hexdecoct.c | 3 | ||||
-rw-r--r-- | src/basic/time-util.c | 24 | ||||
-rw-r--r-- | src/basic/util.h | 10 |
5 files changed, 63 insertions, 3 deletions
diff --git a/src/basic/escape.c b/src/basic/escape.c index 2e483880c8..01daf11ce7 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -413,6 +413,34 @@ char *xescape(const char *s, const char *bad) { return r; } +char *octescape(const char *s, size_t len) { + char *r, *t; + const char *f; + + /* Escapes all chars in bad, in addition to \ and " chars, + * in \nnn style escaping. */ + + r = new(char, len * 4 + 1); + if (!r) + return NULL; + + for (f = s, t = r; f < s + len; f++) { + + if (*f < ' ' || *f >= 127 || *f == '\\' || *f == '"') { + *(t++) = '\\'; + *(t++) = '0' + (*f >> 6); + *(t++) = '0' + ((*f >> 3) & 8); + *(t++) = '0' + (*f & 8); + } else + *(t++) = *f; + } + + *t = 0; + + return r; + +} + static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) { assert(bad); diff --git a/src/basic/escape.h b/src/basic/escape.h index 1b28bd10af..deaa4def28 100644 --- a/src/basic/escape.h +++ b/src/basic/escape.h @@ -48,6 +48,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit); char *xescape(const char *s, const char *bad); +char *octescape(const char *s, size_t len); char *shell_escape(const char *s, const char *bad); char *shell_maybe_quote(const char *s); diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 592df53cb5..d7ad8d41f2 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -25,6 +25,7 @@ #include "alloc-util.h" #include "hexdecoct.h" #include "macro.h" +#include "util.h" char octchar(int x) { return '0' + (x & 7); @@ -572,7 +573,7 @@ static int base64_append_width(char **prefix, int plen, if (!t) return -ENOMEM; - memcpy(t + plen, sep, slen); + memcpy_safe(t + plen, sep, slen); for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) { int act = MIN(width, avail); diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 3973850b44..510f018d9b 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -42,10 +42,30 @@ static nsec_t timespec_load_nsec(const struct timespec *ts); +static clockid_t map_clock_id(clockid_t c) { + + /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will + * fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is + * when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on + * those archs. */ + + switch (c) { + + case CLOCK_BOOTTIME_ALARM: + return CLOCK_BOOTTIME; + + case CLOCK_REALTIME_ALARM: + return CLOCK_REALTIME; + + default: + return c; + } +} + usec_t now(clockid_t clock_id) { struct timespec ts; - assert_se(clock_gettime(clock_id, &ts) == 0); + assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0); return timespec_load(&ts); } @@ -53,7 +73,7 @@ usec_t now(clockid_t clock_id) { nsec_t now_nsec(clockid_t clock_id) { struct timespec ts; - assert_se(clock_gettime(clock_id, &ts) == 0); + assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0); return timespec_load_nsec(&ts); } diff --git a/src/basic/util.h b/src/basic/util.h index 6f42c85a33..e095254b57 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -102,6 +102,16 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_ qsort(base, nmemb, size, compar); } +/** + * Normal memcpy requires src to be nonnull. We do nothing if n is 0. + */ +static inline void memcpy_safe(void *dst, const void *src, size_t n) { + if (n == 0) + return; + assert(src); + memcpy(dst, src, n); +} + int on_ac_power(void); #define memzero(x,l) (memset((x), 0, (l))) |