* NEWS: Document this. * zic.c (mkdirs): Do not mkdir a root directory. Avoid unnecessary stat call. --- NEWS | 2 ++ zic.c | 24 +++++++++++++----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index f5a0b13..192deb7 100644 --- a/NEWS +++ b/NEWS @@ -55,6 +55,8 @@ Unreleased, experimental changes stamps on the reference platform. (Thanks to Alexander Belopolsky for reporting the bug and suggesting a way forward.) + zic now avoids some unnecessary mkdir and stat system calls. + zdump has a new -i option to generate transitions in a more-compact but still human-readable format. This option is experimental, and the output format may change in future versions. diff --git a/zic.c b/zic.c index b8bd0a6..5ff78b4 100644 --- a/zic.c +++ b/zic.c @@ -3027,25 +3027,27 @@ mkdirs(char *argname) if (argname == NULL || *argname == '\0') return true; cp = name = ecpyalloc(argname); - while ((cp = strchr(cp + 1, '/')) != 0) { - *cp = '\0'; + + /* Do not mkdir a root directory, as it must exist. */ #ifdef HAVE_DOS_FILE_NAMES - /* - ** DOS drive specifier? - */ - if (is_alpha(name[0]) && name[1] == ':' && name[2] == '\0') { - *cp = '/'; - continue; - } + if (is_alpha(name[0]) && name[1] == ':') + cp += 2; #endif + while (*cp == '/') + cp++; + + for (; (cp = strchr(cp, '/')) != 0; cp++) { + *cp = '\0'; /* ** Try to create it. It's OK if creation fails because ** the directory already exists, perhaps because some - ** other process just created it. + ** other process just created it. For simplicity do + ** not check first whether it already exists, as that + ** is checked anyway if the mkdir fails. */ if (mkdir(name, MKDIR_UMASK) != 0) { int err = errno; - if (itsdir(name) <= 0) { + if (err != EEXIST && itsdir(name) <= 0) { char const *e = strerror(err); warning(_("%s: Can't create directory" " %s: %s"), -- 2.7.4