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