missing include
[apps/madmutt.git] / filter.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 1996-2000 Michael R. Elkins.
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #if HAVE_CONFIG_H
11 # include "config.h"
12 #endif
13
14 #include "mutt.h"
15
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <sys/wait.h>
19
20 /* Invokes a commmand on a pipe and optionally connects its stdin and stdout
21  * to the specified handles.
22  */
23 pid_t
24 mutt_create_filter_fd (const char *cmd, FILE ** in, FILE ** out, FILE ** err,
25                        int fdin, int fdout, int fderr)
26 {
27   int pin[2], pout[2], perr[2], thepid;
28
29   if (in) {
30     *in = 0;
31     if (pipe (pin) == -1)
32       return (-1);
33   }
34
35   if (out) {
36     *out = 0;
37     if (pipe (pout) == -1) {
38       if (in) {
39         close (pin[0]);
40         close (pin[1]);
41       }
42       return (-1);
43     }
44   }
45
46   if (err) {
47     *err = 0;
48     if (pipe (perr) == -1) {
49       if (in) {
50         close (pin[0]);
51         close (pin[1]);
52       }
53       if (out) {
54         close (pout[0]);
55         close (pout[1]);
56       }
57       return (-1);
58     }
59   }
60
61   mutt_block_signals_system ();
62
63   if ((thepid = fork ()) == 0) {
64     mutt_unblock_signals_system (0);
65
66     if (in) {
67       close (pin[1]);
68       dup2 (pin[0], 0);
69       close (pin[0]);
70     }
71     else if (fdin != -1) {
72       dup2 (fdin, 0);
73       close (fdin);
74     }
75
76     if (out) {
77       close (pout[0]);
78       dup2 (pout[1], 1);
79       close (pout[1]);
80     }
81     else if (fdout != -1) {
82       dup2 (fdout, 1);
83       close (fdout);
84     }
85
86     if (err) {
87       close (perr[0]);
88       dup2 (perr[1], 2);
89       close (perr[1]);
90     }
91     else if (fderr != -1) {
92       dup2 (fderr, 2);
93       close (fderr);
94     }
95
96     execl (EXECSHELL, "sh", "-c", cmd, NULL);
97     _exit (127);
98   }
99   else if (thepid == -1) {
100     mutt_unblock_signals_system (1);
101
102     if (in) {
103       close (pin[0]);
104       close (pin[1]);
105     }
106
107     if (out) {
108       close (pout[0]);
109       close (pout[1]);
110     }
111
112     if (err) {
113       close (perr[0]);
114       close (perr[1]);
115     }
116
117     return (-1);
118   }
119
120   if (out) {
121     close (pout[1]);
122     *out = fdopen (pout[0], "r");
123   }
124
125   if (in) {
126     close (pin[0]);
127     *in = fdopen (pin[1], "w");
128   }
129
130   if (err) {
131     close (perr[1]);
132     *err = fdopen (perr[0], "r");
133   }
134
135   return (thepid);
136 }
137
138 pid_t mutt_create_filter (const char *s, FILE ** in, FILE ** out, FILE ** err)
139 {
140   return (mutt_create_filter_fd (s, in, out, err, -1, -1, -1));
141 }
142
143 int mutt_wait_filter (pid_t pid)
144 {
145   int rc;
146
147   waitpid (pid, &rc, 0);
148   mutt_unblock_signals_system (1);
149   rc = WIFEXITED (rc) ? WEXITSTATUS (rc) : -1;
150
151   return rc;
152 }