summaryrefslogtreecommitdiff
path: root/packages/klibc/files/dash_readopt.patch
blob: 49bc087eddbe894c9890419e23179ccf9590bd8b (plain)
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
Index: klibc-1.5/usr/dash/miscbltin.c
===================================================================
--- klibc-1.5.orig/usr/dash/miscbltin.c	2008-03-27 20:38:09.354564817 +0100
+++ klibc-1.5/usr/dash/miscbltin.c	2008-04-04 18:05:32.063364195 +0200
@@ -46,6 +46,7 @@
 #include <ctype.h>
 #include <stdint.h>
 #include <time.h>		/* strtotimeval() */
+#include <termios.h>
 
 #include "shell.h"
 #include "options.h"
@@ -83,6 +84,11 @@
 	int timeout;
 	int i;
 	fd_set set;
+	int n_flag = 0;
+	unsigned int nchars = 0;
+	int silent = 0;
+	struct termios tty, old_tty;
+
 	struct timeval ts, t0, t1, to;
 
 	ts.tv_sec = ts.tv_usec = 0;
@@ -90,11 +96,18 @@
 	rflag = 0;
 	timeout = 0;
 	prompt = NULL;
-	while ((i = nextopt("p:rt:")) != '\0') {
+	while ((i = nextopt("p:rt:n:s")) != '\0') {
 		switch(i) {
 		case 'p':
 			prompt = optionarg;
 			break;
+		case 'n':
+			nchars = strtoul(optionarg, NULL, 10);
+			n_flag = nchars; /* just a flag "nchars is nonzero" */
+			break;
+		case 's':
+			silent = 1;
+			break;
 		case 't':
 			p = strtotimeval(optionarg, &ts);
 			if (*p || (!ts.tv_sec && !ts.tv_usec))
@@ -118,6 +131,23 @@
 		sh_error("arg count");
 	if ((ifs = bltinlookup("IFS")) == NULL)
 		ifs = defifs;
+	if (n_flag || silent) {
+		if (tcgetattr(0, &tty) != 0) {
+			/* Not a tty */
+			n_flag = 0;
+			silent = 0;
+		} else {
+			old_tty = tty;
+			if (n_flag) {
+				tty.c_lflag &= ~ICANON;
+				tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
+			}
+			if (silent) {
+				tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
+			}
+			tcsetattr(0, TCSANOW, &tty);
+		}
+	}
 	status = 0;
 	startword = 1;
 	backslash = 0;
@@ -133,13 +163,15 @@
 		ts.tv_sec += t0.tv_sec;
 	}
 	STARTSTACKSTR(p);
-	for (;;) {
+	do {
 		if (timeout) {
 			gettimeofday(&t1, NULL);
 			if (t1.tv_sec > ts.tv_sec ||
 			    (t1.tv_sec == ts.tv_sec &&
 			     t1.tv_usec >= ts.tv_usec)) {
 				status = 1;
+				if (n_flag)
+					tcsetattr(0, TCSANOW, &old_tty);
 				break;	/* Timeout! */
 			}
 
@@ -156,6 +188,8 @@
 			FD_SET(0, &set);
 			if (select(1, &set, NULL, NULL, &to) != 1) {
 				status = 1;
+				if (n_flag)
+					tcsetattr(0, TCSANOW, &old_tty);
 				break; /* Timeout! */
 			}
 		}
@@ -191,7 +225,9 @@
 put:
 			STPUTC(c, p);
 		}
-	}
+	} while (!n_flag || --nchars);
+	if (n_flag || silent)
+		tcsetattr(0, TCSANOW, &old_tty);
 	STACKSTRNUL(p);
 	/* Remove trailing blanks */
 	while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)