aboutsummaryrefslogtreecommitdiff
path: root/builtins/functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtins/functions.c')
-rw-r--r--builtins/functions.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/builtins/functions.c b/builtins/functions.c
index 27bb06f8..b69f81d9 100644
--- a/builtins/functions.c
+++ b/builtins/functions.c
@@ -246,6 +246,48 @@ public void say(Text_t text, bool newline)
fputc('\n', stdout);
}
+public Text_t ask(Text_t prompt, bool bold, bool force_tty)
+{
+ Text_t ret = Text("");
+ FILE *out = stdout;
+ FILE *in = stdin;
+
+ if (force_tty && !isatty(STDOUT_FILENO)) {
+ out = fopen("/dev/tty", "w");
+ if (!out) goto cleanup;
+ }
+
+ if (bold) fputs("\x1b[1m", out);
+ Text$print(out, prompt);
+ if (bold) fputs("\x1b[m", out);
+ fflush(out);
+
+ if (force_tty && !isatty(STDIN_FILENO)) {
+ in = fopen("/dev/tty", "r");
+ if (!in) goto cleanup;
+ }
+
+ char *line = NULL;
+ size_t bufsize = 0;
+ ssize_t length = getline(&line, &bufsize, in);
+ if (length == -1) goto cleanup;
+
+ if (length > 0 && line[length-1] == '\n') {
+ line[length-1] = '\0';
+ --length;
+ }
+
+ char *gc_input = GC_MALLOC_ATOMIC(length + 1);
+ memcpy(gc_input, line, length + 1);
+
+ ret = Text$from_strn(gc_input, length);
+
+ cleanup:
+ if (out && out != stdout) fclose(out);
+ if (in && in != stdin) fclose(in);
+ return ret;
+}
+
public bool pop_flag(char **argv, int *i, const char *flag, Text_t *result)
{
if (argv[*i][0] != '-' || argv[*i][1] != '-') {