X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=9a45e6058e200813fed1bae7ff9d27f0ebb164a5;hp=2f0aba88ae6e1c443f54b1d821ed25d73649a069;hb=49371bb50e0fe6e9e90309a20006bcfd9e2fa8f4;hpb=a9e12476ed32256690eb801099c41526834b6390 diff --git a/src/shared/util.c b/src/shared/util.c index 2f0aba88a..9a45e6058 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -148,6 +148,10 @@ usec_t timespec_load(const struct timespec *ts) { ts->tv_nsec == (long) -1) return (usec_t) -1; + if (ts->tv_sec > 0 && + USEC_PER_SEC > ((UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / (usec_t) ts->tv_sec)) + return (usec_t) -1; + return (usec_t) ts->tv_sec * USEC_PER_SEC + (usec_t) ts->tv_nsec / NSEC_PER_USEC; @@ -175,6 +179,9 @@ usec_t timeval_load(const struct timeval *tv) { tv->tv_usec == (suseconds_t) -1) return (usec_t) -1; + if (USEC_PER_SEC > (UINT64_MAX - tv->tv_usec) / (usec_t) tv->tv_sec) + return (usec_t) -1; + return (usec_t) tv->tv_sec * USEC_PER_SEC + (usec_t) tv->tv_usec; @@ -216,45 +223,38 @@ char* endswith(const char *s, const char *postfix) { return (char*) s + sl - pl; } -bool startswith(const char *s, const char *prefix) { - size_t sl, pl; +char* startswith(const char *s, const char *prefix) { + const char *a, *b; assert(s); assert(prefix); - sl = strlen(s); - pl = strlen(prefix); - - if (pl == 0) - return true; - - if (sl < pl) - return false; + a = s, b = prefix; + for (;;) { + if (*b == 0) + return (char*) a; + if (*a != *b) + return NULL; - return memcmp(s, prefix, pl) == 0; + a++, b++; + } } -bool startswith_no_case(const char *s, const char *prefix) { - size_t sl, pl; - unsigned i; +char* startswith_no_case(const char *s, const char *prefix) { + const char *a, *b; assert(s); assert(prefix); - sl = strlen(s); - pl = strlen(prefix); - - if (pl == 0) - return true; - - if (sl < pl) - return false; - - for(i = 0; i < pl; ++i) - if (tolower(s[i]) != tolower(prefix[i])) - return false; + a = s, b = prefix; + for (;;) { + if (*b == 0) + return (char*) a; + if (tolower(*a) != tolower(*b)) + return NULL; - return true; + a++, b++; + } } bool first_word(const char *s, const char *word) { @@ -5698,6 +5698,30 @@ int can_sleep(const char *type) { return false; } +int can_sleep_disk(const char *type) { + char *w, *state; + size_t l, k; + int r; + _cleanup_free_ char *p = NULL; + + assert(type); + + r = read_one_line_file("/sys/power/disk", &p); + if (r < 0) + return r == -ENOENT ? 0 : r; + + k = strlen(type); + FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state) { + if (l == k && memcmp(w, type, l) == 0) + return true; + + if (l == k + 2 && w[0] == '[' && memcmp(w + 1, type, l - 2) == 0 && w[l-1] == ']') + return true; + } + + return false; +} + bool is_valid_documentation_url(const char *url) { assert(url); @@ -6072,8 +6096,7 @@ finish: /* hey glibc, APIs with callbacks without a user pointer are so useless */ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar) (const void *, const void *, void *), - void *arg) { + int (*compar) (const void *, const void *, void *), void *arg) { size_t l, u, idx; const void *p; int comparison;