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:
Karel Zak 2016-04-18 11:01:26 +02:00
commit 71d5088f05
7 changed files with 47 additions and 21 deletions

View File

@ -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':

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));