Mercurial > octave
changeset 31320:6a5e4ef80a95
Create directory for history file recursively (bug #62365).
* liboctave/system/file-ops.cc, liboctave/system/file-ops.h
(octave::sys::recursive_mkdir): Add new functions to create a directory making
sure that all parent directories are also created.
* liboctave/system/cmd-hist.cc (gnu_history::do_write): Use new function when
creating directory for history.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sat, 15 Oct 2022 17:36:34 +0200 |
parents | 6cf02f842e74 |
children | 1d99e68c05c0 |
files | liboctave/system/file-ops.cc liboctave/system/file-ops.h liboctave/util/cmd-hist.cc |
diffstat | 3 files changed, 61 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/system/file-ops.cc Wed Oct 19 12:14:09 2022 -0400 +++ b/liboctave/system/file-ops.cc Sat Oct 15 17:36:34 2022 +0200 @@ -416,6 +416,59 @@ return status; } + int recursive_mkdir (const std::string& name, mode_t mode) + { + std::string msg; + return recursive_mkdir (name, mode, msg); + } + + int recursive_mkdir (const std::string& name, mode_t mode, std::string& msg) + { + int status; + + // account for root in absolute directories +#if defined (OCTAVE_USE_WINDOWS_API) + // root of current drive + std::size_t skip_root = 0; + if (name.size () > 1) + { + if (name[1] == ':') + // drive root (e.g., C:\) + skip_root = 2; + else if (file_ops::is_dir_sep (name[0]) + && file_ops::is_dir_sep (name[1])) + { + // UNC path root (e.g., \\SERVER\share\) + skip_root = name.find_first_of (file_ops::dir_sep_chars (), 2); + skip_root = name.find_first_of (file_ops::dir_sep_chars (), + skip_root + 1); + } + } + + std::size_t delim = name.find_first_of (file_ops::dir_sep_chars (), + skip_root + 1); +#else + std::size_t delim = name.find_first_of (file_ops::dir_sep_chars (), 1); +#endif + + // iterate over all componenents of NAME and make directories + while (delim != std::string::npos) + { + std::string base = name.substr (0, delim); + sys::file_stat fs (base); + if (! fs.is_dir ()) + { + status = mkdir (base, mode, msg); + if (status < 0) + return status; + } + delim = name.find_first_of (file_ops::dir_sep_chars (), delim + 1); + } + + // finally, create requested directory + return mkdir (name, mode, msg); + } + int mkfifo (const std::string& nm, mode_t md) { std::string msg;
--- a/liboctave/system/file-ops.h Wed Oct 19 12:14:09 2022 -0400 +++ b/liboctave/system/file-ops.h Sat Oct 15 17:36:34 2022 +0200 @@ -122,6 +122,12 @@ mkdir (const std::string&, mode_t, std::string&); extern OCTAVE_API int + recursive_mkdir (const std::string& name, mode_t mode); + + extern OCTAVE_API int + recursive_mkdir (const std::string& name, mode_t mode, std::string& msg); + + extern OCTAVE_API int mkfifo (const std::string&, mode_t); extern OCTAVE_API int
--- a/liboctave/util/cmd-hist.cc Wed Oct 19 12:14:09 2022 -0400 +++ b/liboctave/util/cmd-hist.cc Sat Oct 15 17:36:34 2022 +0200 @@ -370,7 +370,8 @@ if (! hist_dir.empty ()) { sys::file_stat fs (hist_dir); - if (! fs.is_dir () && (sys::mkdir (hist_dir, 0777) < 0)) + if (! fs.is_dir () + && (sys::recursive_mkdir (hist_dir, 0777) < 0)) (*current_liboctave_error_handler) ("%s: Could not create directory \"%s\" for history", "gnu_history::do_write", hist_dir.c_str ());