aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.demarchi@intel.com>2013-07-15 01:41:19 -0300
committerLucas De Marchi <lucas.demarchi@intel.com>2013-07-15 12:44:33 -0300
commit85d02ebea38a782a23c4af65619d253dc08f8a26 (patch)
tree4538377dc0096d964a7119bd3d9b7bca2bef3414
parent7980eaf0ec0ffd47e2af79f647f5eed1d22f5e32 (diff)
downloadkmod-85d02ebea38a782a23c4af65619d253dc08f8a26.tar.gz
util: Add mkdir_p implementation from testsuite
-rw-r--r--Makefile.am1
-rw-r--r--libkmod/libkmod-util.c61
-rw-r--r--libkmod/libkmod-util.h1
-rw-r--r--testsuite/init_module.c1
-rw-r--r--testsuite/mkdir.c83
-rw-r--r--testsuite/mkdir.h24
6 files changed, 62 insertions, 109 deletions
diff --git a/Makefile.am b/Makefile.am
index 0ed944c..57b7372 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,7 +154,6 @@ testsuite_path_la_LDFLAGS = $(TESTSUITE_OVERRIDE_LIBS_LDFLAGS)
testsuite_delete_module_la_LDFLAGS = $(TESTSUITE_OVERRIDE_LIBS_LDFLAGS)
testsuite_init_module_la_LDFLAGS = $(TESTSUITE_OVERRIDE_LIBS_LDFLAGS)
testsuite_init_module_la_SOURCES = testsuite/init_module.c \
- testsuite/mkdir.c testsuite/mkdir.h \
testsuite/stripped-module.h
testsuite_init_module_la_LIBADD = libkmod/libkmod-internal.la
diff --git a/libkmod/libkmod-util.c b/libkmod/libkmod-util.c
index e636ae1..43d8b02 100644
--- a/libkmod/libkmod-util.c
+++ b/libkmod/libkmod-util.c
@@ -2,6 +2,8 @@
* libkmod - 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 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
@@ -308,6 +310,65 @@ char *path_make_absolute_cwd(const char *p)
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, mode_t mode)
+{
+ char *start = strdupa(path);
+ int len = strlen(path);
+ char *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;
+}
+
const struct kmod_ext kmod_exts[] = {
{".ko", sizeof(".ko") - 1},
#ifdef ENABLE_ZLIB
diff --git a/libkmod/libkmod-util.h b/libkmod/libkmod-util.h
index 17f8801..83c975c 100644
--- a/libkmod/libkmod-util.h
+++ b/libkmod/libkmod-util.h
@@ -20,6 +20,7 @@ int read_str_ulong(int fd, unsigned long *value, int base) _must_check_ __attrib
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, 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)));
diff --git a/testsuite/init_module.c b/testsuite/init_module.c
index 686f671..ebf1b94 100644
--- a/testsuite/init_module.c
+++ b/testsuite/init_module.c
@@ -44,7 +44,6 @@
/* FIXME: hack, change name so we don't clash */
#undef ERR
-#include "mkdir.h"
#include "testsuite.h"
#include "stripped-module.h"
diff --git a/testsuite/mkdir.c b/testsuite/mkdir.c
deleted file mode 100644
index f692c5a..0000000
--- a/testsuite/mkdir.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com
- * This program 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 program 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 <errno.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "mkdir.h"
-#include "testsuite.h"
-
-static inline int is_dir(const char *path)
-{
- struct stat st;
-
- if (stat(path, &st) >= 0)
- return S_ISDIR(st.st_mode);
-
- return -errno;
-}
-
-TS_EXPORT int mkdir_p(const char *path, mode_t mode)
-{
- char *start = strdupa(path);
- int len = strlen(path);
- char *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;
-}
diff --git a/testsuite/mkdir.h b/testsuite/mkdir.h
deleted file mode 100644
index 35f6a1d..0000000
--- a/testsuite/mkdir.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com>
- *
- * This program 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 program 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
- */
-
-#pragma once
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-int mkdir_p(const char *path, mode_t mode);