diff options
author | Tom Tromey <tom@tromey.com> | 2018-09-17 10:48:20 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2018-10-27 11:58:41 -0600 |
commit | e418a61a67a3476826259163383e5deb661042cc (patch) | |
tree | 44214b56d20367f0979c8c00e469edcb290171a6 /gdb/common | |
parent | 29be4d9dee1263b36e33421dd8ea69b9b7308391 (diff) | |
download | binutils-e418a61a67a3476826259163383e5deb661042cc.zip binutils-e418a61a67a3476826259163383e5deb661042cc.tar.gz binutils-e418a61a67a3476826259163383e5deb661042cc.tar.bz2 |
Move mkdir_recursive to common/filestuff.c
This moves mkdir_recursive from dwarf-index-cache.c to
common/filestuff.c, and also changes it to return a boolean that says
whether or not it worked.
gdb/ChangeLog
2018-10-27 Tom Tromey <tom@tromey.com>
* unittests/mkdir-recursive-selftests.c: New file.
* Makefile.in (SUBDIR_UNITTESTS_SRCS): Add
unittests/mkdir-recursive-selftests.c.
* dwarf-index-cache.c (mkdir_recursive): Move to
common/filestuff.c.
(index_cache::store): Check return value of mkdir_recursive.
(create_dir_and_check, test_mkdir_recursive): Move to new file.
(_initialize_index_cache): Don't register test.
* common/filestuff.h (mkdir_recursive): Declare.
* common/filestuff.c (mkdir_recursive): Move from
dwarf-index-cache.c. Return bool.
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/filestuff.c | 45 | ||||
-rw-r--r-- | gdb/common/filestuff.h | 10 |
2 files changed, 55 insertions, 0 deletions
diff --git a/gdb/common/filestuff.c b/gdb/common/filestuff.c index dfd86f9..d4bd1a8 100644 --- a/gdb/common/filestuff.c +++ b/gdb/common/filestuff.c @@ -447,3 +447,48 @@ is_regular_file (const char *name, int *errno_ptr) *errno_ptr = EINVAL; return false; } + +/* See common/filestuff.h. */ + +bool +mkdir_recursive (const char *dir) +{ + gdb::unique_xmalloc_ptr<char> holder (xstrdup (dir)); + char * const start = holder.get (); + char *component_start = start; + char *component_end = start; + + while (1) + { + /* Find the beginning of the next component. */ + while (*component_start == '/') + component_start++; + + /* Are we done? */ + if (*component_start == '\0') + return true; + + /* Find the slash or null-terminator after this component. */ + component_end = component_start; + while (*component_end != '/' && *component_end != '\0') + component_end++; + + /* Temporarily replace the slash with a null terminator, so we can create + the directory up to this component. */ + char saved_char = *component_end; + *component_end = '\0'; + + /* If we get EEXIST and the existing path is a directory, then we're + happy. If it exists, but it's a regular file and this is not the last + component, we'll fail at the next component. If this is the last + component, the caller will fail with ENOTDIR when trying to + open/create a file under that path. */ + if (mkdir (start, 0700) != 0) + if (errno != EEXIST) + return false; + + /* Restore the overwritten char. */ + *component_end = saved_char; + component_start = component_end; + } +} diff --git a/gdb/common/filestuff.h b/gdb/common/filestuff.h index e9328f5..ecfc18d 100644 --- a/gdb/common/filestuff.h +++ b/gdb/common/filestuff.h @@ -122,4 +122,14 @@ typedef std::unique_ptr<DIR, gdb_dir_deleter> gdb_dir_up; we're expecting a regular file. */ extern bool is_regular_file (const char *name, int *errno_ptr); + +/* A cheap (as in low-quality) recursive mkdir. Try to create all the + parents directories up to DIR and DIR itself. Stop if we hit an + error along the way. There is no attempt to remove created + directories in case of failure. + + Returns false on failure and sets errno. */ + +extern bool mkdir_recursive (const char *dir); + #endif /* FILESTUFF_H */ |