diff options
-rw-r--r-- | UPSTREAM.notes | 9 | ||||
-rw-r--r-- | src/libudev/missing.h | 2 | ||||
-rw-r--r-- | src/libudev/util.c | 107 | ||||
-rw-r--r-- | src/libudev/util.h | 1 | ||||
-rw-r--r-- | src/udev/label.c | 2 | ||||
-rw-r--r-- | src/udev/mkdir.c | 72 |
6 files changed, 148 insertions, 45 deletions
diff --git a/UPSTREAM.notes b/UPSTREAM.notes index f95149833e..12c1359393 100644 --- a/UPSTREAM.notes +++ b/UPSTREAM.notes @@ -8,3 +8,12 @@ commit edeb68c53f1cdc452016b4c8512586a70b1262e3. Upstream has moved this functionality to systemd-tmpfilesd since kmod v14 now exports static node info in tmpfiles.d format. We wish to retain this functionality in udevd. + +2013-07-10 + + * Add "hwdb: allow list of lookup keys per given record" + * Bring src/udev/mkdir.c in line with upstreams use of *_internal() with prefix + * Import format_timespan() from upstream's src/shared/time-util.c. Note: our + src/libudev/util.c is derived from upstream's src/shared/util.c minus unneeded functions + plus three functions from src/shared/time-util.c: now(), timespec_load() and + timespan(). diff --git a/src/libudev/missing.h b/src/libudev/missing.h index aa578d1fe0..a2ca518948 100644 --- a/src/libudev/missing.h +++ b/src/libudev/missing.h @@ -139,7 +139,7 @@ static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask, int dfd, const char *pathname) { #if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ \ - || defined __arm__ && !defined __aarch64__ + || defined __arm__ && !defined __aarch64__ union { uint64_t _64; uint32_t _32[2]; diff --git a/src/libudev/util.c b/src/libudev/util.c index e447f89647..f625cfe99b 100644 --- a/src/libudev/util.c +++ b/src/libudev/util.c @@ -127,6 +127,113 @@ usec_t timespec_load(const struct timespec *ts) { (usec_t) ts->tv_nsec / NSEC_PER_USEC; } +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "y", USEC_PER_YEAR }, + { "month", USEC_PER_MONTH }, + { "w", USEC_PER_WEEK }, + { "d", USEC_PER_DAY }, + { "h", USEC_PER_HOUR }, + { "min", USEC_PER_MINUTE }, + { "s", USEC_PER_SEC }, + { "ms", USEC_PER_MSEC }, + { "us", 1 }, + }; + + unsigned i; + char *p = buf; + bool something = false; + + assert(buf); + assert(l > 0); + + if (t == (usec_t) -1) + return NULL; + + if (t <= 0) { + snprintf(p, l, "0"); + p[l-1] = 0; + return p; + } + + /* The result of this function can be parsed with parse_sec */ + + for (i = 0; i < ELEMENTSOF(table); i++) { + int k; + size_t n; + bool done = false; + usec_t a, b; + + if (t <= 0) + break; + + if (t < accuracy && something) + break; + + if (t < table[i].usec) + continue; + + if (l <= 1) + break; + + a = t / table[i].usec; + b = t % table[i].usec; + + /* Let's see if we should shows this in dot notation */ + if (t < USEC_PER_MINUTE && b > 0) { + usec_t cc; + int j; + + j = 0; + for (cc = table[i].usec; cc > 1; cc /= 10) + j++; + + for (cc = accuracy; cc > 1; cc /= 10) { + b /= 10; + j--; + } + + if (j > 0) { + k = snprintf(p, l, + "%s%llu.%0*llu%s", + p > buf ? " " : "", + (unsigned long long) a, + j, + (unsigned long long) b, + table[i].suffix); + + t = 0; + done = true; + } + } + + /* No? Then let's show it normally */ + if (!done) { + k = snprintf(p, l, + "%s%llu%s", + p > buf ? " " : "", + (unsigned long long) a, + table[i].suffix); + + t = b; + } + + n = MIN((size_t) k, l); + + l -= n; + p += n; + + something = true; + } + + *p = 0; + + return buf; +} + char* endswith(const char *s, const char *postfix) { size_t sl, pl; diff --git a/src/libudev/util.h b/src/libudev/util.h index 2ac6f59c49..60b300da3c 100644 --- a/src/libudev/util.h +++ b/src/libudev/util.h @@ -84,6 +84,7 @@ union dirent_storage { usec_t now(clockid_t clock); usec_t timespec_load(const struct timespec *ts); +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); size_t page_size(void); #define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) diff --git a/src/udev/label.c b/src/udev/label.c index 1ab40f4bba..1e4d01113a 100644 --- a/src/udev/label.c +++ b/src/udev/label.c @@ -85,7 +85,7 @@ int label_init(const char *prefix) { l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0; log_debug("Successfully loaded SELinux database in %s, size on heap is %iK.", - format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp), + format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp, 0), (l+1023)/1024); } #endif diff --git a/src/udev/mkdir.c b/src/udev/mkdir.c index b9920ec207..c775bfa0c3 100644 --- a/src/udev/mkdir.c +++ b/src/udev/mkdir.c @@ -26,54 +26,47 @@ #include <stdlib.h> #include <stdio.h> -#include "mkdir.h" #include "label.h" #include "util.h" +#include "mkdir.h" -static int makedir_safe(const char *path, mode_t mode, uid_t uid, gid_t gid, bool apply) { +static int is_dir(const char* path) { struct stat st; - if (label_mkdir(path, mode, apply) >= 0) - if (chmod_and_chown(path, mode, uid, gid) < 0) - return -errno; - - if (lstat(path, &st) < 0) - return -errno; - - if ((st.st_mode & 0777) != mode || - st.st_uid != uid || - st.st_gid != gid || - !S_ISDIR(st.st_mode)) { - errno = EEXIST; + if (stat(path, &st) < 0) return -errno; - } - return 0; + return S_ISDIR(st.st_mode); } -static int makedir_parents(const char *path, mode_t mode, bool apply) { - struct stat st; +static int mkdir_parents_internal(const char *prefix, const char *path, mode_t mode, bool apply) { const char *p, *e; + int r; assert(path); + if (prefix && !path_startswith(path, prefix)) + return -ENOTDIR; + /* return immediately if directory exists */ e = strrchr(path, '/'); if (!e) return -EINVAL; + + if (e == path) + return 0; + p = strndupa(path, e - path); - if (stat(p, &st) >= 0) { - if ((st.st_mode & S_IFMT) == S_IFDIR) - return 0; - else - return -ENOTDIR; - } + r = is_dir(p); + if (r > 0) + return 0; + if (r == 0) + return -ENOTDIR; /* create every parent directory in the path, except the last component */ p = path + strspn(path, "/"); for (;;) { - int r; - char *t; + char t[strlen(path) + 1]; e = p + strcspn(p, "/"); p = e + strspn(e, "/"); @@ -83,39 +76,32 @@ static int makedir_parents(const char *path, mode_t mode, bool apply) { if (*p == 0) return 0; - t = strndup(path, e - path); - if (!t) - return -ENOMEM; + memcpy(t, path, e - path); + t[e-path] = 0; - r = label_mkdir(t, mode, apply); - free(t); + if (prefix && path_startswith(prefix, t)) + continue; + r = label_mkdir(t, mode, apply); if (r < 0 && errno != EEXIST) return -errno; } } int mkdir_parents(const char *path, mode_t mode) { - return makedir_parents(path, mode, false); + return mkdir_parents_internal(NULL, path, mode, false); } int mkdir_parents_label(const char *path, mode_t mode) { - return makedir_parents(path, mode, true); -} - -static int is_dir(const char* path) { - struct stat st; - if (stat(path, &st) < 0) - return -errno; - return S_ISDIR(st.st_mode); + return mkdir_parents_internal(NULL, path, mode, true); } -static int makedir_p(const char *path, mode_t mode, bool apply) { +static int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, bool apply) { int r; /* Like mkdir -p */ - r = makedir_parents(path, mode, apply); + r = mkdir_parents_internal(prefix, path, mode, apply); if (r < 0) return r; @@ -127,5 +113,5 @@ static int makedir_p(const char *path, mode_t mode, bool apply) { } int mkdir_p(const char *path, mode_t mode) { - return makedir_p(path, mode, false); + return mkdir_p_internal(NULL, path, mode, false); } |