diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/common-utils.c | 62 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 2 | 
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  | 
