/*1* $Id: prgbox.c,v 1.14 2019/07/25 00:07:15 tom Exp $2*3* prgbox.c -- implements the prg box4*5* Copyright 2011-2016,2019 Thomas E. Dickey6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU Lesser General Public License, version 2.19* as published by the Free Software Foundation.10*11* This program is distributed in the hope that it will be useful, but12* WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU14* Lesser General Public License for more details.15*16* You should have received a copy of the GNU Lesser General Public17* License along with this program; if not, write to18* Free Software Foundation, Inc.19* 51 Franklin St., Fifth Floor20* Boston, MA 02110, USA.21*/2223#include <dialog.h>2425static void26reapchild(int sig)27{28(void) sig;29}3031/*32* Open a pipe which ties stderr and stdout together.33*/34FILE *35dlg_popen(const char *command, const char *type)36{37FILE *result = 0;38int fd[2];3940if ((*type == 'r' || *type == 'w') && pipe(fd) == 0) {41char *blob;4243switch (fork()) {44case -1: /* Error. */45(void) close(fd[0]);46(void) close(fd[1]);47break;48case 0: /* child. */49if (*type == 'r') {50if (fd[1] != STDOUT_FILENO) {51(void) dup2(fd[1], STDOUT_FILENO);52(void) close(fd[1]);53}54(void) dup2(STDOUT_FILENO, STDERR_FILENO);55(void) close(fd[0]);56} else {57if (fd[0] != STDIN_FILENO) {58(void) dup2(fd[0], STDIN_FILENO);59(void) close(fd[0]);60}61(void) close(fd[1]);62(void) close(STDERR_FILENO);63}64/*65* Bourne shell needs "-c" option to force it to use only the66* given command. Also, it needs the command to be parsed into67* tokens.68*/69if ((blob = malloc(10 + strlen(command))) != 0) {70char **argv;71sprintf(blob, "sh -c \"%s\"", command);72argv = dlg_string_to_argv(blob);73execvp("sh", argv);74}75_exit(127);76/* NOTREACHED */77default: /* parent */78if (*type == 'r') {79result = fdopen(fd[0], type);80(void) close(fd[1]);81} else {82result = fdopen(fd[1], type);83(void) close(fd[0]);84}85break;86}87}8889return result;90}9192/*93* Display text from a pipe in a scrolling window.94*/95int96dialog_prgbox(const char *title,97const char *cprompt,98const char *command,99int height,100int width,101int pauseopt)102{103int code;104FILE *fp;105void (*oldreaper) (int) = signal(SIGCHLD, reapchild);106107fp = dlg_popen(command, "r");108if (fp == NULL)109dlg_exiterr("pipe open failed: %s", command);110111code = dlg_progressbox(title, cprompt, height, width, pauseopt, fp);112113pclose(fp);114signal(SIGCHLD, oldreaper);115116return code;117}118119120