NeoMutt  2020-09-25
Teaching an old dog new tricks
DOXYGEN
filter.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stdbool.h>
31 #include <stdlib.h>
32 #include <sys/wait.h>
33 #include <unistd.h>
34 #include "filter.h"
35 #include "envlist.h"
36 #include "signal2.h"
37 
61 pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out,
62  FILE **fp_err, int fdin, int fdout, int fderr)
63 {
64  int pin[2], pout[2], perr[2], pid;
65 
66  if (fp_in)
67  {
68  *fp_in = NULL;
69  if (pipe(pin) == -1)
70  return -1;
71  }
72 
73  if (fp_out)
74  {
75  *fp_out = NULL;
76  if (pipe(pout) == -1)
77  {
78  if (fp_in)
79  {
80  close(pin[0]);
81  close(pin[1]);
82  }
83  return -1;
84  }
85  }
86 
87  if (fp_err)
88  {
89  *fp_err = NULL;
90  if (pipe(perr) == -1)
91  {
92  if (fp_in)
93  {
94  close(pin[0]);
95  close(pin[1]);
96  }
97  if (fp_out)
98  {
99  close(pout[0]);
100  close(pout[1]);
101  }
102  return -1;
103  }
104  }
105 
107 
108  pid = fork();
109  if (pid == 0)
110  {
112 
113  if (fp_in)
114  {
115  close(pin[1]);
116  dup2(pin[0], 0);
117  close(pin[0]);
118  }
119  else if (fdin != -1)
120  {
121  dup2(fdin, 0);
122  close(fdin);
123  }
124 
125  if (fp_out)
126  {
127  close(pout[0]);
128  dup2(pout[1], 1);
129  close(pout[1]);
130  }
131  else if (fdout != -1)
132  {
133  dup2(fdout, 1);
134  close(fdout);
135  }
136 
137  if (fp_err)
138  {
139  close(perr[0]);
140  dup2(perr[1], 2);
141  close(perr[1]);
142  }
143  else if (fderr != -1)
144  {
145  dup2(fderr, 2);
146  close(fderr);
147  }
148 
149  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
150  _exit(127);
151  }
152  else if (pid == -1)
153  {
155 
156  if (fp_in)
157  {
158  close(pin[0]);
159  close(pin[1]);
160  }
161 
162  if (fp_out)
163  {
164  close(pout[0]);
165  close(pout[1]);
166  }
167 
168  if (fp_err)
169  {
170  close(perr[0]);
171  close(perr[1]);
172  }
173 
174  return -1;
175  }
176 
177  if (fp_out)
178  {
179  close(pout[1]);
180  *fp_out = fdopen(pout[0], "r");
181  }
182 
183  if (fp_in)
184  {
185  close(pin[0]);
186  *fp_in = fdopen(pin[1], "w");
187  }
188 
189  if (fp_err)
190  {
191  close(perr[1]);
192  *fp_err = fdopen(perr[0], "r");
193  }
194 
195  return pid;
196 }
197 
206 pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
207 {
208  return filter_create_fd(cmd, fp_in, fp_out, fp_err, -1, -1, -1);
209 }
210 
217 int filter_wait(pid_t pid)
218 {
219  int rc = 0;
220 
221  waitpid(pid, &rc, 0);
223  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
224 
225  return rc;
226 }
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
Pass files through external commands (filters)
#define EXEC_SHELL
Definition: filter.h:27
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
Private copy of the environment variables.
pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:61
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169
Signal handling.