peek(1): fix erroring on stdin/stdout redirection

This commit is contained in:
dtb 2024-08-31 22:19:13 -06:00
parent 5c70852890
commit 1037e32e6e
Signed by: trinity
GPG Key ID: 34C0543BBB6AF81B

View File

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