aboutsummaryrefslogtreecommitdiff
path: root/contrib/dialog/prgbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dialog/prgbox.c')
-rw-r--r--contrib/dialog/prgbox.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/contrib/dialog/prgbox.c b/contrib/dialog/prgbox.c
new file mode 100644
index 000000000000..fea23936db9a
--- /dev/null
+++ b/contrib/dialog/prgbox.c
@@ -0,0 +1,111 @@
+/*
+ * $Id: prgbox.c,v 1.6 2011/03/02 09:59:26 tom Exp $
+ *
+ * prgbox.c -- implements the prg box
+ *
+ * Copyright 2011 Thomas E. Dickey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to
+ * Free Software Foundation, Inc.
+ * 51 Franklin St., Fifth Floor
+ * Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+
+/*
+ * Open a pipe which ties stderr and stdout together.
+ */
+static FILE *
+dlg_popen(const char *command, const char *type)
+{
+ FILE *result = 0;
+ int fd[2];
+ int pid;
+ char *blob;
+ char **argv;
+
+ if ((*type == 'r' || *type != 'w') && pipe(fd) == 0) {
+ switch (pid = fork()) {
+ case -1: /* Error. */
+ (void) close(fd[0]);
+ (void) close(fd[1]);
+ break;
+ case 0: /* child. */
+ if (*type == 'r') {
+ if (fd[1] != STDOUT_FILENO) {
+ (void) dup2(fd[1], STDOUT_FILENO);
+ (void) close(fd[1]);
+ }
+ (void) dup2(STDOUT_FILENO, STDERR_FILENO);
+ (void) close(fd[0]);
+ } else {
+ if (fd[0] != STDIN_FILENO) {
+ (void) dup2(fd[0], STDIN_FILENO);
+ (void) close(fd[0]);
+ }
+ (void) close(fd[1]);
+ (void) close(STDERR_FILENO);
+ }
+ /*
+ * Bourne shell needs "-c" option to force it to use only the
+ * given command. Also, it needs the command to be parsed into
+ * tokens.
+ */
+ if ((blob = malloc(4 + strlen(command))) != 0) {
+ sprintf(blob, "-c %s", command);
+ argv = dlg_string_to_argv(blob);
+ execvp("sh", argv);
+ }
+ _exit(127);
+ /* NOTREACHED */
+ default: /* parent */
+ if (*type == 'r') {
+ result = fdopen(fd[0], type);
+ (void) close(fd[1]);
+ } else {
+ result = fdopen(fd[1], type);
+ (void) close(fd[0]);
+ }
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Display text from a pipe in a scrolling window.
+ */
+int
+dialog_prgbox(const char *title,
+ const char *cprompt,
+ const char *command,
+ int height,
+ int width,
+ int pauseopt)
+{
+ int code;
+ FILE *fp;
+
+ fp = dlg_popen(command, "r");
+ if (fp == NULL)
+ dlg_exiterr("pipe open failed: %s", command);
+
+ code = dlg_progressbox(title, cprompt, height, width, pauseopt, fp);
+
+ pclose(fp);
+
+ return code;
+}