]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
Move generic util functions to shared directory
authorLucas De Marchi <lucas.demarchi@intel.com>
Fri, 3 Oct 2014 03:01:35 +0000 (00:01 -0300)
committerLucas De Marchi <lucas.demarchi@intel.com>
Fri, 3 Oct 2014 03:33:25 +0000 (00:33 -0300)
19 files changed:
Makefile.am
libkmod/libkmod-config.c
libkmod/libkmod-elf.c
libkmod/libkmod-file.c
libkmod/libkmod-hash.c
libkmod/libkmod-index.c
libkmod/libkmod-module.c
libkmod/libkmod-signature.c
libkmod/libkmod-util.c
libkmod/libkmod-util.h
libkmod/libkmod.c
shared/.gitignore [new file with mode: 0644]
shared/util.c [new file with mode: 0644]
shared/util.h [new file with mode: 0644]
testsuite/init_module.c
testsuite/test-util.c
testsuite/testsuite.c
tools/depmod.c
tools/static-nodes.c

index bc5df92bf45d31027fad3537570e8f344549121d..db05023a3b82b16ffa037669f9333486620ed2aa 100644 (file)
@@ -43,7 +43,11 @@ LIBKMOD_REVISION=8
 LIBKMOD_AGE=2
 
 noinst_LTLIBRARIES = libkmod/libkmod-util.la
-libkmod_libkmod_util_la_SOURCES = libkmod/libkmod-hash.c \
+libkmod_libkmod_util_la_SOURCES = shared/macro.h \
+                                 shared/missing.h\
+                                 shared/util.c \
+                                 shared/util.h \
+                                 libkmod/libkmod-hash.c \
                                  libkmod/libkmod-hash.h \
                                  libkmod/libkmod-array.c \
                                  libkmod/libkmod-array.h \
index 09539246cc987c00420d161d0fc44170b9ef83d3..3bbc866825ea897f34c0ff61893b98e3f1c6f217 100644 (file)
@@ -31,6 +31,8 @@
 #include <sys/types.h>
 #include <dirent.h>
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-internal.h"
 
index 53335f349434cfe08d06779591252ac4bf7ace9b..5144099d7481056442187b91537526a0f444d2a7 100644 (file)
@@ -24,6 +24,8 @@
 #include <assert.h>
 #include <errno.h>
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-internal.h"
 
index feb4a1510d495239e025e8f01954b0044f941e4b..f32ce2aa79da2569ba7c136683c9ffda2680fb38 100644 (file)
@@ -28,6 +28,8 @@
 #include <sys/mman.h>
 #include <unistd.h>
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-internal.h"
 
index eb7afb7b1bd3eac472ded8ccd7635021c6ed9617..9b4d1f18db65416194be5d377b5e571518fd32ef 100644 (file)
@@ -18,6 +18,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-hash.h"
 
index 1c64743d0fc6c9a1fcc7d39b3665dbe7dd26a15b..db431d281580c52e71c32109b88352f8414b8375 100644 (file)
@@ -28,6 +28,7 @@
 #include <inttypes.h>
 
 #include <shared/macro.h>
+#include <shared/util.h>
 
 #include "libkmod-internal.h"
 #include "libkmod-index.h"
index b81b451609b14f9dfc41c5ee2988b2d9960f2517..b22f40038ee1ed283e5fb661afb74becc79afc6b 100644 (file)
@@ -41,6 +41,8 @@
 #include <linux/module.h>
 #endif
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-internal.h"
 
index 8fe5b403fe0ba2455d4a53ae9622f844404b16b7..96712e4152ae62f5f7681e7412a7eb9a05840239 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 
 #include <shared/missing.h>
+#include <shared/util.h>
 
 #include "libkmod-internal.h"
 
index df1243306aac8f6f0633604b893efa8d2c09ed66..ea90bbb05621bcfe05a8d0a34cb00dfe8322d3fb 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <stdarg.h>
 #include <unistd.h>
-#include <errno.h>
 #include <string.h>
 #include <ctype.h>
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-internal.h"
 
-/*
- * Read one logical line from a configuration file.
- *
- * Line endings may be escaped with backslashes, to form one logical line from
- * several physical lines.  No end of line character(s) are included in the
- * result.
- *
- * If linenum is not NULL, it is incremented by the number of physical lines
- * which have been read.
- */
-char *getline_wrapped(FILE *fp, unsigned int *linenum)
-{
-       int size = 256;
-       int i = 0, n = 0;
-       _cleanup_free_ char *buf = malloc(size);
-
-       if (buf == NULL)
-               return NULL;
-
-       for(;;) {
-               int ch = getc_unlocked(fp);
-
-               switch(ch) {
-               case EOF:
-                       if (i == 0)
-                               return NULL;
-                       /* else fall through */
-
-               case '\n':
-                       n++;
-
-                       {
-                               char *ret;
-                               if (i == size) {
-                                       ret = realloc(buf, size + 1);
-                                       if (!ret)
-                                               return NULL;
-                               } else
-                                       ret = buf;
-                               ret[i] = '\0';
-                               buf = NULL;
-                               if (linenum)
-                                       *linenum += n;
-                               return ret;
-                       }
-
-               case '\\':
-                       ch = getc_unlocked(fp);
-
-                       if (ch == '\n') {
-                               n++;
-                               continue;
-                       }
-                       /* else fall through */
-
-               default:
-                       buf[i++] = ch;
-
-                       if (i == size) {
-                               char *tmp;
-                               size *= 2;
-                               tmp = realloc(buf, size);
-                               if (!tmp)
-                                       return NULL;
-                               buf = tmp;
-                       }
-               }
-       }
-}
+const struct kmod_ext kmod_exts[] = {
+       {".ko", sizeof(".ko") - 1},
+#ifdef ENABLE_ZLIB
+       {".ko.gz", sizeof(".ko.gz") - 1},
+#endif
+#ifdef ENABLE_XZ
+       {".ko.xz", sizeof(".ko.xz") - 1},
+#endif
+       { }
+};
 
 inline int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len)
 {
@@ -176,232 +117,6 @@ char *path_to_modname(const char *path, char buf[PATH_MAX], size_t *len)
        return modname_normalize(modname, buf, len);
 }
 
-inline void *memdup(const void *p, size_t n)
-{
-       void *r = malloc(n);
-
-       if (r == NULL)
-               return NULL;
-
-       return memcpy(r, p, n);
-}
-
-ssize_t read_str_safe(int fd, char *buf, size_t buflen)
-{
-       size_t todo = buflen - 1;
-       size_t done = 0;
-
-       do {
-               ssize_t r = read(fd, buf + done, todo);
-
-               if (r == 0)
-                       break;
-               else if (r > 0) {
-                       todo -= r;
-                       done += r;
-               } else {
-                       if (errno == EAGAIN || errno == EWOULDBLOCK ||
-                                                               errno == EINTR)
-                               continue;
-                       else
-                               return -errno;
-               }
-       } while (todo > 0);
-
-       buf[done] = '\0';
-       return done;
-}
-
-ssize_t write_str_safe(int fd, const char *buf, size_t buflen)
-{
-       size_t todo = buflen;
-       size_t done = 0;
-
-       do {
-               ssize_t r = write(fd, buf + done, todo);
-
-               if (r == 0)
-                       break;
-               else if (r > 0) {
-                       todo -= r;
-                       done += r;
-               } else {
-                       if (errno == EAGAIN || errno == EWOULDBLOCK ||
-                                                               errno == EINTR)
-                               continue;
-                       else
-                               return -errno;
-               }
-       } while (todo > 0);
-
-       return done;
-}
-
-int read_str_long(int fd, long *value, int base)
-{
-       char buf[32], *end;
-       long v;
-       int err;
-
-       *value = 0;
-       err = read_str_safe(fd, buf, sizeof(buf));
-       if (err < 0)
-               return err;
-       errno = 0;
-       v = strtol(buf, &end, base);
-       if (end == buf || !isspace(*end))
-               return -EINVAL;
-
-       *value = v;
-       return 0;
-}
-
-int read_str_ulong(int fd, unsigned long *value, int base)
-{
-       char buf[32], *end;
-       long v;
-       int err;
-
-       *value = 0;
-       err = read_str_safe(fd, buf, sizeof(buf));
-       if (err < 0)
-               return err;
-       errno = 0;
-       v = strtoul(buf, &end, base);
-       if (end == buf || !isspace(*end))
-               return -EINVAL;
-       *value = v;
-       return 0;
-}
-
-char *strchr_replace(char *s, int c, char r)
-{
-       char *p;
-
-       for (p = s; *p != '\0'; p++)
-               if (*p == c)
-                       *p = r;
-
-       return s;
-}
-
-bool path_is_absolute(const char *p)
-{
-       assert(p != NULL);
-
-       return p[0] == '/';
-}
-
-char *path_make_absolute_cwd(const char *p)
-{
-       _cleanup_free_ char *cwd = NULL;
-       size_t plen, cwdlen;
-       char *r;
-
-       if (path_is_absolute(p))
-               return strdup(p);
-
-       cwd = get_current_dir_name();
-       if (!cwd)
-               return NULL;
-
-       plen = strlen(p);
-       cwdlen = strlen(cwd);
-
-       /* cwd + '/' + p + '\0' */
-       r = realloc(cwd, cwdlen + 1 + plen + 1);
-       if (r == NULL)
-               return NULL;
-
-       cwd = NULL;
-       r[cwdlen] = '/';
-       memcpy(&r[cwdlen + 1], p, plen + 1);
-
-       return r;
-}
-
-static inline int is_dir(const char *path)
-{
-       struct stat st;
-
-       if (stat(path, &st) >= 0)
-               return S_ISDIR(st.st_mode);
-
-       return -errno;
-}
-
-int mkdir_p(const char *path, int len, mode_t mode)
-{
-       char *start, *end;
-
-       start = strndupa(path, len);
-       end = start + len;
-
-       /*
-        * scan backwards, replacing '/' with '\0' while the component doesn't
-        * exist
-        */
-       for (;;) {
-               int r = is_dir(start);
-               if (r > 0) {
-                       end += strlen(end);
-
-                       if (end == start + len)
-                               return 0;
-
-                       /* end != start, since it would be caught on the first
-                        * iteration */
-                       *end = '/';
-                       break;
-               } else if (r == 0)
-                       return -ENOTDIR;
-
-               if (end == start)
-                       break;
-
-               *end = '\0';
-
-               /* Find the next component, backwards, discarding extra '/'*/
-               while (end > start && *end != '/')
-                       end--;
-
-               while (end > start && *(end - 1) == '/')
-                       end--;
-       }
-
-       for (; end < start + len;) {
-               if (mkdir(start, mode) < 0 && errno != EEXIST)
-                       return -errno;
-
-               end += strlen(end);
-               *end = '/';
-       }
-
-       return 0;
-}
-
-int mkdir_parents(const char *path, mode_t mode)
-{
-       char *end = strrchr(path, '/');
-
-       /* no parent directories */
-       if (end == NULL)
-               return 0;
-
-       return mkdir_p(path, end - path, mode);
-}
-
-const struct kmod_ext kmod_exts[] = {
-       {".ko", sizeof(".ko") - 1},
-#ifdef ENABLE_ZLIB
-       {".ko.gz", sizeof(".ko.gz") - 1},
-#endif
-#ifdef ENABLE_XZ
-       {".ko.xz", sizeof(".ko.xz") - 1},
-#endif
-       { }
-};
-
 bool path_ends_with_kmod_ext(const char *path, size_t len)
 {
        const struct kmod_ext *eitr;
@@ -415,20 +130,3 @@ bool path_ends_with_kmod_ext(const char *path, size_t len)
 
        return false;
 }
-
-#define USEC_PER_SEC  1000000ULL
-#define NSEC_PER_USEC 1000ULL
-unsigned long long ts_usec(const struct timespec *ts)
-{
-       return (unsigned long long) ts->tv_sec * USEC_PER_SEC +
-              (unsigned long long) ts->tv_nsec / NSEC_PER_USEC;
-}
-
-unsigned long long stat_mstamp(const struct stat *st)
-{
-#ifdef HAVE_STRUCT_STAT_ST_MTIM
-       return ts_usec(&st->st_mtim);
-#else
-       return (unsigned long long) st->st_mtime;
-#endif
-}
index f3e9c6852273c70b1a3f0ea5e59ade22307e599e..3eb5e0ce2a608d1118f849966e4d33e1fda15418 100644 (file)
@@ -2,64 +2,18 @@
 
 #include <limits.h>
 #include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <stddef.h>
 
 #include <shared/macro.h>
 
-char *getline_wrapped(FILE *fp, unsigned int *linenum) __attribute__((nonnull(1)));
-#define streq(a, b) (strcmp((a), (b)) == 0)
-#define strstartswith(a, b) (strncmp(a, b, strlen(b)) == 0)
-void *memdup(const void *p, size_t n) __attribute__((nonnull(1)));
-
-ssize_t read_str_safe(int fd, char *buf, size_t buflen) _must_check_ __attribute__((nonnull(2)));
-ssize_t write_str_safe(int fd, const char *buf, size_t buflen) __attribute__((nonnull(2)));
-int read_str_long(int fd, long *value, int base) _must_check_ __attribute__((nonnull(2)));
-int read_str_ulong(int fd, unsigned long *value, int base) _must_check_ __attribute__((nonnull(2)));
-char *strchr_replace(char *s, int c, char r);
-bool path_is_absolute(const char *p) _must_check_ __attribute__((nonnull(1)));
-char *path_make_absolute_cwd(const char *p) _must_check_ __attribute__((nonnull(1)));
-int mkdir_p(const char *path, int len, mode_t mode);
-int mkdir_parents(const char *path, mode_t mode);
-int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len) _must_check_ __attribute__((nonnull(1,2)));
-char *modname_normalize(const char *modname, char buf[PATH_MAX], size_t *len) __attribute__((nonnull(1, 2)));
-char *path_to_modname(const char *path, char buf[PATH_MAX], size_t *len) __attribute__((nonnull(2)));
+#define KMOD_EXT_UNC 0
 
 extern const struct kmod_ext {
        const char *ext;
        size_t len;
 } kmod_exts[];
-#define KMOD_EXT_UNC 0
-bool path_ends_with_kmod_ext(const char *path, size_t len) __attribute__((nonnull(1)));
-
-unsigned long long stat_mstamp(const struct stat *st);
-unsigned long long ts_usec(const struct timespec *ts);
 
-#define get_unaligned(ptr)                     \
-({                                             \
-       struct __attribute__((packed)) {        \
-               typeof(*(ptr)) __v;             \
-       } *__p = (typeof(__p)) (ptr);           \
-       __p->__v;                               \
-})
-
-#define put_unaligned(val, ptr)                \
-do {                                           \
-       struct __attribute__((packed)) {        \
-               typeof(*(ptr)) __v;             \
-       } *__p = (typeof(__p)) (ptr);           \
-       __p->__v = (val);                       \
-} while(0)
-
-static _always_inline_ unsigned int ALIGN_POWER2(unsigned int u)
-{
-       return 1 << ((sizeof(u) * 8) - __builtin_clz(u - 1));
-}
-
-static inline void freep(void *p) {
-        free(*(void**) p);
-}
-
-#define _cleanup_free_ _cleanup_(freep)
+int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len) _must_check_ __attribute__((nonnull(1,2)));
+char *modname_normalize(const char *modname, char buf[PATH_MAX], size_t *len) __attribute__((nonnull(1, 2)));
+char *path_to_modname(const char *path, char buf[PATH_MAX], size_t *len) __attribute__((nonnull(2)));
+bool path_ends_with_kmod_ext(const char *path, size_t len) __attribute__((nonnull(1)));
index babd73fa5ea43bacfdb054a5923f79960abe33a8..89d70c3e5bf4d2646b6b991df2b334a7b3b619ae 100644 (file)
@@ -32,6 +32,8 @@
 #include <sys/utsname.h>
 #include <sys/stat.h>
 
+#include <shared/util.h>
+
 #include "libkmod.h"
 #include "libkmod-internal.h"
 #include "libkmod-index.h"
diff --git a/shared/.gitignore b/shared/.gitignore
new file mode 100644 (file)
index 0000000..088ef79
--- /dev/null
@@ -0,0 +1,5 @@
+.dirstamp
+.deps/
+.libs/
+*.la
+*.lo
diff --git a/shared/util.c b/shared/util.c
new file mode 100644 (file)
index 0000000..2d44107
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * kmod - interface to kernel module operations
+ *
+ * Copyright (C) 2011-2013  ProFUSION embedded systems
+ * Copyright (C) 2012  Lucas De Marchi <lucas.de.marchi@gmail.com>
+ * Copyright (C) 2013-2014  Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <shared/util.h>
+
+#define USEC_PER_SEC  1000000ULL
+#define NSEC_PER_USEC 1000ULL
+
+/* string handling functions and memory allocations                         */
+/* ************************************************************************ */
+
+void *memdup(const void *p, size_t n)
+{
+       void *r = malloc(n);
+
+       if (r == NULL)
+               return NULL;
+
+       return memcpy(r, p, n);
+}
+
+char *strchr_replace(char *s, int c, char r)
+{
+       char *p;
+
+       for (p = s; *p != '\0'; p++) {
+               if (*p == c)
+                       *p = r;
+       }
+
+       return s;
+}
+
+/* read-like and fread-like functions                                       */
+/* ************************************************************************ */
+ssize_t read_str_safe(int fd, char *buf, size_t buflen)
+{
+       size_t todo = buflen - 1;
+       size_t done = 0;
+
+       do {
+               ssize_t r = read(fd, buf + done, todo);
+
+               if (r == 0)
+                       break;
+               else if (r > 0) {
+                       todo -= r;
+                       done += r;
+               } else {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK ||
+                                                               errno == EINTR)
+                               continue;
+                       else
+                               return -errno;
+               }
+       } while (todo > 0);
+
+       buf[done] = '\0';
+       return done;
+}
+
+ssize_t write_str_safe(int fd, const char *buf, size_t buflen)
+{
+       size_t todo = buflen;
+       size_t done = 0;
+
+       do {
+               ssize_t r = write(fd, buf + done, todo);
+
+               if (r == 0)
+                       break;
+               else if (r > 0) {
+                       todo -= r;
+                       done += r;
+               } else {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK ||
+                                                               errno == EINTR)
+                               continue;
+                       else
+                               return -errno;
+               }
+       } while (todo > 0);
+
+       return done;
+}
+
+int read_str_long(int fd, long *value, int base)
+{
+       char buf[32], *end;
+       long v;
+       int err;
+
+       *value = 0;
+       err = read_str_safe(fd, buf, sizeof(buf));
+       if (err < 0)
+               return err;
+       errno = 0;
+       v = strtol(buf, &end, base);
+       if (end == buf || !isspace(*end))
+               return -EINVAL;
+
+       *value = v;
+       return 0;
+}
+
+int read_str_ulong(int fd, unsigned long *value, int base)
+{
+       char buf[32], *end;
+       long v;
+       int err;
+
+       *value = 0;
+       err = read_str_safe(fd, buf, sizeof(buf));
+       if (err < 0)
+               return err;
+       errno = 0;
+       v = strtoul(buf, &end, base);
+       if (end == buf || !isspace(*end))
+               return -EINVAL;
+       *value = v;
+       return 0;
+}
+
+/*
+ * Read one logical line from a configuration file.
+ *
+ * Line endings may be escaped with backslashes, to form one logical line from
+ * several physical lines.  No end of line character(s) are included in the
+ * result.
+ *
+ * If linenum is not NULL, it is incremented by the number of physical lines
+ * which have been read.
+ */
+char *getline_wrapped(FILE *fp, unsigned int *linenum)
+{
+       int size = 256;
+       int i = 0, n = 0;
+       _cleanup_free_ char *buf = malloc(size);
+
+       if (buf == NULL)
+               return NULL;
+
+       for(;;) {
+               int ch = getc_unlocked(fp);
+
+               switch(ch) {
+               case EOF:
+                       if (i == 0)
+                               return NULL;
+                       /* else fall through */
+
+               case '\n':
+                       n++;
+
+                       {
+                               char *ret;
+                               if (i == size) {
+                                       ret = realloc(buf, size + 1);
+                                       if (!ret)
+                                               return NULL;
+                               } else
+                                       ret = buf;
+                               ret[i] = '\0';
+                               buf = NULL;
+                               if (linenum)
+                                       *linenum += n;
+                               return ret;
+                       }
+
+               case '\\':
+                       ch = getc_unlocked(fp);
+
+                       if (ch == '\n') {
+                               n++;
+                               continue;
+                       }
+                       /* else fall through */
+
+               default:
+                       buf[i++] = ch;
+
+                       if (i == size) {
+                               char *tmp;
+                               size *= 2;
+                               tmp = realloc(buf, size);
+                               if (!tmp)
+                                       return NULL;
+                               buf = tmp;
+                       }
+               }
+       }
+}
+
+/* path handling functions                                                  */
+/* ************************************************************************ */
+
+bool path_is_absolute(const char *p)
+{
+       assert(p != NULL);
+
+       return p[0] == '/';
+}
+
+char *path_make_absolute_cwd(const char *p)
+{
+       _cleanup_free_ char *cwd = NULL;
+       size_t plen, cwdlen;
+       char *r;
+
+       if (path_is_absolute(p))
+               return strdup(p);
+
+       cwd = get_current_dir_name();
+       if (!cwd)
+               return NULL;
+
+       plen = strlen(p);
+       cwdlen = strlen(cwd);
+
+       /* cwd + '/' + p + '\0' */
+       r = realloc(cwd, cwdlen + 1 + plen + 1);
+       if (r == NULL)
+               return NULL;
+
+       cwd = NULL;
+       r[cwdlen] = '/';
+       memcpy(&r[cwdlen + 1], p, plen + 1);
+
+       return r;
+}
+
+static inline int is_dir(const char *path)
+{
+       struct stat st;
+
+       if (stat(path, &st) >= 0)
+               return S_ISDIR(st.st_mode);
+
+       return -errno;
+}
+
+int mkdir_p(const char *path, int len, mode_t mode)
+{
+       char *start, *end;
+
+       start = strndupa(path, len);
+       end = start + len;
+
+       /*
+        * scan backwards, replacing '/' with '\0' while the component doesn't
+        * exist
+        */
+       for (;;) {
+               int r = is_dir(start);
+               if (r > 0) {
+                       end += strlen(end);
+
+                       if (end == start + len)
+                               return 0;
+
+                       /* end != start, since it would be caught on the first
+                        * iteration */
+                       *end = '/';
+                       break;
+               } else if (r == 0)
+                       return -ENOTDIR;
+
+               if (end == start)
+                       break;
+
+               *end = '\0';
+
+               /* Find the next component, backwards, discarding extra '/'*/
+               while (end > start && *end != '/')
+                       end--;
+
+               while (end > start && *(end - 1) == '/')
+                       end--;
+       }
+
+       for (; end < start + len;) {
+               if (mkdir(start, mode) < 0 && errno != EEXIST)
+                       return -errno;
+
+               end += strlen(end);
+               *end = '/';
+       }
+
+       return 0;
+}
+
+int mkdir_parents(const char *path, mode_t mode)
+{
+       char *end = strrchr(path, '/');
+
+       /* no parent directories */
+       if (end == NULL)
+               return 0;
+
+       return mkdir_p(path, end - path, mode);
+}
+
+unsigned long long ts_usec(const struct timespec *ts)
+{
+       return (unsigned long long) ts->tv_sec * USEC_PER_SEC +
+              (unsigned long long) ts->tv_nsec / NSEC_PER_USEC;
+}
+
+unsigned long long stat_mstamp(const struct stat *st)
+{
+#ifdef HAVE_STRUCT_STAT_ST_MTIM
+       return ts_usec(&st->st_mtim);
+#else
+       return (unsigned long long) st->st_mtime;
+#endif
+}
diff --git a/shared/util.h b/shared/util.h
new file mode 100644 (file)
index 0000000..1ed7214
--- /dev/null
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <limits.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <shared/macro.h>
+
+/* string handling functions and memory allocations                         */
+/* ************************************************************************ */
+#define streq(a, b) (strcmp((a), (b)) == 0)
+#define strstartswith(a, b) (strncmp(a, b, strlen(b)) == 0)
+char *strchr_replace(char *s, int c, char r);
+void *memdup(const void *p, size_t n) __attribute__((nonnull(1)));
+
+/* read-like and fread-like functions                                       */
+/* ************************************************************************ */
+ssize_t read_str_safe(int fd, char *buf, size_t buflen) _must_check_ __attribute__((nonnull(2)));
+ssize_t write_str_safe(int fd, const char *buf, size_t buflen) __attribute__((nonnull(2)));
+int read_str_long(int fd, long *value, int base) _must_check_ __attribute__((nonnull(2)));
+int read_str_ulong(int fd, unsigned long *value, int base) _must_check_ __attribute__((nonnull(2)));
+char *getline_wrapped(FILE *fp, unsigned int *linenum) __attribute__((nonnull(1)));
+
+/* path handling functions                                                  */
+/* ************************************************************************ */
+bool path_is_absolute(const char *p) _must_check_ __attribute__((nonnull(1)));
+char *path_make_absolute_cwd(const char *p) _must_check_ __attribute__((nonnull(1)));
+int mkdir_p(const char *path, int len, mode_t mode);
+int mkdir_parents(const char *path, mode_t mode);
+unsigned long long stat_mstamp(const struct stat *st);
+unsigned long long ts_usec(const struct timespec *ts);
+
+/* endianess and alignments                                                 */
+/* ************************************************************************ */
+#define get_unaligned(ptr)                     \
+({                                             \
+       struct __attribute__((packed)) {        \
+               typeof(*(ptr)) __v;             \
+       } *__p = (typeof(__p)) (ptr);           \
+       __p->__v;                               \
+})
+
+#define put_unaligned(val, ptr)                        \
+do {                                           \
+       struct __attribute__((packed)) {        \
+               typeof(*(ptr)) __v;             \
+       } *__p = (typeof(__p)) (ptr);           \
+       __p->__v = (val);                       \
+} while(0)
+
+static _always_inline_ unsigned int ALIGN_POWER2(unsigned int u)
+{
+       return 1 << ((sizeof(u) * 8) - __builtin_clz(u - 1));
+}
+
+/* misc                                                                     */
+/* ************************************************************************ */
+static inline void freep(void *p) {
+        free(*(void**) p);
+}
+#define _cleanup_free_ _cleanup_(freep)
index 269a47115bad45b629befa8b5dacddce53c1f892..edbba0795a9c21c5d1f14a412c057143302c1274 100644 (file)
@@ -40,6 +40,8 @@
 #include <sys/utsname.h>
 #include <unistd.h>
 
+#include <shared/util.h>
+
 /* kmod_elf_get_section() is not exported, we need the private header */
 #include <libkmod-internal.h>
 
index 4fedb246630936d89497ec1a0e5cb60162271843..8b6474bc7feb69fa283c8275722418e0d0dbdce2 100644 (file)
@@ -22,6 +22,8 @@
 #include <string.h>
 #include <libkmod.h>
 
+#include <shared/util.h>
+
 #include "libkmod-util.h"
 #include "testsuite.h"
 
index 9330e887e1e41af20a452d0ac6cc4968417ce389..54b662b45a4643cae23d876c2e26f38891c83abb 100644 (file)
@@ -32,6 +32,8 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 
+#include <shared/util.h>
+
 #include "libkmod-util.h"
 #include "testsuite.h"
 
index 41cad0b52409e5265e97c0fec79e2867f70e3a34..274d020aae931b1b0b15f16bb0c9c5632174f855 100644 (file)
@@ -22,6 +22,7 @@
 #include "libkmod-util.h"
 
 #include <shared/macro.h>
+#include <shared/util.h>
 
 #include <stdio.h>
 #include <stdlib.h>
index 019539090d232b4b7c55a6e8cdebcaee089475ef..b7ea23274c0f2d23c280c1c184acab1cb0bc16f5 100644 (file)
@@ -30,7 +30,8 @@
 #include <sys/utsname.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include "libkmod-util.h"
+
+#include <shared/util.h>
 
 #include "kmod.h"