mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
display: yes no prompt improvement
Original code missed to catch all apperances of SIGINT. Also enhance logging when running in shell without tty. Accept this regex as valid input: '^[ ^t]*([Yy]([Ee]([Ss]|)|)|[Nn]([Oo]|))[ ^t]*$'
This commit is contained in:
parent
cfdc87b623
commit
35612bd27c
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.156 -
|
Version 2.02.156 -
|
||||||
================================
|
================================
|
||||||
|
Yes/No prompt accepts '^[ ^t]*([Yy]([Ee]([Ss]|)|)|[Nn]([Oo]|))[ ^t]*$'.
|
||||||
If available, also collect output from lsblk command when running lvmdump -s.
|
If available, also collect output from lsblk command when running lvmdump -s.
|
||||||
Fix regression in blkdeactivate causing dm and md devices to be skipped. (2.02.155)
|
Fix regression in blkdeactivate causing dm and md devices to be skipped. (2.02.155)
|
||||||
|
|
||||||
|
@ -831,50 +831,102 @@ void display_name_error(name_error_t name_error)
|
|||||||
* Prompt for y or n from stdin.
|
* Prompt for y or n from stdin.
|
||||||
* Defaults to 'no' in silent mode.
|
* Defaults to 'no' in silent mode.
|
||||||
* All callers should support --yes and/or --force to override this.
|
* All callers should support --yes and/or --force to override this.
|
||||||
|
*
|
||||||
|
* Accepted are either _yes[] or _no[] strings or just their outset.
|
||||||
|
* When running without 'tty' stdin is printed to stderr.
|
||||||
|
* 'Yes' is accepted ONLY with '\n'.
|
||||||
*/
|
*/
|
||||||
char yes_no_prompt(const char *prompt, ...)
|
char yes_no_prompt(const char *prompt, ...)
|
||||||
{
|
{
|
||||||
int c = 0, ret = 0, cb = 0;
|
/* Lowercase Yes/No strings */
|
||||||
|
static const char _yes[] = "yes";
|
||||||
|
static const char _no[] = "no";
|
||||||
|
const char *answer = NULL;
|
||||||
|
int c = silent_mode() ? EOF : 0;
|
||||||
|
int i, ret = 0, sig = 0;
|
||||||
|
char buf[12];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
sigint_allow();
|
sigint_allow();
|
||||||
do {
|
|
||||||
if (c == '\n' || !c) {
|
for (;;) {
|
||||||
|
if (!ret) {
|
||||||
|
/* Show prompt */
|
||||||
va_start(ap, prompt);
|
va_start(ap, prompt);
|
||||||
vfprintf(stderr, prompt, ap);
|
vfprintf(stderr, prompt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
if (silent_mode()) {
|
|
||||||
fputc('n', stderr);
|
if (c == EOF)
|
||||||
ret = 'n';
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
ret = 0;
|
i = 0;
|
||||||
|
answer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextchar:
|
||||||
|
if ((sig = sigint_caught()))
|
||||||
|
break; /* Check if already interrupted before getchar() */
|
||||||
|
|
||||||
if ((c = getchar()) == EOF) {
|
if ((c = getchar()) == EOF) {
|
||||||
ret = 'n'; /* SIGINT */
|
/* SIGNAL or no chars on stdin (missing '\n') or ^D */
|
||||||
cb = 1;
|
if (!i)
|
||||||
break;
|
break; /* Just shown prompt,-> print [n]\n */
|
||||||
|
|
||||||
|
goto invalid; /* Note: c holds EOF */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((i < (sizeof(buf) - 4)) && isprint(c))
|
||||||
|
buf[i++] = c;
|
||||||
|
|
||||||
c = tolower(c);
|
c = tolower(c);
|
||||||
if ((c == 'y') || (c == 'n')) {
|
|
||||||
/* If both 'y' and 'n' given, begin again. */
|
if ((ret > 0) && (c == answer[0]))
|
||||||
if (ret && c != ret)
|
answer++; /* Matching, next char */
|
||||||
ret = -1;
|
else if (c == '\n') {
|
||||||
else
|
if (feof(stdin))
|
||||||
ret = c;
|
fputc('\n', stderr);
|
||||||
}
|
if (ret > 0)
|
||||||
} while (ret < 1 || c != '\n');
|
break; /* Answered */
|
||||||
|
invalid:
|
||||||
|
if (i >= (sizeof(buf) - 4)) {
|
||||||
|
/* '...' for missing input */
|
||||||
|
i = sizeof(buf) - 1;
|
||||||
|
buf[i - 1] = buf[i - 2] = buf[i - 3] = '.';
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
log_warn("WARNING: Invalid input '%s'.", buf);
|
||||||
|
ret = 0; /* Otherwise refresh prompt */
|
||||||
|
} else if (!ret && (c == _yes[0])) {
|
||||||
|
ret = 'y';
|
||||||
|
answer = _yes + 1; /* Expecting 'Yes' */
|
||||||
|
} else if (!ret && (c == _no[0])) {
|
||||||
|
ret = 'n';
|
||||||
|
answer = _no + 1; /* Expecting 'No' */
|
||||||
|
} else if (!ret && isspace(c)) {
|
||||||
|
/* Ignore any whitespace before */
|
||||||
|
--i;
|
||||||
|
goto nextchar;
|
||||||
|
} else if ((ret > 0) && isspace(c)) {
|
||||||
|
/* Ignore any whitespace after */
|
||||||
|
while (*answer)
|
||||||
|
answer++; /* jump to end-of-word */
|
||||||
|
} else
|
||||||
|
ret = -1; /* Read till '\n' and refresh */
|
||||||
|
}
|
||||||
|
|
||||||
sigint_restore();
|
sigint_restore();
|
||||||
|
|
||||||
if (cb && !sigint_caught())
|
/* For other then Yes answer check there is really no interrupt */
|
||||||
fputc(ret, stderr);
|
if (sig || sigint_caught()) {
|
||||||
|
stack;
|
||||||
if (c != '\n')
|
ret = 'n';
|
||||||
fputc('\n', stderr);
|
} else if (c == EOF) {
|
||||||
|
fputs("[n]\n", stderr);
|
||||||
|
ret = 'n';
|
||||||
|
} else
|
||||||
|
/* Not knowing if it's terminal, makes this hard.... */
|
||||||
|
log_verbose("Accepted input: [%c]", ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user