peek(1): fix erroring on stdin/stdout redirection
This commit is contained in:
parent
5c70852890
commit
1037e32e6e
40
src/peek.c
40
src/peek.c
@ -62,6 +62,9 @@ usage(char *argv0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
|
bool is_term; /* Is stdin a terminal? */
|
||||||
|
bool must_be_term = 1; /* Must it be? */
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
if (pledge("stdio tty unveil", "") != 0 || unveil(NULL, NULL) != 0) {
|
if (pledge("stdio tty unveil", "") != 0 || unveil(NULL, NULL) != 0) {
|
||||||
/* This isn't fatal; these return values could be cast to void just as
|
/* This isn't fatal; these return values could be cast to void just as
|
||||||
@ -70,37 +73,37 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
is_term = isatty(STDIN_FILENO);
|
||||||
|
|
||||||
if (argc > 0) { /* option parsing */
|
if (argc > 0) { /* option parsing */
|
||||||
bool allow_nonterminals;
|
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
program_name = argv[0];
|
program_name = argv[0];
|
||||||
|
|
||||||
allow_nonterminals = 0;
|
|
||||||
while ((c = getopt(argc, argv, "i")) != -1) {
|
while ((c = getopt(argc, argv, "i")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'i': allow_nonterminals = 1; break;
|
case 'i': must_be_term = 0; break;
|
||||||
default: return usage(argv[0]);
|
default: return usage(argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc > optind) { return usage(argv[0]); }
|
if (argc > optind) { return usage(argv[0]); }
|
||||||
|
}
|
||||||
|
|
||||||
if (!allow_nonterminals && isatty(STDIN_FILENO) != 1) {
|
if (!is_term && must_be_term) {
|
||||||
(void)fprintf(
|
(void)fprintf(
|
||||||
stderr,
|
stderr,
|
||||||
"%s: Must be run in a terminal (specify -i to skip this"
|
"%s: Must be run in a terminal (specify -i to skip this check)\n",
|
||||||
" check)\n",
|
|
||||||
argv[0]
|
argv[0]
|
||||||
);
|
);
|
||||||
return EX_USAGE;
|
return EX_USAGE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (is_term) {
|
||||||
{ /* Install signal handler */
|
{ /* Install signal handler */
|
||||||
/* There isn't a difference in functionality between the signal(2) and
|
/* There isn't a difference in functionality between the signal(2)
|
||||||
* sigaction(2) methods. sigaction(2) is vastly preferred for
|
* and sigaction(2) methods. sigaction(2) is vastly preferred for
|
||||||
* portability but some configurations can only use signal(2). */
|
* portability but some older systems only have signal(2). */
|
||||||
/* Errors aren't terminating because the worst that happens is some
|
/* Errors aren't terminating because the worst that happens is some
|
||||||
* terminal phooeyness if things go awry. */
|
* terminal phooeyness if things go awry. */
|
||||||
#if defined _POSIX_C_SOURCE
|
#if defined _POSIX_C_SOURCE
|
||||||
@ -109,21 +112,26 @@ int main(int argc, char *argv[]){
|
|||||||
act.sa_handler = restore_echo;
|
act.sa_handler = restore_echo;
|
||||||
if (sigaction(SIGINT, &act, NULL) != 0) { perror(program_name); }
|
if (sigaction(SIGINT, &act, NULL) != 0) { perror(program_name); }
|
||||||
#else
|
#else
|
||||||
if (signal(SIGINT, restore_echo) == SIG_ERR) { perror(program_name); }
|
if (signal(SIGINT, restore_echo) == SIG_ERR) {
|
||||||
|
perror(program_name);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Banish terminal echo; this terminates when it fails, because it's the
|
{ /* Banish terminal echo */
|
||||||
* whole point of the program. */
|
/* This terminates when it fails because it's the whole point of
|
||||||
{
|
* the program. */
|
||||||
struct termios t;
|
struct termios t;
|
||||||
|
|
||||||
if (tcgetattr(STDIN_FILENO, &t) != 0) { return ioerr(program_name); }
|
if (tcgetattr(STDIN_FILENO, &t) != 0) {
|
||||||
|
return ioerr(program_name);
|
||||||
|
}
|
||||||
t.c_lflag ^= ECHO;
|
t.c_lflag ^= ECHO;
|
||||||
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) != 0) {
|
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) != 0) {
|
||||||
return ioerr(program_name);
|
return ioerr(program_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{ /* Input loop */
|
{ /* Input loop */
|
||||||
int c;
|
int c;
|
||||||
@ -133,7 +141,7 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_echo(0);
|
if (is_term) { restore_echo(0); }
|
||||||
|
|
||||||
return EX_OK;
|
return EX_OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user