Thread (7 messages) 7 messages, 2 authors, 2013-07-15

Re: [PATCH 1/6] testsuite: Fix mkdir_p corner cases

From: Tom Gundersen <hidden>
Date: 2013-07-15 15:19:51

Hi Lucas,

Thanks for picking this up.

All the patches look good to me, and "kmod static-nodes" now works as expected.

Cheers,

Tom

On Mon, Jul 15, 2013 at 7:12 AM, Lucas De Marchi
[off-list ref] wrote:
quoted hunk ↗ jump to hunk
From: Lucas De Marchi <redacted>

 - Fix infinite loop when path is relative
 - Fix not considering EEXIST as a success
 - General refactor to mkdir_p so it never calls mkdir for an existing
   dir (given no creates it from outside)
---
 testsuite/mkdir.c | 54 +++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 19 deletions(-)
diff --git a/testsuite/mkdir.c b/testsuite/mkdir.c
index 0a7de69..be2e37b 100644
--- a/testsuite/mkdir.c
+++ b/testsuite/mkdir.c
@@ -23,47 +23,63 @@
 #include "mkdir.h"
 #include "testsuite.h"

+static inline int is_dir(const char *path)
+{
+       struct stat st;
+
+       if (stat(path, &st) >= 0) {
+               if (S_ISDIR(st.st_mode))
+                       return 1;
+               return 0;
+       }
+
+       return -errno;
+}
+
 TS_EXPORT int mkdir_p(const char *path, mode_t mode)
 {
        char *start = strdupa(path);
        int len = strlen(path);
        char *end = start + len;
-       struct stat st;

        /*
         * scan backwards, replacing '/' with '\0' while the component doesn't
         * exist
         */
        for (;;) {
-               if (stat(start, &st) >= 0) {
-                       if (S_ISDIR(st.st_mode))
-                               break;
-                       return -ENOTDIR;
-               }
+               int r = is_dir(start);
+               if (r > 0) {
+                       end += strlen(end);

-               /* Find the next component, backwards, discarding extra '/'*/
-               for (; end != start && *end != '/'; end--)
-                       ;
+                       if (end == start + len)
+                               return 0;

-               for (; end != start - 1 && *end == '/'; end--)
-                       ;
+                       /* end != start, since it would be caught on the first
+                        * iteration */
+                       *end = '/';
+                       break;
+               } else if (r == 0)
+                       return -ENOTDIR;

-               end++;
                if (end == start)
                        break;

                *end = '\0';
-       }

-       if (end == start + len)
-               return 0;
+               /* Find the next component, backwards, discarding extra '/'*/
+               while (end > start && *end != '/')
+                       end--;

-       for (; end < start + len;) {
-               *end = '/';
-               end += strlen(end);
+               while (end > start && *(end - 1) == '/')
+                       end--;
+       }

-               if (mkdir(start, mode) < 0)
+       for (; end < start + len;) {
+               if (mkdir(start, mode) < 0 && errno != EEXIST)
                        return -errno;
+
+               end += strlen(end);
+               *end = '/';
        }

        return 0;
--
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help