diff options
-rwxr-xr-x | vellum | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/vellum b/vellum index b436b6c..aee12d5 100755 --- a/vellum +++ b/vellum | |||
@@ -1,7 +1,7 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | # https://unix.stackexchange.com/a/464963 | ||
4 | readc() { # arg: <variable-name> | 3 | readc() { # arg: <variable-name> |
4 | # adapted from https://unix.stackexchange.com/a/464963 | ||
5 | if [ -t 0 ]; then | 5 | if [ -t 0 ]; then |
6 | # if stdin is a tty device, put it out of icanon, set min and | 6 | # if stdin is a tty device, put it out of icanon, set min and |
7 | # time to sane value, but don't otherwise touch other input or | 7 | # time to sane value, but don't otherwise touch other input or |
@@ -10,21 +10,36 @@ readc() { # arg: <variable-name> | |||
10 | saved_tty_settings=$(stty -g) | 10 | saved_tty_settings=$(stty -g) |
11 | stty -icanon min 1 time 0 | 11 | stty -icanon min 1 time 0 |
12 | fi | 12 | fi |
13 | eval "$1=" | 13 | |
14 | while | 14 | # Sanitize any variable that's passed in |
15 | # read one byte, using a work around for the fact that command | 15 | case "$1" in |
16 | # substitution strips the last character. | 16 | c) var=_c ;; |
17 | c=$(dd bs=1 count=1 2> /dev/null; echo .) | 17 | var) var=_var ;; |
18 | '') var=REPLY ;; | ||
19 | *) var="$1" ;; | ||
20 | esac | ||
21 | |||
22 | # Zero-out the variable | ||
23 | eval "$var=" | ||
24 | |||
25 | # Read one full *character*, not *byte* | ||
26 | while :; do | ||
27 | c=$(dd bs=1 count=1 2>/dev/null; echo .) | ||
18 | c=${c%.} | 28 | c=${c%.} |
19 | 29 | ||
20 | # break out of the loop on empty input (eof) or if a full character | 30 | # Break on EOF |
21 | # has been accumulated in the output variable (using "wc -m" to count | 31 | test -n "$c" || break |
22 | # the number of characters). | 32 | |
23 | [ -n "$c" ] && | 33 | eval "$var=\${$var}$c" |
24 | eval "$1=\${$1}"'$c | 34 | |
25 | [ "$(($(printf %s "${'"$1"'}" | wc -m)))" -eq 0 ]'; do | 35 | # Break when we have a full character (wc -m) |
26 | continue | 36 | test "$(eval printf %s "\$$var" | wc -m)" -eq 0 || break |
27 | done | 37 | done |
38 | |||
39 | # Round-trip sanitized variables | ||
40 | test "x$var" = x_c && eval c="\$$var" | ||
41 | test "x$var" = x_var && eval var="\$$var" | ||
42 | |||
28 | if [ -t 0 ]; then | 43 | if [ -t 0 ]; then |
29 | # restore settings saved earlier if stdin is a tty device. | 44 | # restore settings saved earlier if stdin is a tty device. |
30 | stty "$saved_tty_settings" | 45 | stty "$saved_tty_settings" |