1220747Snwhitehorn/* 2251843Sbapt * $Id: prgbox.c,v 1.9 2012/12/02 23:40:30 tom Exp $ 3220747Snwhitehorn * 4220747Snwhitehorn * prgbox.c -- implements the prg box 5220747Snwhitehorn * 6251843Sbapt * Copyright 2011,2012 Thomas E. Dickey 7220747Snwhitehorn * 8220747Snwhitehorn * This program is free software; you can redistribute it and/or modify 9224014Snwhitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10224014Snwhitehorn * as published by the Free Software Foundation. 11220747Snwhitehorn * 12220747Snwhitehorn * This program is distributed in the hope that it will be useful, but 13220747Snwhitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14220747Snwhitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15220747Snwhitehorn * Lesser General Public License for more details. 16220747Snwhitehorn * 17220747Snwhitehorn * You should have received a copy of the GNU Lesser General Public 18220747Snwhitehorn * License along with this program; if not, write to 19220747Snwhitehorn * Free Software Foundation, Inc. 20220747Snwhitehorn * 51 Franklin St., Fifth Floor 21220747Snwhitehorn * Boston, MA 02110, USA. 22220747Snwhitehorn */ 23220747Snwhitehorn 24220747Snwhitehorn#include <dialog.h> 25220747Snwhitehorn 26251843Sbaptstatic void 27251843Sbaptreapchild(int sig) 28251843Sbapt{ 29251843Sbapt (void) sig; 30251843Sbapt} 31251843Sbapt 32220747Snwhitehorn/* 33220747Snwhitehorn * Open a pipe which ties stderr and stdout together. 34220747Snwhitehorn */ 35220747Snwhitehornstatic FILE * 36220747Snwhitehorndlg_popen(const char *command, const char *type) 37220747Snwhitehorn{ 38220747Snwhitehorn FILE *result = 0; 39220747Snwhitehorn int fd[2]; 40251843Sbapt char *blob; 41251843Sbapt char **argv; 42220747Snwhitehorn 43220747Snwhitehorn if ((*type == 'r' || *type != 'w') && pipe(fd) == 0) { 44251843Sbapt switch (fork()) { 45220747Snwhitehorn case -1: /* Error. */ 46220747Snwhitehorn (void) close(fd[0]); 47220747Snwhitehorn (void) close(fd[1]); 48220747Snwhitehorn break; 49220747Snwhitehorn case 0: /* child. */ 50220747Snwhitehorn if (*type == 'r') { 51220747Snwhitehorn if (fd[1] != STDOUT_FILENO) { 52220747Snwhitehorn (void) dup2(fd[1], STDOUT_FILENO); 53220747Snwhitehorn (void) close(fd[1]); 54220747Snwhitehorn } 55220747Snwhitehorn (void) dup2(STDOUT_FILENO, STDERR_FILENO); 56220747Snwhitehorn (void) close(fd[0]); 57220747Snwhitehorn } else { 58220747Snwhitehorn if (fd[0] != STDIN_FILENO) { 59220747Snwhitehorn (void) dup2(fd[0], STDIN_FILENO); 60220747Snwhitehorn (void) close(fd[0]); 61220747Snwhitehorn } 62220747Snwhitehorn (void) close(fd[1]); 63220747Snwhitehorn (void) close(STDERR_FILENO); 64220747Snwhitehorn } 65220747Snwhitehorn /* 66220747Snwhitehorn * Bourne shell needs "-c" option to force it to use only the 67220747Snwhitehorn * given command. Also, it needs the command to be parsed into 68220747Snwhitehorn * tokens. 69220747Snwhitehorn */ 70251843Sbapt if ((blob = malloc(4 + strlen(command))) != 0) { 71251843Sbapt sprintf(blob, "-c %s", command); 72251843Sbapt argv = dlg_string_to_argv(blob); 73251843Sbapt execvp("sh", argv); 74251843Sbapt } 75220747Snwhitehorn _exit(127); 76220747Snwhitehorn /* NOTREACHED */ 77220747Snwhitehorn default: /* parent */ 78220747Snwhitehorn if (*type == 'r') { 79220747Snwhitehorn result = fdopen(fd[0], type); 80220747Snwhitehorn (void) close(fd[1]); 81220747Snwhitehorn } else { 82220747Snwhitehorn result = fdopen(fd[1], type); 83220747Snwhitehorn (void) close(fd[0]); 84220747Snwhitehorn } 85220747Snwhitehorn break; 86220747Snwhitehorn } 87220747Snwhitehorn } 88220747Snwhitehorn 89220747Snwhitehorn return result; 90220747Snwhitehorn} 91220747Snwhitehorn 92220747Snwhitehorn/* 93220747Snwhitehorn * Display text from a pipe in a scrolling window. 94220747Snwhitehorn */ 95220747Snwhitehornint 96220747Snwhitehorndialog_prgbox(const char *title, 97220747Snwhitehorn const char *cprompt, 98220747Snwhitehorn const char *command, 99220747Snwhitehorn int height, 100220747Snwhitehorn int width, 101220747Snwhitehorn int pauseopt) 102220747Snwhitehorn{ 103220747Snwhitehorn int code; 104220747Snwhitehorn FILE *fp; 105251843Sbapt void (*oldreaper) (int) = signal(SIGCHLD, reapchild); 106220747Snwhitehorn 107220747Snwhitehorn fp = dlg_popen(command, "r"); 108220747Snwhitehorn if (fp == NULL) 109220747Snwhitehorn dlg_exiterr("pipe open failed: %s", command); 110220747Snwhitehorn 111220747Snwhitehorn code = dlg_progressbox(title, cprompt, height, width, pauseopt, fp); 112220747Snwhitehorn 113220747Snwhitehorn pclose(fp); 114251843Sbapt signal(SIGCHLD, oldreaper); 115220747Snwhitehorn 116220747Snwhitehorn return code; 117220747Snwhitehorn} 118