From a0bc980bab7953fe4ddd573870c9c2bdd8c00147 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 13 May 2019 18:38:22 +0200 Subject: [PATCH 1/2] ignore ENOENT errors up until the last element while trying to create each of the path elements in case a restricted file-system is being used where path elements can be hidden or non-accessible. --- glib/gfileutils.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/glib/gfileutils.c b/glib/gfileutils.c index 676c08c21a..8bff0e9c57 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -248,9 +248,12 @@ g_mkdir_with_parents (const gchar *pathname, if (g_mkdir (fn, mode) == -1 && errno != EEXIST) { int errno_save = errno; - g_free (fn); - errno = errno_save; - return -1; + if (p && errno != ENOENT) + { + g_free (fn); + errno = errno_save; + return -1; + } } } else if (!g_file_test (fn, G_FILE_TEST_IS_DIR)) -- GitLab From d783d5a8f633768922e755106fc8e65825b46380 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 13 May 2019 18:36:55 +0200 Subject: [PATCH 2/2] try to create the complete path right away and fall back to creating all path elements one by one. this also helps to avoid TOCTOU problems and avoids walking the path all the time, providing a nice performance gain, by avoiding syscalls. --- glib/gfileutils.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/glib/gfileutils.c b/glib/gfileutils.c index 8bff0e9c57..16ee663844 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -226,6 +226,20 @@ g_mkdir_with_parents (const gchar *pathname, return -1; } + /* try to create the full path first */ + if (g_mkdir (pathname, mode) == 0) + return 0; + else if (errno == EEXIST) + { + if (!g_file_test (pathname, G_FILE_TEST_IS_DIR)) + { + errno = ENOTDIR; + return -1; + } + return 0; + } + + /* walk the full path and try creating each element */ fn = g_strdup (pathname); if (g_path_is_absolute (fn)) -- GitLab