* NEWS, zic.8, zic.c (usage): Mention it. * zic.c (skip_mkdir): New static var. (main): Set it. (mkdirs): Use it. --- NEWS | 2 ++ zic.8 | 6 ++++++ zic.c | 16 +++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index c605a1fb..e777c6a7 100644 --- a/NEWS +++ b/NEWS @@ -105,6 +105,8 @@ Unreleased, experimental changes exceedingly long TZ strings no longer fail merely because they exceed an arbitrary file name length limit imposed by tzcode. + zic has a new option -D, inspired by FreeBSD. + zic now uses the fdopen function, which was standardized by POSIX.1-1988 and is now safe to use in portable code. This replaces its use of the older umask function, which diff --git a/zic.8 b/zic.8 index 62ebfcc9..45318020 100644 --- a/zic.8 +++ b/zic.8 @@ -77,6 +77,12 @@ Also see the .B \-r option for another way to alter output size. .TP +.BI \-D +Do not create ancestor directories of output files, +For example, for a zone named America/Los_Angeles +the directory America should already exist. +By default, the directory and its ancestors are created +if they do not already exist. .BI "\-d " directory Create time conversion information files in the named directory rather than in the standard directory named below. diff --git a/zic.c b/zic.c index 9a2c0624..d8408abf 100644 --- a/zic.c +++ b/zic.c @@ -247,6 +247,7 @@ static int max_format_len; static zic_t max_year; static zic_t min_year; static bool noise; +static bool skip_mkdir; static int rfilenum; static lineno rlinenum; static const char * progname; @@ -704,8 +705,8 @@ usage(FILE *stream, int status) { fprintf(stream, _("%s: usage is %s [ --version ] [ --help ] [ -v ] \\\n" - "\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ]" - " [ -L leapseconds ] \\\n" + "\t[ -b {slim|fat} ] [ -d directory ] [ -D ] \\\n" + "\t[ -l localtime ] [ -L leapseconds ] \\\n" "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -R @hi ] \\\n" "\t[ -t localtime-link ] \\\n" "\t[ filename ... ]\n\n" @@ -1037,7 +1038,7 @@ main(int argc, char **argv) } else if (strcmp(argv[k], "--help") == 0) { usage(stdout, EXIT_SUCCESS); } - while ((c = getopt(argc, argv, "b:d:l:L:p:r:R:st:vy:")) != -1) + while ((c = getopt(argc, argv, "b:d:Dl:L:p:r:R:st:vy:")) != -1) switch (c) { default: usage(stderr, EXIT_FAILURE); @@ -1058,6 +1059,9 @@ main(int argc, char **argv) duplicate_options("-d"); directory = optarg; break; + case 'D': + skip_mkdir = true; + break; case 'l': if (lcltime) duplicate_options("-l"); @@ -3951,6 +3955,11 @@ mp = _("time zone abbreviation differs from POSIX standard"); static void mkdirs(char const *argname, bool ancestors) { + /* If -D was specified, do not create directories. + If a file operation's parent directory is missing, + the operation will fail and be diagnosed. */ + if (!skip_mkdir) { + char *name = xstrdup(argname); char *cp = name; @@ -3997,4 +4006,5 @@ mkdirs(char const *argname, bool ancestors) *cp++ = '/'; } free(name); + } } -- 2.48.1