# HG changeset patch # User John W. Eaton # Date 1337884359 14400 # Node ID f871dc8eb22178b40491fb361bb17381b8b59058 # Parent a543ed02e6739431bdddd5eff87b3d5406bf94b6 [mq]: mkdir-p diff --git a/liboctave/file-ops.cc b/liboctave/file-ops.cc --- a/liboctave/file-ops.cc +++ b/liboctave/file-ops.cc @@ -362,13 +362,6 @@ : 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) { @@ -385,7 +378,13 @@ int status = -1; if (make_parents) - status = octave_mkdir_parents (name.c_str (), mode, make_ancestor); + { + OCTAVE_LOCAL_BUFFER (char, nm, name.size () + 1); + + strcpy (nm, name.c_str ()); + + status = octave_mkdir_parents (nm, mode); + } else status = gnulib::mkdir (name.c_str (), mode); diff --git a/liboctave/lo-cutils.c b/liboctave/lo-cutils.c --- a/liboctave/lo-cutils.c +++ b/liboctave/lo-cutils.c @@ -20,6 +20,13 @@ */ +/* + +The function make_ancestor was adapted from GNU Coreutils, copyright (C) +1990-2012 Free Software Foundation, Inc. + +*/ + #ifdef HAVE_CONFIG_H #include #endif @@ -42,8 +49,9 @@ #include "lo-cutils.h" #include "syswait.h" +#include "mkancesdirs.h" +#include "mkdir-p.h" #include "savewd.h" -#include "mkdir-p.h" OCTAVE_API void octave_qsort (void *base, size_t n, size_t size, @@ -95,6 +103,25 @@ /* Do nothing */ } +// Make ancestor directory DIR, whose last component is COMPONENT, +// with options OPTIONS. Assume the working directory is COMPONENT's +// parent. Return 0 if successful and the resulting directory is +// readable, 1 if successful but the resulting directory is not +// readable, -1 (setting errno) otherwise. + +static int +make_ancestor (char const *dir, char const *component, void *options) +{ + struct mkdir_options const *o = options; + + int r = mkdir (component, o->ancestor_mode); + + if (r == 0) + r = ! (o->ancestor_mode & S_IRUSR); + + return r; +} + static int process_dir (char *dir, struct savewd *wd, void *options) { @@ -102,24 +129,26 @@ 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); + (uid_t) -1, (gid_t) -1, true) ? 0 : -1); } OCTAVE_API int -octave_mkdir_parents (const char *dir, mode_t mode, - int (*make_ancestor) (const char *, const char *, void *)) +octave_mkdir_parents (char *dir, mode_t mode) { + int retval; + 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; + argv[0] = dir; + + mode_t umask_value = umask (0); + 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)); + o.ancestor_mode = (mode & ~umask_value) | (S_IWUSR | S_IXUSR); + o.mode = mode & ~umask_value; + o.mode_bits = 0; + retval = (savewd_process_files (1, argv, process_dir, &o)); - free (dir2); + return retval; } diff --git a/liboctave/lo-cutils.h b/liboctave/lo-cutils.h --- a/liboctave/lo-cutils.h +++ b/liboctave/lo-cutils.h @@ -51,8 +51,7 @@ 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 *)); +octave_mkdir_parents (char *dir, mode_t mode); #ifdef __cplusplus }