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