1cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Subprocesses with pipes. 2cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2005-2012 Free Software Foundation, Inc. 4cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify 6cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project it under the terms of the GNU General Public License as published by 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation, either version 3 of the License, or 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 9cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 10cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project This program is distributed in the hope that it will be useful, 11cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project but WITHOUT ANY WARRANTY; without even the implied warranty of 12cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project GNU General Public License for more details. 14cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 15cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project You should have received a copy of the GNU General Public License 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 18cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Written by Juan Manuel Guerrero <juan.guerrero@gmx.de>. */ 19cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 20cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h> 22cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 23cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "subpipe.h" 24cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 25cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <errno.h> 26cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <fcntl.h> 27cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <sys/stat.h> 28cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <process.h> 29cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <signal.h> 30cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdio.h> 31cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdlib.h> 32cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <string.h> 33cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <unistd.h> 34cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "xalloc.h" 35cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 36cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 37cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifndef STDIN_FILENO 38cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define STDIN_FILENO 0 39cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif 40cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifndef STDOUT_FILENO 41cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define STDOUT_FILENO 1 42cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif 43cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 44cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 45cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "error.h" 46cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 47cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "gettext.h" 48cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define _(Msgid) gettext (Msgid) 49cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 50cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 51cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Initialize this module. */ 52cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 53cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 54cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic int old_stdin; 55cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic int old_stdout; 56cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic char **arguments; 57cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic char tmp_file_name[2][L_tmpnam]; 58cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 59cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#define remove_tmp_file(fd, name) \ 60cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project do { \ 61cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close ((fd)); \ 62cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (unlink ((name))) \ 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang error (EXIT_FAILURE, 0, _("removing of '%s' failed"), (name)); \ 64cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } while (0) 65cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 66cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 67cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid 68cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectinit_subpipe(void) 69cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *tmpdir; 71cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int fd; 72cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang tmpdir = getenv("TMPDIR"); 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (tmpdir == NULL) 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang tmpdir = getenv("TMP"); 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (tmpdir == NULL) 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang tmpdir = getenv("TEMP"); 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (access(tmpdir, D_OK)) 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang tmpdir = "."; 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang strcpy(tmp_file_name[0], tmpdir); 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang strcat(tmp_file_name[0], "/bnXXXXXX"); 83cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project fd = mkstemp(tmp_file_name[0]); 84cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (fd < 0) 85cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("creation of a temporary file failed")); 86cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close (fd); 87cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang strcpy(tmp_file_name[1], tmpdir); 8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang strcat(tmp_file_name[1], "/bnXXXXXX"); 90cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project fd = mkstemp(tmp_file_name[1]); 91cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (fd < 0) 92cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("creation of a temporary file failed")); 93cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close (fd); 94cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 95cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 96cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 97cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Create a subprocess that is run as a filter. ARGV is the 98cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project NULL-terminated argument vector for the subprocess. Store read and 99cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project write file descriptors for communication with the subprocess into 100cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project FD[0] and FD[1]: input meant for the process can be written into 101cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project FD[0], and output from the process can be read from FD[1]. Return 102cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project the subprocess id. 103cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 104cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project Because DOS has neither fork nor pipe functionality to run the subprocess 105cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project as a filter, the filter is reproduced using temporary files. First bison's 106cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project stdout is redirected to a temporary file. After bison has produced all of 107cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project is output, this file is closed and connected to m4's stdin. All m4's output 108cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project is redirected from m4's stdout to a second temporary file and reopened as 109cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project bison's stdin. */ 110cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 111cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectpid_t 112cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectcreate_subpipe(char const *const *argv, int fd[2]) 113cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 114cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int argc; 115cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int from_in_fd; /* pipe from bison to m4. */ 116cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project pid_t pid; 117cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 118cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 119cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project pid = getpid(); 120cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 121cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 122cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * Save original stdin and stdout 123cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * for later restauration. 124cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 125cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project old_stdin = dup(STDIN_FILENO); 126cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (old_stdin < 0) 127cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("saving stdin failed")); 128cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 129cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project old_stdout = dup(STDOUT_FILENO); 130cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (old_stdout < 0) 131cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("saving stdout failed")); 132cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 133cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 134cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * Save argv for later use. 135cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 136cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project for (argc = 0; argv[argc]; argc++) 137cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project ; 138cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project argc++; 139cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project arguments = xmalloc(argc * sizeof(arguments[0])); 140cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project for (argc = 0; argv[argc]; argc++) 141cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 142cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project arguments[argc] = xmalloc((strlen(argv[argc]) + 1) * sizeof(arguments[0][0])); 143cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project strcpy(arguments[argc], argv[argc]); 144cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 145cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project arguments[argc] = NULL; 146cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 147cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 148cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * All bison's output will be gathered in this temporary file 149cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * and will be redirected to m4's stdin. 150cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 151cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project from_in_fd = open(tmp_file_name[0], O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR); 152cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (from_in_fd < 0) 153cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("opening of tmpfile failed")); 154cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dup2(from_in_fd, STDOUT_FILENO) < 0) 155cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 156cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(from_in_fd, tmp_file_name[0]); 157cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("redirecting bison's stdout to the temporary file failed")); 158cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 159cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close(from_in_fd); 160cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 161cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 162cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project fd[0] = STDOUT_FILENO; 163cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project return pid; 164cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 165cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 166cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 167cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* A signal handler that just records that a signal has happened. */ 168cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic int child_interrupted; 169cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 170cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void 171cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectsignal_catcher(int signo) 172cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 173cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project child_interrupted++; 174cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 175cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 176cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 177cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid 178cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectend_of_output_subpipe(pid_t pid, int fd[2]) 179cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 180cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project char *program; 181cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int from_out_fd = open(tmp_file_name[0], O_RDONLY, S_IRUSR); /* pipe from bison to m4. */ 182cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int to_in_fd = open(tmp_file_name[1], O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR); /* pipe from m4 to bison. */ 183cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int status; 184cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project void (*previous_handler)(int); 185cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 186cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 187cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project program = strrchr(arguments[0], '/'); 188cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (program) 189cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project program++; 190cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project else 191cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project program = arguments[0]; 192cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 193cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 194cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * Redirect bison's output to m4's stdin. 195cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 196cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (from_out_fd < 0) 197cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("opening of tmpfile failed")); 198cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dup2(from_out_fd, STDIN_FILENO) < 0) 199cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 200cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(from_out_fd, tmp_file_name[0]); 201cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("redirecting m4's stdin from the temporary file failed")); 202cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 203cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close(from_out_fd); 204cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 205cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 206cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * All m4's output will be gathered in this temporary file 207cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * and will be redirected to bison's stdin. 208cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 209cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (to_in_fd < 0) 210cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 211cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDIN_FILENO, tmp_file_name[0]); 212cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("opening of a temporary file failed")); 213cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 214cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dup2(to_in_fd, STDOUT_FILENO) < 0) 215cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 216cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDIN_FILENO, tmp_file_name[0]); 217cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(to_in_fd, tmp_file_name[1]); 218cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("redirecting m4's stdout to a temporary file failed")); 219cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 220cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close(to_in_fd); 221cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 222cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 223cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * Run m4. 224cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 225cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project child_interrupted = 0; 226cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project errno = 0; 227cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project previous_handler = signal(SIGINT, signal_catcher); 228cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project status = spawnvp(P_WAIT, program, arguments); 229cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project signal(SIGINT, previous_handler); 230cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (child_interrupted) 231cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 232cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDIN_FILENO, tmp_file_name[0]); 233cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDOUT_FILENO, tmp_file_name[1]); 23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang error(EXIT_FAILURE, 0, _("subsidiary program '%s' interrupted"), program); 235cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 236cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (status) 237cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 238cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDIN_FILENO, tmp_file_name[0]); 239cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDOUT_FILENO, tmp_file_name[1]); 240cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _(errno == ENOENT 24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang ? "subsidiary program '%s' not found" 242cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project : status < 1 24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang ? "subsidiary program '%s' failed" 24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang : "subsidiary program '%s' failed (status=%i, errno=%i)"), program, status, errno); 245cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 246cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 247cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 248cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project /* 249cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project * Redirect m4's output to bison's stdin. 250cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project */ 251cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dup2(old_stdout, STDOUT_FILENO) < 0) 252cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, "restore of bison's stdout failed"); 253cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close(old_stdout); 254cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project to_in_fd = open(tmp_file_name[1], O_RDONLY, S_IRUSR); /* pipe from m4 to bison. */ 255cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (to_in_fd < 0) 256cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 257cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDIN_FILENO, tmp_file_name[0]); 258cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("opening of tmpfile failed")); 259cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 260cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dup2(to_in_fd, STDIN_FILENO) < 0) 261cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project { 262cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(STDIN_FILENO, tmp_file_name[0]); 263cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project remove_tmp_file(to_in_fd, tmp_file_name[1]); 264cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, -1, "dup2"); 265cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, _("redirecting bison's stdin from the temporary file failed")); 266cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project } 267cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close(to_in_fd); 268cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 269cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 270cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project fd[1] = STDIN_FILENO; 271cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 272cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 273cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 274cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Free resources, unlink temporary files and restore stdin and stdout. */ 275cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 276cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid 277cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectreap_subpipe(pid_t pid, char const *program) 278cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{ 279cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project int argc; 280cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 281cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project for (argc = 0; arguments[argc]; argc++) 282cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project free(arguments[argc]); 283cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project free(arguments); 284cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 285cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (unlink(tmp_file_name[0])) 28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang error(EXIT_FAILURE, 0, _("removing of '%s' failed"), tmp_file_name[0]); 287cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (unlink(tmp_file_name[1])) 28805436638acc7c010349a69c3395f1a57c642dc62Ying Wang error(EXIT_FAILURE, 0, _("removing of '%s' failed"), tmp_file_name[1]); 289cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project 290cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project if (dup2(old_stdin, STDIN_FILENO) < 0) 291cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project error(EXIT_FAILURE, 0, "restore of bison's stdin failed"); 292cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project close(old_stdin); 293cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project} 294