]> diplodocus.org Git - nmh/blob - sbr/m_popen.c
new.c: Order two return statements to match comment.
[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 #include "m_popen.h"
12
13 static int m_pid = NOTOK; /* Process we're waiting for */
14 static int sd = NOTOK; /* Original standard output */
15
16 /*
17 * Fork a process and redirect our standard output to that process
18 */
19
20 void
21 m_popen (char *name, int savestdout)
22 {
23 int pd[2];
24 char *file;
25 char **arglist;
26
27 if (savestdout && (sd = dup (fileno (stdout))) == NOTOK)
28 adios ("standard output", "unable to dup()");
29
30 if (pipe (pd) == NOTOK)
31 adios ("pipe", "unable to");
32
33 switch (m_pid = fork()) {
34 case NOTOK:
35 adios ("fork", "unable to");
36
37 case OK:
38 SIGNAL (SIGINT, SIG_DFL);
39 SIGNAL (SIGQUIT, SIG_DFL);
40
41 close (pd[1]);
42 if (pd[0] != fileno (stdin)) {
43 dup2 (pd[0], fileno (stdin));
44 close (pd[0]);
45 }
46 arglist = argsplit(name, &file, NULL);
47 execvp (file, arglist);
48 fprintf (stderr, "unable to exec ");
49 perror (name);
50 _exit (-1);
51
52 default:
53 close (pd[0]);
54 if (pd[1] != fileno (stdout)) {
55 dup2 (pd[1], fileno (stdout));
56 close (pd[1]);
57 }
58 }
59 }
60
61
62 void
63 m_pclose (void)
64 {
65 if (m_pid == NOTOK)
66 return;
67
68 if (sd != NOTOK) {
69 fflush (stdout);
70 if (dup2 (sd, fileno (stdout)) == NOTOK)
71 adios ("standard output", "unable to dup2()");
72
73 clearerr (stdout);
74 close (sd);
75 sd = NOTOK;
76 }
77 else
78 fclose (stdout);
79
80 pidwait (m_pid, OK);
81 m_pid = NOTOK;
82 }