1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
/* $OpenBSD: input.c,v 1.2 2012/07/10 10:28:05 nicm Exp $ */
/*
* Copyright (c) 2012 Nicholas Marriott <nicm@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "cu.h"
/*
* Prompt and read a line of user input from stdin. We want to use the termios
* we were started with so restore and stick in a signal handler for ^C.
*/
volatile sig_atomic_t input_stop;
void input_signal(int);
void
input_signal(int sig)
{
input_stop = 1;
}
const char *
get_input(const char *prompt)
{
static char s[BUFSIZ];
struct sigaction act, oact;
char c, *cp, *out = NULL;
ssize_t n;
memset(&act, 0, sizeof(act));
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_handler = input_signal;
if (sigaction(SIGINT, &act, &oact) != 0)
cu_err(1, "sigaction");
input_stop = 0;
restore_termios();
printf("%s ", prompt);
fflush(stdout);
cp = s;
while (cp != s + sizeof(s) - 1) {
n = read(STDIN_FILENO, &c, 1);
if (n == -1 && errno != EINTR)
cu_err(1, "read");
if (n != 1 || input_stop)
break;
if (c == '\n') {
out = s;
break;
}
if (!iscntrl((u_char)c))
*cp++ = c;
}
*cp = '\0';
set_termios();
sigaction(SIGINT, &oact, NULL);
return (out);
}
|