251 lines
9.1 KiB
Diff
251 lines
9.1 KiB
Diff
|
|
From 40cd25147b4461979c0d992299f2c101f9034f7a Mon Sep 17 00:00:00 2001
|
||
|
|
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||
|
|
Date: Tue, 6 Jun 2017 08:19:29 +0200
|
||
|
|
Subject: [PATCH 101/224] xargs: add -o, --open-tty option
|
||
|
|
|
||
|
|
This option is available in the xargs implementation of FreeBSD, NetBSD,
|
||
|
|
OpenBSD and in the Apple variant. Add it for compatibility.
|
||
|
|
|
||
|
|
* xargs/xargs.c (open_tty): Add static flag for the new option.
|
||
|
|
(longopts): Add member.
|
||
|
|
(main): Handle the 'o' case in the getopt_long() loop.
|
||
|
|
(prep_child_for_exec): Redirect stdin of the child to /dev/tty when
|
||
|
|
the -o option is given. Furthermore, move the just-opened file
|
||
|
|
descriptor to STDIN_FILENO.
|
||
|
|
(usage): Document the new option.
|
||
|
|
* bootstrap.conf (gnulib_modules): Add dup2.
|
||
|
|
* xargs/xargs.1 (SYNOPSIS): Replace the too-long list of options by
|
||
|
|
"[options]" - they are listed later anyway.
|
||
|
|
(OPTIONS): Document the new option.
|
||
|
|
(STANDARDS CONFORMANCE): Mention that the -o option is an extension.
|
||
|
|
* doc/find.texi (xargs options): Document the new option.
|
||
|
|
(Invoking the shell from xargs): Amend the explanation of the
|
||
|
|
redirection example with a note about the -o option.
|
||
|
|
(Viewing And Editing): Likewise.
|
||
|
|
(Error Messages From xargs): Add the message when dup2() fails.
|
||
|
|
(NEWS): Mention the new option.
|
||
|
|
|
||
|
|
Fixes http://savannah.gnu.org/bugs/?51151
|
||
|
|
---
|
||
|
|
NEWS | 4 ++++
|
||
|
|
bootstrap.conf | 1 +
|
||
|
|
doc/find.texi | 24 ++++++++++++++++++++++++
|
||
|
|
xargs/xargs.1 | 41 +++++++++++++----------------------------
|
||
|
|
xargs/xargs.c | 33 ++++++++++++++++++++++++++-------
|
||
|
|
5 files changed, 68 insertions(+), 35 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/doc/find.texi b/doc/find.texi
|
||
|
|
index 24d8ef99..4516b64c 100644
|
||
|
|
--- a/doc/find.texi
|
||
|
|
+++ b/doc/find.texi
|
||
|
|
@@ -3746,6 +3746,17 @@ Use at most @var{max-args} arguments per command line. Fewer than
|
||
|
|
option) is exceeded, unless the @samp{-x} option is given, in which
|
||
|
|
case @code{xargs} will exit.
|
||
|
|
|
||
|
|
+@item --open-tty
|
||
|
|
+@itemx -o
|
||
|
|
+Reopen stdin as @file{/dev/tty} in the child process before executing
|
||
|
|
+the command, thus allowing that command to be associated to the terminal
|
||
|
|
+while @code{xargs} reads from a different stream, e.g. from a pipe.
|
||
|
|
+This is useful if you want @code{xargs} to run an interactive application.
|
||
|
|
+@example
|
||
|
|
+grep -lz PATTERN * | xargs -0o vi
|
||
|
|
+@end example
|
||
|
|
+
|
||
|
|
+
|
||
|
|
@item --interactive
|
||
|
|
@itemx -p
|
||
|
|
Prompt the user about whether to run each command line and read a line
|
||
|
|
@@ -3877,6 +3888,10 @@ Therefore instead of keeping a @code{sh} process around for no reason,
|
||
|
|
we just arrange for the subshell to exec Emacs, saving an extra
|
||
|
|
process creation.
|
||
|
|
|
||
|
|
+Although GNU @code{xargs} and the implementations on some other platforms
|
||
|
|
+like BSD support the @samp{-o} option to achieve the same, the above is
|
||
|
|
+the portable way to redirect stdin to @file{/dev/tty}.
|
||
|
|
+
|
||
|
|
Sometimes, though, it can be helpful to keep the shell process around:
|
||
|
|
|
||
|
|
@example
|
||
|
|
@@ -4050,6 +4065,10 @@ protect the @code{$@@} against expansion by your interactive shell
|
||
|
|
nothing). The capitalised @samp{Emacs} on the command line is used as
|
||
|
|
@code{$0} by the shell that @code{xargs} launches.
|
||
|
|
|
||
|
|
+Please note that the implementations in GNU @code{xargs} and at least BSD
|
||
|
|
+support the @samp{-o} option as extension to achieve the same, while the
|
||
|
|
+above is the portable way to redirect stdin to @file{/dev/tty}.
|
||
|
|
+
|
||
|
|
@node Archiving
|
||
|
|
@section Archiving
|
||
|
|
|
||
|
|
@@ -5564,6 +5583,11 @@ signals to increase or decrease the parallelism of its processing.
|
||
|
|
If you don't plan to send it those signals, this warning can be ignored
|
||
|
|
(though if you're a programmer, you may want to help us figure out
|
||
|
|
why @code{xargs} is confused by your operating system).
|
||
|
|
+
|
||
|
|
+@item failed to redirect standard input of the child process
|
||
|
|
+@code{xargs} redirects the stdin stream of the command to be run to either
|
||
|
|
+@file{/dev/null} or to @file{/dev/tty} for the @samp{-o} option.
|
||
|
|
+See the manual of the system call @code{dup2(2)}.
|
||
|
|
@end table
|
||
|
|
|
||
|
|
@node Error Messages From locate
|
||
|
|
diff --git a/xargs/xargs.1 b/xargs/xargs.1
|
||
|
|
index 68377868..f66dbc05 100644
|
||
|
|
--- a/xargs/xargs.1
|
||
|
|
+++ b/xargs/xargs.1
|
||
|
|
@@ -4,34 +4,7 @@ xargs \- build and execute command lines from standard input
|
||
|
|
.SH SYNOPSIS
|
||
|
|
.B xargs
|
||
|
|
.nh
|
||
|
|
-[\fB\-0prtx\fR]
|
||
|
|
-[\fB\-E \fIeof-str\fR]
|
||
|
|
-[\fB\-e\fR[\fIeof-str\fR]]
|
||
|
|
-[\fB\-\-eof\fR[=\fIeof-str\fR]]
|
||
|
|
-[\fB\-\-null\fR]
|
||
|
|
-[\fB\-d \fIdelimiter\fR]
|
||
|
|
-[\fB\-\-delimiter \fIdelimiter\fR]
|
||
|
|
-[\fB\-I \fIreplace-str\fR]
|
||
|
|
-[\fB\-i\fR[\fIreplace-str\fR]]
|
||
|
|
-[\fB\-\-replace\fR[=\fIreplace-str\fR]]
|
||
|
|
-[\fB\-l\fR[\fImax-lines\fR]]
|
||
|
|
-[\fB\-L \fImax-lines\fR]
|
||
|
|
-[\fB\-\-max\-lines\fR[=\fImax-lines\fR]]
|
||
|
|
-[\fB\-n \fImax-args\fR]
|
||
|
|
-[\fB\-\-max\-args\fR=\fImax-args\fR]
|
||
|
|
-[\fB\-s \fImax-chars\fR]
|
||
|
|
-[\fB\-\-max\-chars\fR=\fImax-chars\fR]
|
||
|
|
-[\fB\-P \fImax-procs\fR]
|
||
|
|
-[\fB\-\-max\-procs\fR=\fImax-procs\fR]
|
||
|
|
-[\fB\-\-process\-slot\-var\fR=\fIname\fR]
|
||
|
|
-[\fB\-\-interactive\fR]
|
||
|
|
-[\fB\-\-verbose\fR]
|
||
|
|
-[\fB\-\-exit\fR]
|
||
|
|
-[\fB\-\-no\-run\-if\-empty\fR]
|
||
|
|
-[\fB\-\-arg\-file\fR=\fIfile\fR]
|
||
|
|
-[\fB\-\-show\-limits\fR]
|
||
|
|
-[\fB\-\-version\fR]
|
||
|
|
-[\fB\-\-help\fR]
|
||
|
|
+[\fIoptions\fR]
|
||
|
|
[\fIcommand\fR [\fIinitial-arguments\fR]]
|
||
|
|
.hy
|
||
|
|
.SH DESCRIPTION
|
||
|
|
@@ -252,6 +225,15 @@ arrange for each process to produce a separate output file (or
|
||
|
|
otherwise use separate resources).
|
||
|
|
.TP
|
||
|
|
.PD
|
||
|
|
+.B \-o, \-\-open\-tty
|
||
|
|
+Reopen stdin as
|
||
|
|
+.I /dev/tty
|
||
|
|
+in the child process before executing the command. This is useful if
|
||
|
|
+you want
|
||
|
|
+.B xargs
|
||
|
|
+to run an interactive application.
|
||
|
|
+.TP
|
||
|
|
+.PD
|
||
|
|
.B \-p, \-\-interactive
|
||
|
|
Prompt the user about whether to run each command line and read a line
|
||
|
|
from the terminal. Only run the command line if the response starts
|
||
|
|
@@ -404,6 +386,9 @@ The \-l and \-i options appear in the 1997 version of the POSIX
|
||
|
|
standard, but do not appear in the 2004 version of the standard.
|
||
|
|
Therefore you should use \-L and \-I instead, respectively.
|
||
|
|
.P
|
||
|
|
+The \-o option is an extension to the POSIX standard for better
|
||
|
|
+compatibility with BSD.
|
||
|
|
+.P
|
||
|
|
The POSIX standard allows implementations to have a limit on the size
|
||
|
|
of arguments to the
|
||
|
|
.B exec
|
||
|
|
diff --git a/xargs/xargs.c b/xargs/xargs.c
|
||
|
|
index 5cf8c131..a2917e48 100644
|
||
|
|
--- a/xargs/xargs.c
|
||
|
|
+++ b/xargs/xargs.c
|
||
|
|
@@ -151,6 +151,9 @@ static volatile int child_error = EXIT_SUCCESS;
|
||
|
|
|
||
|
|
static volatile int original_exit_value;
|
||
|
|
|
||
|
|
+/* If true, open /dev/tty in the child process before executing the command. */
|
||
|
|
+static bool open_tty = false; /* option -o */
|
||
|
|
+
|
||
|
|
/* If true, print each command on stderr before executing it. */
|
||
|
|
static bool print_command = false; /* Option -t */
|
||
|
|
|
||
|
|
@@ -185,6 +188,7 @@ static struct option const longopts[] =
|
||
|
|
{"replace", optional_argument, NULL, 'I'},
|
||
|
|
{"max-lines", optional_argument, NULL, 'l'},
|
||
|
|
{"max-args", required_argument, NULL, 'n'},
|
||
|
|
+ {"open-tty", no_argument, NULL, 'o'},
|
||
|
|
{"interactive", no_argument, NULL, 'p'},
|
||
|
|
{"no-run-if-empty", no_argument, NULL, 'r'},
|
||
|
|
{"max-chars", required_argument, NULL, 's'},
|
||
|
|
@@ -509,7 +513,7 @@ main (int argc, char **argv)
|
||
|
|
bc_use_sensible_arg_max (&bc_ctl);
|
||
|
|
}
|
||
|
|
|
||
|
|
- while ((optc = getopt_long (argc, argv, "+0a:E:e::i::I:l::L:n:prs:txP:d:",
|
||
|
|
+ while ((optc = getopt_long (argc, argv, "+0a:E:e::i::I:l::L:n:oprs:txP:d:",
|
||
|
|
longopts, &option_index)) != -1)
|
||
|
|
{
|
||
|
|
switch (optc)
|
||
|
|
@@ -608,6 +612,10 @@ main (int argc, char **argv)
|
||
|
|
bc_ctl.exit_if_size_exceeded = true;
|
||
|
|
break;
|
||
|
|
|
||
|
|
+ case 'o':
|
||
|
|
+ open_tty = true;
|
||
|
|
+ break;
|
||
|
|
+
|
||
|
|
case 'p':
|
||
|
|
query_before_executing = true;
|
||
|
|
print_command = true;
|
||
|
|
@@ -1185,22 +1193,30 @@ prep_child_for_exec (void)
|
||
|
|
unsigned int slot = add_proc (0);
|
||
|
|
set_slot_var (slot);
|
||
|
|
|
||
|
|
- if (!keep_stdin)
|
||
|
|
+ if (!keep_stdin || open_tty)
|
||
|
|
{
|
||
|
|
- const char inputfile[] = "/dev/null";
|
||
|
|
- /* fprintf (stderr, "attaching stdin to /dev/null\n"); */
|
||
|
|
+ int fd;
|
||
|
|
+ const char *inputfile = open_tty ? "/dev/tty" : "/dev/null";
|
||
|
|
|
||
|
|
close (0);
|
||
|
|
- if (open (inputfile, O_RDONLY) < 0)
|
||
|
|
+ if ((fd = open (inputfile, O_RDONLY)) < 0)
|
||
|
|
{
|
||
|
|
- /* This is not entirely fatal, since
|
||
|
|
+ /* Treat a failure to open /dev/tty as fatal.
|
||
|
|
+ * The other case is not entirely fatal, since
|
||
|
|
* executing the child with a closed
|
||
|
|
* stdin is almost as good as executing it
|
||
|
|
* with its stdin attached to /dev/null.
|
||
|
|
*/
|
||
|
|
- error (0, errno, "%s",
|
||
|
|
+ error (open_tty ? EXIT_FAILURE : 0, errno, "%s",
|
||
|
|
quotearg_n_style (0, locale_quoting_style, inputfile));
|
||
|
|
}
|
||
|
|
+ if (STDIN_FILENO < fd)
|
||
|
|
+ {
|
||
|
|
+ if (dup2(fd, STDIN_FILENO) != 0)
|
||
|
|
+ error (EXIT_FAILURE, errno,
|
||
|
|
+ _("failed to redirect standard input of the child process"));
|
||
|
|
+ close(fd);
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -1676,6 +1692,9 @@ usage (int status)
|
||
|
|
HTL (_(" -l[MAX-LINES] similar to -L but defaults to at most one non-\n"
|
||
|
|
" blank input line if MAX-LINES is not specified\n"));
|
||
|
|
HTL (_(" -n, --max-args=MAX-ARGS use at most MAX-ARGS arguments per command line\n"));
|
||
|
|
+ HTL (_(" -o, --open-tty Reopen stdin as /dev/tty in the child process\n"
|
||
|
|
+ " before executing the command; useful to run an\n"
|
||
|
|
+ " interactive application.\n"));
|
||
|
|
HTL (_(" -P, --max-procs=MAX-PROCS run at most MAX-PROCS processes at a time\n"));
|
||
|
|
HTL (_(" -p, --interactive prompt before running commands\n"));
|
||
|
|
HTL (_(" --process-slot-var=VAR set environment variable VAR in child processes\n"));
|
||
|
|
--
|
||
|
|
2.19.1
|
||
|
|
|