summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src')
-rw-r--r--libglusterfs/src/common-utils.c62
-rw-r--r--libglusterfs/src/common-utils.h2
2 files changed, 64 insertions, 0 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 7e7eb461409..4b8807be1eb 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -58,6 +58,68 @@ struct dnscache6 {
};
+/* works similar to mkdir(1) -p.
+ * @start returns the point in path from which components were created
+ * @start is -1 if the entire path existed before.
+ */
+int
+mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks, int *start)
+{
+ int i = 0;
+ int ret = -1;
+ char dir[PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+ int created = -1;
+
+ strcpy (dir, path);
+ i = (dir[0] == '/')? 1: 0;
+ do {
+ if (path[i] != '/' && path[i] != '\0')
+ continue;
+
+ dir[i] = '\0';
+ ret = mkdir (dir, mode);
+ if (ret && errno != EEXIST) {
+ gf_log ("", GF_LOG_ERROR, "Failed due to reason %s",
+ strerror (errno));
+ goto out;
+ }
+
+ if (ret && errno == EEXIST)
+ created = i;
+
+ if (ret && errno == EEXIST && !allow_symlinks) {
+ ret = lstat (dir, &stbuf);
+ if (ret)
+ goto out;
+
+ if (S_ISLNK (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "%s is a symlink",
+ dir);
+ goto out;
+ }
+ }
+ dir[i] = '/';
+
+ } while (path[i++] != '\0');
+
+ ret = stat (dir, &stbuf);
+ if (ret || !S_ISDIR (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Failed to create directory, "
+ "possibly some of the components were not directories");
+ goto out;
+ }
+
+ ret = 0;
+ if (start)
+ *start = created;
+out:
+
+ return ret;
+}
+
int
log_base2 (unsigned long x)
{
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index d5880291250..69d57c8d431 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -392,6 +392,8 @@ memdup (const void *ptr, size_t size)
return newptr;
}
+int
+mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks, int *start);
/*
* rounds up nr to power of two. If nr is already a power of two, just returns
* nr