aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/lib.c27
-rw-r--r--lib/lib.h1
2 files changed, 28 insertions, 0 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 985c580d..6699a685 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -322,6 +322,33 @@ char *xabspath(char *path)
return path;
}
+// Ensure entire path exists.
+// If mode != -1 set permissions on newly created dirs.
+// Requires that path string be writable (for temporary null terminators).
+void xmkpath(char *path, int mode)
+{
+ char *p, old;
+ mode_t mask;
+ int rc;
+ struct stat st;
+
+ for (p = path; ; p++) {
+ if (!*p || *p == '/') {
+ old = *p;
+ *p = rc = 0;
+ if (stat(path, &st) || !S_ISDIR(st.st_mode)) {
+ if (mode != -1) {
+ mask=umask(0);
+ rc = mkdir(path, mode);
+ umask(mask);
+ } else rc = mkdir(path, 0777);
+ }
+ *p = old;
+ if(rc) perror_exit("mkpath '%s'",path);
+ }
+ if (!*p) break;
+ }
+}
// Find all file in a colon-separated path with access type "type" (generally
// X_OK or R_OK). Returns a list of absolute paths to each file found, in
// order.
diff --git a/lib/lib.h b/lib/lib.h
index 28ff0da8..afc3a8b2 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -73,6 +73,7 @@ void xwrite(int fd, void *buf, size_t len);
char *xgetcwd(void);
void xstat(char *path, struct stat *st);
char *xabspath(char *path);
+void xmkpath(char *path, int mode);
struct string_list *find_in_path(char *path, char *filename);
void utoa_to_buf(unsigned n, char *buf, unsigned buflen);
void itoa_to_buf(int n, char *buf, unsigned buflen);