* 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