diff options
Diffstat (limited to 'lib/mkancesdirs.c')
-rw-r--r-- | lib/mkancesdirs.c | 121 |
1 files changed, 54 insertions, 67 deletions
diff --git a/lib/mkancesdirs.c b/lib/mkancesdirs.c index 19f7dca..7a8173f 100644 --- a/lib/mkancesdirs.c +++ b/lib/mkancesdirs.c @@ -1,11 +1,11 @@ /* Make a file's ancestor directories. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2009-2016 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,8 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* Written by Paul Eggert. */ @@ -43,11 +42,9 @@ Create any ancestor directories that don't already exist, by invoking MAKE_DIR (FILE, COMPONENT, MAKE_DIR_ARG). This function - should return 0 if successful and the resulting directory is - readable, 1 if successful but the resulting directory might not be - readable, -1 (setting errno) otherwise. If COMPONENT is relative, - it is relative to the temporary working directory, which may differ - from *WD. + should return 0 if successful, -1 (setting errno) otherwise. If + COMPONENT is relative, it is relative to the temporary working + directory, which may differ from *WD. Ordinarily MAKE_DIR is executed with the working directory changed to reflect the already-made prefix, and mkancesdirs returns with @@ -66,8 +63,8 @@ ptrdiff_t mkancesdirs (char *file, struct savewd *wd, - int (*make_dir) (char const *, char const *, void *), - void *make_dir_arg) + int (*make_dir) (char const *, char const *, void *), + void *make_dir_arg) { /* Address of the previous directory separator that follows an ordinary byte in a file name in the left-to-right scan, or NULL @@ -91,63 +88,53 @@ mkancesdirs (char *file, struct savewd *wd, while ((c = *p++)) if (ISSLASH (*p)) { - if (! ISSLASH (c)) - sep = p; + if (! ISSLASH (c)) + sep = p; } else if (ISSLASH (c) && *p && sep) { - /* Don't bother to make or test for "." since it does not - affect the algorithm. */ - if (! (sep - component == 1 && component[0] == '.')) - { - int make_dir_errno = 0; - int savewd_chdir_options = 0; - int chdir_result; - - /* Temporarily modify FILE to isolate this file name - component. */ - *sep = '\0'; - - /* Invoke MAKE_DIR on this component, except don't bother - with ".." since it must exist if its "parent" does. */ - if (sep - component == 2 - && component[0] == '.' && component[1] == '.') - made_dir = false; - else - switch (make_dir (file, component, make_dir_arg)) - { - case -1: - make_dir_errno = errno; - break; - - case 0: - savewd_chdir_options |= SAVEWD_CHDIR_READABLE; - /* Fall through. */ - case 1: - made_dir = true; - break; - } - - if (made_dir) - savewd_chdir_options |= SAVEWD_CHDIR_NOFOLLOW; - - chdir_result = - savewd_chdir (wd, component, savewd_chdir_options, NULL); - - /* Undo the temporary modification to FILE, unless there - was a failure. */ - if (chdir_result != -1) - *sep = '/'; - - if (chdir_result != 0) - { - if (make_dir_errno != 0 && errno == ENOENT) - errno = make_dir_errno; - return chdir_result; - } - } - - component = p; + /* Don't bother to make or test for "." since it does not + affect the algorithm. */ + if (! (sep - component == 1 && component[0] == '.')) + { + int make_dir_errno = 0; + int savewd_chdir_options = 0; + int chdir_result; + + /* Temporarily modify FILE to isolate this file name + component. */ + *sep = '\0'; + + /* Invoke MAKE_DIR on this component, except don't bother + with ".." since it must exist if its "parent" does. */ + if (sep - component == 2 + && component[0] == '.' && component[1] == '.') + made_dir = false; + else if (make_dir (file, component, make_dir_arg) < 0) + make_dir_errno = errno; + else + made_dir = true; + + if (made_dir) + savewd_chdir_options |= SAVEWD_CHDIR_NOFOLLOW; + + chdir_result = + savewd_chdir (wd, component, savewd_chdir_options, NULL); + + /* Undo the temporary modification to FILE, unless there + was a failure. */ + if (chdir_result != -1) + *sep = '/'; + + if (chdir_result != 0) + { + if (make_dir_errno != 0 && errno == ENOENT) + errno = make_dir_errno; + return chdir_result; + } + } + + component = p; } return component - file; |