[CRIU] [PATCH 1/4] util: Add mkdirpat_precise helper
Cyrill Gorcunov
gorcunov at gmail.com
Wed Feb 27 16:34:22 MSK 2019
To know where new dirents are created.
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
criu/include/util.h | 6 +++++-
criu/util.c | 41 +++++++++++++++++++++++++++--------------
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/criu/include/util.h b/criu/include/util.h
index 57192c5f273d..694b5358cf68 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -253,7 +253,11 @@ static inline bool issubpath(const char *path, const char *sub_path)
/*
* mkdir -p
*/
-int mkdirpat(int fd, const char *path, int mode);
+int mkdirpat_precise(int fd, const char *path, int mode, const char **new);
+static inline int mkdirpat(int fd, const char *path, int mode)
+{
+ return mkdirpat_precise(fd, path, mode, NULL);
+}
/*
* Tests whether a path is a prefix of another path. This is different than
diff --git a/criu/util.c b/criu/util.c
index 1cc4ecd4427e..fd9bd78326b5 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1001,38 +1001,51 @@ struct vma_area *alloc_vma_area(void)
return p;
}
-int mkdirpat(int fd, const char *path, int mode)
+/*
+ * Make the whole @path to the specified directory, report
+ * the position of newly created directories via @new.
+ */
+int mkdirpat_precise(int fd, const char *path, int mode, const char **new)
{
- size_t i;
- char made_path[PATH_MAX], *pos;
+ char made_path[PATH_MAX];
+ char *pos = made_path, *end;
+ const char *where = path;
if (strlen(path) >= PATH_MAX) {
pr_err("path %s is longer than PATH_MAX\n", path);
return -ENOSPC;
}
- strcpy(made_path, path);
+ strcpy(pos, path);
- i = 0;
- if (made_path[0] == '/')
- i++;
+ end = pos + strlen(path);
+ if (pos[0] == '/')
+ pos++;
- for (; i < strlen(made_path); i++) {
- pos = strchr(made_path + i, '/');
+ for (; pos < end; pos++) {
+ pos = strchr(pos, '/');
if (pos)
*pos = '\0';
- if (mkdirat(fd, made_path, mode) < 0 && errno != EEXIST) {
- int ret = -errno;
- pr_perror("couldn't mkdirpat directory %s", made_path);
- return ret;
+ if (mkdirat(fd, made_path, mode) < 0) {
+ if (errno == EEXIST) {
+ where = path;
+ } else {
+ int ret = -errno;
+ pr_perror("couldn't mkdirpat directory %s", made_path);
+ return ret;
+ }
}
if (pos) {
*pos = '/';
- i = pos - made_path;
+ if (where == path)
+ where = &path[pos - made_path + 1];
} else
break;
}
+ if (new)
+ *new = where;
+
return 0;
}
--
2.20.1
More information about the CRIU
mailing list