Change #if by #ifdef in mutt.h
[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 <unistd.h>
15 #include <stdlib.h>
16 #include <sys/wait.h>
17
18 #include <lib-sys/mutt_signal.h>
19
20 #include "mutt.h"
21
22 /* Invokes a commmand on a pipe and optionally connects its stdin and stdout
23  * to the specified handles.
24  */
25 pid_t
26 mutt_create_filter_fd (const char *cmd, FILE ** in, FILE ** out, FILE ** err,
27                        int fdin, int fdout, int fderr)
28 {
29   int pin[2], pout[2], perr[2], thepid;
30
31   if (in) {
32     *in = 0;
33     if (pipe (pin) == -1)
34       return (-1);
35   }
36
37   if (out) {
38     *out = 0;
39     if (pipe (pout) == -1) {
40       if (in) {
41         close (pin[0]);
42         close (pin[1]);
43       }
44       return (-1);
45     }
46   }
47
48   if (err) {
49     *err = 0;
50     if (pipe (perr) == -1) {
51       if (in) {
52         close (pin[0]);
53         close (pin[1]);
54       }
55       if (out) {
56         close (pout[0]);
57         close (pout[1]);
58       }
59       return (-1);
60     }
61   }
62
63   mutt_block_signals_system ();
64
65   if ((thepid = fork ()) == 0) {
66     mutt_unblock_signals_system (0);
67
68     if (in) {
69       close (pin[1]);
70       dup2 (pin[0], 0);
71       close (pin[0]);
72     }
73     else if (fdin != -1) {
74       dup2 (fdin, 0);
75       close (fdin);
76     }
77
78     if (out) {
79       close (pout[0]);
80       dup2 (pout[1], 1);
81       close (pout[1]);
82     }
83     else if (fdout != -1) {
84       dup2 (fdout, 1);
85       close (fdout);
86     }
87
88     if (err) {
89       close (perr[0]);
90       dup2 (perr[1], 2);
91       close (perr[1]);
92     }
93     else if (fderr != -1) {
94       dup2 (fderr, 2);
95       close (fderr);
96     }
97
98     execl ("/bin/sh", "sh", "-c", cmd, NULL);
99     _exit (127);
100   }
101   else if (thepid == -1) {
102     mutt_unblock_signals_system (1);
103
104     if (in) {
105       close (pin[0]);
106       close (pin[1]);
107     }
108
109     if (out) {
110       close (pout[0]);
111       close (pout[1]);
112     }
113
114     if (err) {
115       close (perr[0]);
116       close (perr[1]);
117     }
118
119     return (-1);
120   }
121
122   if (out) {
123     close (pout[1]);
124     *out = fdopen (pout[0], "r");
125   }
126
127   if (in) {
128     close (pin[0]);
129     *in = fdopen (pin[1], "w");
130   }
131
132   if (err) {
133     close (perr[1]);
134     *err = fdopen (perr[0], "r");
135   }
136
137   return (thepid);
138 }
139
140 pid_t mutt_create_filter (const char *s, FILE ** in, FILE ** out, FILE ** err)
141 {
142   return (mutt_create_filter_fd (s, in, out, err, -1, -1, -1));
143 }
144
145 int mutt_wait_filter (pid_t pid)
146 {
147   int rc;
148
149   waitpid (pid, &rc, 0);
150   mutt_unblock_signals_system (1);
151   rc = WIFEXITED (rc) ? WEXITSTATUS (rc) : -1;
152
153   return rc;
154 }