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