]> diplodocus.org Git - nmh/blob - sbr/m_popen.c
Alter mh-chart(7)'s NAME to be lowercase.
[nmh] / sbr / m_popen.c
1
2 /*
3 * m_popen.c -- Interface for a popen() call that redirects the current
4 * process standard output to the popen()d process.
5 *
6 * This code is Copyright (c) 2014, by the authors of nmh. See the
7 * COPYRIGHT file in the root directory of the nmh distribution for
8 * complete copyright information.
9 */
10
11 #include <h/mh.h>
12 #include <h/signals.h>
13
14 static int m_pid = NOTOK; /* Process we're waiting for */
15 static int sd = NOTOK; /* Original standard output */
16
17 /*
18 * Fork a process and redirect our standard output to that process
19 */
20
21 void
22 m_popen (char *name, int savestdout)
23 {
24 int pd[2];
25 char *file;
26 char **arglist;
27
28 if (savestdout && (sd = dup (fileno (stdout))) == NOTOK)
29 adios ("standard output", "unable to dup()");
30
31 if (pipe (pd) == NOTOK)
32 adios ("pipe", "unable to");
33
34 switch (m_pid = fork()) {
35 case NOTOK:
36 adios ("fork", "unable to");
37
38 case OK:
39 SIGNAL (SIGINT, SIG_DFL);
40 SIGNAL (SIGQUIT, SIG_DFL);
41
42 close (pd[1]);
43 if (pd[0] != fileno (stdin)) {
44 dup2 (pd[0], fileno (stdin));
45 close (pd[0]);
46 }
47 arglist = argsplit(name, &file, NULL);
48 execvp (file, arglist);
49 fprintf (stderr, "unable to exec ");
50 perror (name);
51 _exit (-1);
52
53 default:
54 close (pd[0]);
55 if (pd[1] != fileno (stdout)) {
56 dup2 (pd[1], fileno (stdout));
57 close (pd[1]);
58 }
59 }
60 }
61
62
63 void
64 m_pclose (void)
65 {
66 if (m_pid == NOTOK)
67 return;
68
69 if (sd != NOTOK) {
70 fflush (stdout);
71 if (dup2 (sd, fileno (stdout)) == NOTOK)
72 adios ("standard output", "unable to dup2()");
73
74 clearerr (stdout);
75 close (sd);
76 sd = NOTOK;
77 }
78 else
79 fclose (stdout);
80
81 pidwait (m_pid, OK);
82 m_pid = NOTOK;
83 }