Modify the -p implementation to use a user's locale, so they can respond to

the prompt in their native language.

Also make the prompt fit what POSIX asks for (?...).

This should not affect use of -p with yes(1) [as every locale I know of matches
'y' as YESEXPR as well], but that's what -t is for anyway.  -p is meant to be
really used interactively.

Submitted by:	tjr, jmallett
This commit is contained in:
Juli Mallett 2002-05-05 06:42:44 +00:00
parent 15fdd586e3
commit 305e39f49b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96057
2 changed files with 63 additions and 13 deletions

View File

@ -194,10 +194,12 @@ is 5000.
.It Fl p
Echo each command to be executed and ask the user whether it should be
executed.
A response of
An affirmative response,
.Ql y
in the POSIX locale,
causes the command to be executed, any other response causes it to be
skipped.
No commands are executed if the process is not attached to a terminal.
.It Fl R Ar replacements
This option specifies the maximum number of arguments that
.Fl I

View File

@ -56,6 +56,10 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <langinfo.h>
#include <locale.h>
#include <paths.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -65,6 +69,7 @@ __FBSDID("$FreeBSD$");
static void parse_input(int, char **);
static void prerun(int, char **);
static int prompt(void);
static void run(char **);
static void usage(void);
void strnsubst(char **, const char *, const char *, size_t);
@ -90,6 +95,8 @@ main(int argc, char **argv)
eofstr = "";
Jflag = nflag = 0;
(void)setlocale(LC_MESSAGES, "");
/*
* POSIX.2 limits the exec line length to ARG_MAX - 2K. Running that
* caused some E2BIG errors, so it was changed to ARG_MAX - 4K. Given
@ -454,26 +461,40 @@ run(char **argv)
{
volatile int childerr;
char **avec;
FILE *ttyfp;
pid_t pid;
int ch, status;
int status;
/*
* If the user wants to be notified of each command before it is
* executed, notify them. If they want the notification to be
* followed by a prompt, then prompt them.
*/
if (tflag || pflag) {
(void)fprintf(stderr, "%s", *argv);
for (avec = argv + 1; *avec != NULL; ++avec)
(void)fprintf(stderr, " %s", *avec);
if (pflag && (ttyfp = fopen("/dev/tty", "r")) != NULL) {
(void)fprintf(stderr, "?");
(void)fflush(stderr);
ch = getc(ttyfp);
fclose(ttyfp);
if (ch != 'y')
/*
* If the user has asked to be prompted, do so.
*/
if (pflag)
/*
* If they asked not to exec, return without execution
* but if they asked to, go to the execution. If we
* could not open their tty, break the switch and drop
* back to -t behaviour.
*/
switch (prompt()) {
case 0:
return;
} else {
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
}
case 1:
goto exec;
case 2:
break;
}
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
}
exec:
childerr = 0;
switch(pid = vfork()) {
case -1:
@ -496,6 +517,33 @@ run(char **argv)
rval = 1;
}
/*
* Prompt the user about running a command.
*/
static int
prompt(void)
{
regex_t cre;
size_t rsize;
int match;
char *response;
FILE *ttyfp;
if ((ttyfp = fopen(_PATH_TTY, "r")) == NULL)
return (2); /* Indicate that the TTY failed to open. */
(void)fprintf(stderr, "?...");
(void)fflush(stderr);
if ((response = fgetln(ttyfp, &rsize)) == NULL ||
regcomp(&cre, nl_langinfo(YESEXPR), REG_BASIC) != 0) {
(void)fclose(ttyfp);
return (0);
}
match = regexec(&cre, response, 0, NULL, 0);
(void)fclose(ttyfp);
regfree(&cre);
return (match == 0);
}
static void
usage(void)
{