[1/3] util: Add rmdirp helper

Submitted by Cyrill Gorcunov on Nov. 22, 2016, 4:13 p.m.

Details

Message ID 1479831214-19760-2-git-send-email-gorcunov@virtuozzo.com
State Superseded
Series "sk-unix: Handle case when socket is deleted together with parent dir"
Headers show

Commit Message

Cyrill Gorcunov Nov. 22, 2016, 4:13 p.m.
To remove series of dentries.

Signed-off-by: Cyrill Gorcunov <gorcunov@virtuozzo.com>
---
 criu/include/util.h |  2 ++
 criu/util.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/include/util.h b/criu/include/util.h
index b5e6f7b..1374fa1 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -254,6 +254,8 @@  int mkdirpat(int fd, const char *path, int mode);
  */
 int mkdirname(const char *path);
 
+int rmdirp(const char *path, size_t keep);
+
 /*
  * Tests whether a path is a prefix of another path. This is different than
  * strstartswith because "/foo" is _not_ a path prefix of "/foobar", since they
diff --git a/criu/util.c b/criu/util.c
index 6ce2007..312f76a 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -848,6 +848,46 @@  int mkdirpat(int fd, const char *path, int mode)
 	return 0;
 }
 
+/*
+ * Remove directory @path together with parents,
+ * keeping @keep len of path if provided. Directories
+ * must be empty of course.
+ */
+int rmdirp(const char *path, size_t keep)
+{
+	char made_path[PATH_MAX], *pos;
+	size_t len = strlen(path);
+	int ret;
+
+	if (len >= PATH_MAX) {
+		pr_err("path %s is longer than PATH_MAX\n", path);
+		return -ENOSPC;
+	}
+
+	/* Nothing to do */
+	if (len <= keep)
+		return 0;
+
+	strcpy(made_path, path);
+
+	for (pos = strrchr(made_path, '/');
+	     pos && (pos - made_path) >= keep;
+	     pos = strrchr(made_path, '/')) {
+		ret = rmdir(made_path);
+
+		if (ret < 0 && errno != ENOENT) {
+			ret = -errno;
+			pr_perror("Can't delete %s", made_path);
+			goto out;
+		}
+		*pos = '\0';
+	}
+
+	ret = 0;
+out:
+	return ret;
+}
+
 int mkdirname(const char *path)
 {
 	int err;