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