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