Merge branch '2016wk15' of git://github.com/kerolasa/lelux-utiliteetit
* '2016wk15' of git://github.com/kerolasa/lelux-utiliteetit: mount: try to tell what mount was doing when it failed dmesg: --notime should not suppress --show-delta script: check status of writes when closing outputs script: avoid trying fclose(NULL) sulogin: make fopen O_CLOEXEC specifier usage portable script: close file descriptors on exec docs: optinal option arguments should be long-only
This commit is contained in:
commit
71d5088f05
|
@ -35,7 +35,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
|
|||
fprintf(out, _(" %s [options] file...\n"), program_invocation_short_name);
|
||||
fputs(USAGE_OPTIONS, out);
|
||||
fputs(_(" -n, --no-argument option does not use argument\n"), out);
|
||||
fputs(_(" -o, --optional[=<arg>] option argument is optional\n"), out);
|
||||
fputs(_(" --optional[=<arg>] option argument is optional\n"), out);
|
||||
fputs(_(" -r, --required <arg> option requires an argument\n"), out);
|
||||
fputs(_(" -z no long option\n"), out);
|
||||
fputs(_(" --xyzzy a long option only\n"), out);
|
||||
|
@ -57,11 +57,11 @@ int main(int argc, char **argv)
|
|||
int c;
|
||||
|
||||
enum {
|
||||
OPT_XYZZY = CHAR_MAX + 1
|
||||
OPT_XYZZY = CHAR_MAX + 1,
|
||||
OPT_OPTIONAL /* see howto-man-page.txt about short option */
|
||||
};
|
||||
static const struct option longopts[] = {
|
||||
{"no-argument", no_argument, NULL, 'n'},
|
||||
{"optional", optional_argument, NULL, 'o'},
|
||||
{"required", required_argument, NULL, 'r'},
|
||||
{"xyzzy", no_argument, NULL, OPT_XYZZY},
|
||||
{"extremely-long-long-option", no_argument, NULL, 'e'},
|
||||
|
@ -77,10 +77,10 @@ int main(int argc, char **argv)
|
|||
textdomain(PACKAGE);
|
||||
atexit(close_stdout);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "no::r:elfVh", longopts, NULL)) != -1)
|
||||
while ((c = getopt_long(argc, argv, "nr:elfVh", longopts, NULL)) != -1)
|
||||
switch (c) {
|
||||
case 'n':
|
||||
case 'o':
|
||||
case OPT_OPTIONAL:
|
||||
case 'r':
|
||||
case OPT_XYZZY:
|
||||
case 'e':
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
.\"
|
||||
.\" Please read `man 7 groff_man' to see how to use the various macros.
|
||||
.\"
|
||||
.TH EXAMPLE "1" "July 2014" "util-linux" "User Commands"
|
||||
.TH EXAMPLE "1" "April 2016" "util-linux" "User Commands"
|
||||
.SH NAME
|
||||
example \- a util-linux man-page howto
|
||||
.SH SYNOPSIS
|
||||
|
@ -33,7 +33,7 @@ Write such here.
|
|||
\fB\-n\fR, \fB\-\-no\-argument\fR
|
||||
This option does not use an argument.
|
||||
.TP
|
||||
\fB\-o\fR, \fB\-\-optional\fR[\fI=argument\fR]
|
||||
\fB\-\-optional\fR[\fI=argument\fR]
|
||||
Tell in this description that the
|
||||
.I argument
|
||||
is optional, and what happens when it is or is not given. Notice that the word
|
||||
|
@ -43,6 +43,24 @@ usage text uses the argument
|
|||
.IR num ,
|
||||
the manual page should say
|
||||
.IR number .
|
||||
.IP
|
||||
Notice that after release v2.28 it was decided that introducing new options
|
||||
taking optional arguments should be limited to long-only options. This is
|
||||
done primarily to avoid problematic behaviour of short options. Imagine for
|
||||
example normal option
|
||||
.B \-n
|
||||
and optional option
|
||||
.BR \-o .
|
||||
One will expect
|
||||
.B command \ \-no
|
||||
and
|
||||
.B command \ \-on
|
||||
to be the same, but in fact the former is two separate options while the
|
||||
later will use
|
||||
.B n
|
||||
as option argument of
|
||||
.BR -o .
|
||||
So it is best to avoid short forms of optional options altogether.
|
||||
.TP
|
||||
\fB\-r\fR, \fB\-\-required\fR \fIargument\fR
|
||||
Tell in this description that the
|
||||
|
|
|
@ -45,7 +45,7 @@ Usage:
|
|||
|
||||
Options:
|
||||
-n, --no-argument option does not use argument
|
||||
-o, --optional[=<arg>] option argument is optional
|
||||
--optional[=<arg>] option argument is optional
|
||||
-r, --required <arg> option requires an argument
|
||||
-z no long option
|
||||
--xyzzy a long option only
|
||||
|
|
|
@ -160,7 +160,7 @@ char *oneline(const char *file)
|
|||
|
||||
DBG(dbgprint("reading %s", file));
|
||||
|
||||
if (!(fp = fopen(file, "re")))
|
||||
if (!(fp = fopen(file, "r" UL_CLOEXECSTR)))
|
||||
return NULL;
|
||||
len = getline(&ret, &dummy, fp);
|
||||
if (len >= 0) {
|
||||
|
@ -361,7 +361,7 @@ static int detect_consoles_from_proc(struct list_head *consoles)
|
|||
|
||||
DBG(dbgprint("trying /proc"));
|
||||
|
||||
fc = fopen("/proc/consoles", "re");
|
||||
fc = fopen("/proc/consoles", "r" UL_CLOEXECSTR);
|
||||
if (!fc) {
|
||||
rc = 2;
|
||||
goto done;
|
||||
|
|
|
@ -1363,7 +1363,6 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
case 't':
|
||||
ctl.time_fmt = DMESG_TIMEFTM_NONE;
|
||||
delta = 0;
|
||||
break;
|
||||
case 'u':
|
||||
ctl.fltr_fac = 1;
|
||||
|
|
|
@ -520,7 +520,12 @@ try_readonly:
|
|||
warnx(_("special device %s does not exist"), src);
|
||||
} else {
|
||||
errno = syserr;
|
||||
warn(_("mount(2) failed")); /* print errno */
|
||||
if (tgt)
|
||||
warn("%s: %s", _("mount(2) failed"), tgt);
|
||||
else if (src)
|
||||
warn("%s: %s", _("mount(2) failed"), src);
|
||||
else
|
||||
warn(_("mount(2) failed"));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -535,7 +540,7 @@ try_readonly:
|
|||
"(a path prefix is not a directory)"), src);
|
||||
} else {
|
||||
errno = syserr;
|
||||
warn(_("mount(2) failed")); /* print errno */
|
||||
warn("%s: %s", _("mount(2) failed"), tgt);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -204,8 +204,11 @@ static void __attribute__((__noreturn__)) done(struct script_control *ctl)
|
|||
kill(ctl->child, SIGTERM); /* make sure we don't create orphans */
|
||||
|
||||
if (ctl->timingfp)
|
||||
fclose(ctl->timingfp);
|
||||
fclose(ctl->typescriptfp);
|
||||
if (close_stream(ctl->timingfp) != 0)
|
||||
err(EXIT_FAILURE, "write failed: %s", ctl->tname);
|
||||
if (ctl->typescriptfp)
|
||||
if (close_stream(ctl->typescriptfp) != 0)
|
||||
err(EXIT_FAILURE, "write failed: %s", ctl->fname);
|
||||
|
||||
if (ctl->rc_wanted) {
|
||||
if (WIFSIGNALED(ctl->childstatus))
|
||||
|
@ -419,15 +422,16 @@ static void do_io(struct script_control *ctl)
|
|||
};
|
||||
|
||||
|
||||
if ((ctl->typescriptfp = fopen(ctl->fname, ctl->append ? "a" : "w")) == NULL) {
|
||||
if ((ctl->typescriptfp =
|
||||
fopen(ctl->fname, ctl->append ? "a" UL_CLOEXECSTR : "w" UL_CLOEXECSTR)) == NULL) {
|
||||
warn(_("cannot open %s"), ctl->fname);
|
||||
fail(ctl);
|
||||
}
|
||||
if (ctl->timing) {
|
||||
if (!ctl->tname) {
|
||||
if (!(ctl->timingfp = fopen("/dev/stderr", "w")))
|
||||
if (!(ctl->timingfp = fopen("/dev/stderr", "w" UL_CLOEXECSTR)))
|
||||
err(EXIT_FAILURE, _("cannot open %s"), "/dev/stderr");
|
||||
} else if (!(ctl->timingfp = fopen(ctl->tname, "w")))
|
||||
} else if (!(ctl->timingfp = fopen(ctl->tname, "w" UL_CLOEXECSTR)))
|
||||
err(EXIT_FAILURE, _("cannot open %s"), ctl->tname);
|
||||
}
|
||||
|
||||
|
@ -515,7 +519,7 @@ static void getslave(struct script_control *ctl)
|
|||
{
|
||||
#ifndef HAVE_LIBUTIL
|
||||
ctl->line[strlen("/dev/")] = 't';
|
||||
ctl->slave = open(ctl->line, O_RDWR);
|
||||
ctl->slave = open(ctl->line, O_RDWR | O_CLOEXEC);
|
||||
if (ctl->slave < 0) {
|
||||
warn(_("cannot open %s"), ctl->line);
|
||||
fail(ctl);
|
||||
|
@ -625,7 +629,7 @@ static void getmaster(struct script_control *ctl)
|
|||
break;
|
||||
for (cp = "0123456789abcdef"; *cp; cp++) {
|
||||
*pty = *cp;
|
||||
ctl->master = open(ctl->line, O_RDWR);
|
||||
ctl->master = open(ctl->line, O_RDWR | O_CLOEXEC);
|
||||
if (ctl->master >= 0) {
|
||||
char *tp = &ctl->line[strlen("/dev/")];
|
||||
int ok;
|
||||
|
@ -765,7 +769,7 @@ int main(int argc, char **argv)
|
|||
* handled according to their default dispositions */
|
||||
sigprocmask(SIG_BLOCK, &ctl.sigset, &ctl.sigorg);
|
||||
|
||||
if ((ctl.sigfd = signalfd(-1, &ctl.sigset, 0)) < 0)
|
||||
if ((ctl.sigfd = signalfd(-1, &ctl.sigset, SFD_CLOEXEC)) < 0)
|
||||
err(EXIT_FAILURE, _("cannot set signal handler"));
|
||||
|
||||
DBG(SIGNAL, ul_debug("signal fd=%d", ctl.sigfd));
|
||||
|
|
Loading…
Reference in New Issue