# HG changeset patch # User David Bateman # Date 1337805277 -7200 # Node ID a543ed02e6739431bdddd5eff87b3d5406bf94b6 # Parent 757f729fd41dc4fed00342050f25448650d5be36 Allow the builtin function mkdir to create missing parent directories * bootstrap.conf : Add the mkdir-p and savewd gnulib modules. * file-ops.cc (static int make_ancestor (const char*, const char*, void*)): New function. (int octave_mkdir (const std::string&, mode_t, std::string&, bool): Add fourth argument and use it to conditionally select whether to make the missing parent directories. * file-ops.h (int octave_mkdir (const std::string&, mode_t, std::string&, bool): Add fourth argument. * lo-cutils.c (struct mkdir_options): New structure (static void announce_mkdir (const char*, void*), static int process_dir (char *, struct savewd *, void *), int octave_mkdir_parents (const char *, mode_t, int (*make_ancestor) (const char *, const char *, void *)): New functions. * lo-cutils.h (int octave_mkdir_parents (const char *, mode_t, int (*make_ancestor) (const char *, const char *, void *)): New function. * dirfns.cc (Fmkdir): Call octave_mkdir with the make_parents argument set to true. diff -r 757f729fd41d -r a543ed02e673 build-aux/bootstrap.conf --- a/build-aux/bootstrap.conf Wed May 23 13:36:24 2012 -0400 +++ b/build-aux/bootstrap.conf Wed May 23 22:34:37 2012 +0200 @@ -40,6 +40,7 @@ link lstat mkdir + mkdir-p mkfifo mkostemp mkstemp @@ -56,6 +57,7 @@ rmdir round roundf + savewd sigaction signal sigprocmask diff -r 757f729fd41d -r a543ed02e673 liboctave/file-ops.cc --- a/liboctave/file-ops.cc Wed May 23 13:36:24 2012 -0400 +++ b/liboctave/file-ops.cc Wed May 23 22:34:37 2012 +0200 @@ -48,6 +48,7 @@ #include "quit.h" #include "singleton-cleanup.h" #include "str-vec.h" +#include "lo-cutils.h" file_ops *file_ops::instance = 0; @@ -361,22 +362,32 @@ : dir + dir_sep_char () + file); } +static int +make_ancestor (const char *, const char *component, void *options) +{ + mode_t* mode = reinterpret_cast(options); + return gnulib::mkdir (component, *mode); +} int octave_mkdir (const std::string& nm, mode_t md) { std::string msg; - return octave_mkdir (nm, md, msg); + return octave_mkdir (nm, md, msg, false); } int -octave_mkdir (const std::string& name, mode_t mode, std::string& msg) +octave_mkdir (const std::string& name, mode_t mode, std::string& msg, + bool make_parents) { msg = std::string (); int status = -1; - status = gnulib::mkdir (name.c_str (), mode); + if (make_parents) + status = octave_mkdir_parents (name.c_str (), mode, make_ancestor); + else + status = gnulib::mkdir (name.c_str (), mode); if (status < 0) msg = gnulib::strerror (errno); diff -r 757f729fd41d -r a543ed02e673 liboctave/file-ops.h --- a/liboctave/file-ops.h Wed May 23 13:36:24 2012 -0400 +++ b/liboctave/file-ops.h Wed May 23 22:34:37 2012 +0200 @@ -122,7 +122,8 @@ octave_mkdir (const std::string& nm, mode_t md); extern OCTAVE_API int -octave_mkdir (const std::string& nm, mode_t md, std::string& msg); +octave_mkdir (const std::string& nm, mode_t md, std::string& msg, + bool make_parents = false); extern OCTAVE_API int octave_mkfifo (const std::string& nm, mode_t md); diff -r 757f729fd41d -r a543ed02e673 liboctave/lo-cutils.c --- a/liboctave/lo-cutils.c Wed May 23 13:36:24 2012 -0400 +++ b/liboctave/lo-cutils.c Wed May 23 22:34:37 2012 +0200 @@ -32,6 +32,7 @@ #endif #include +#include #include #include @@ -41,6 +42,9 @@ #include "lo-cutils.h" #include "syswait.h" +#include "savewd.h" +#include "mkdir-p.h" + OCTAVE_API void octave_qsort (void *base, size_t n, size_t size, int (*cmp) (const void *, const void *)) @@ -76,3 +80,46 @@ { return WAITPID (pid, status, options); } + +struct mkdir_options +{ + int (*make_ancestor_function) (const char *, const char *, void *); + mode_t ancestor_mode; + mode_t mode; + mode_t mode_bits; +}; + +static void +announce_mkdir (const char *dir, void *options) +{ + /* Do nothing */ +} + +static int +process_dir (char *dir, struct savewd *wd, void *options) +{ + struct mkdir_options const *o = options; + mode_t ancestor_mode = o->ancestor_mode; + return (make_dir_parents (dir, wd, o->make_ancestor_function, &ancestor_mode, + o->mode, announce_mkdir, o->mode_bits, + (uid_t) -1, (gid_t) -1, false) ? 0 : -1); +} + +OCTAVE_API int +octave_mkdir_parents (const char *dir, mode_t mode, + int (*make_ancestor) (const char *, const char *, void *)) +{ + char *argv[1]; + int retval; + char *dir2 = malloc (strlen (dir) + 1); + strcpy (dir2, dir); /* Make a copy to avoid passing a const char* as char* */ + argv[0] = dir2; + struct mkdir_options o; + o.make_ancestor_function = make_ancestor; + o.ancestor_mode = mode | S_IWUSR | S_IXUSR; + o.mode = mode | umask(0); + o.mode_bits = ~(mode & umask(0)); + retval = (savewd_process_files (1, argv, process_dir, &o)); + free (dir2); + return retval; +} diff -r 757f729fd41d -r a543ed02e673 liboctave/lo-cutils.h --- a/liboctave/lo-cutils.h Wed May 23 13:36:24 2012 -0400 +++ b/liboctave/lo-cutils.h Wed May 23 22:34:37 2012 +0200 @@ -50,6 +50,10 @@ OCTAVE_API pid_t octave_waitpid (pid_t pid, int *status, int options); +OCTAVE_API int +octave_mkdir_parents (const char *dir, mode_t mode, + int (*make_ancestor) (char const *, char const *, void *)); + #ifdef __cplusplus } #endif diff -r 757f729fd41d -r a543ed02e673 src/dirfns.cc --- a/src/dirfns.cc Wed May 23 13:36:24 2012 -0400 +++ b/src/dirfns.cc Wed May 23 22:34:37 2012 +0200 @@ -271,7 +271,7 @@ } else { - int status = octave_mkdir (dirname, 0777, msg); + int status = octave_mkdir (dirname, 0777, msg, true); if (status < 0) {