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