NeoMutt  2018-07-16 +2481-68dcde
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 "mutt/mutt.h"
35 #include "mutt.h"
36 #include "filter.h"
37 #include "mutt_window.h"
38 #ifdef USE_IMAP
39 #include "imap/imap.h"
40 #endif
41 
65 pid_t mutt_create_filter_fd(const char *cmd, FILE **fp_in, FILE **fp_out,
66  FILE **fp_err, int fdin, int fdout, int fderr)
67 {
68  int pin[2], pout[2], perr[2], pid;
69 
70  if (fp_in)
71  {
72  *fp_in = NULL;
73  if (pipe(pin) == -1)
74  return -1;
75  }
76 
77  if (fp_out)
78  {
79  *fp_out = NULL;
80  if (pipe(pout) == -1)
81  {
82  if (fp_in)
83  {
84  close(pin[0]);
85  close(pin[1]);
86  }
87  return -1;
88  }
89  }
90 
91  if (fp_err)
92  {
93  *fp_err = NULL;
94  if (pipe(perr) == -1)
95  {
96  if (fp_in)
97  {
98  close(pin[0]);
99  close(pin[1]);
100  }
101  if (fp_out)
102  {
103  close(pout[0]);
104  close(pout[1]);
105  }
106  return -1;
107  }
108  }
109 
111 
112  pid = fork();
113  if (pid == 0)
114  {
116 
117  if (fp_in)
118  {
119  close(pin[1]);
120  dup2(pin[0], 0);
121  close(pin[0]);
122  }
123  else if (fdin != -1)
124  {
125  dup2(fdin, 0);
126  close(fdin);
127  }
128 
129  if (fp_out)
130  {
131  close(pout[0]);
132  dup2(pout[1], 1);
133  close(pout[1]);
134  }
135  else if (fdout != -1)
136  {
137  dup2(fdout, 1);
138  close(fdout);
139  }
140 
141  if (fp_err)
142  {
143  close(perr[0]);
144  dup2(perr[1], 2);
145  close(perr[1]);
146  }
147  else if (fderr != -1)
148  {
149  dup2(fderr, 2);
150  close(fderr);
151  }
152 
153  if (MuttIndexWindow && (MuttIndexWindow->cols > 0))
154  {
155  char columns[16];
156  snprintf(columns, sizeof(columns), "%d", MuttIndexWindow->cols);
157  mutt_envlist_set("COLUMNS", columns, true);
158  }
159 
160  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
161  _exit(127);
162  }
163  else if (pid == -1)
164  {
166 
167  if (fp_in)
168  {
169  close(pin[0]);
170  close(pin[1]);
171  }
172 
173  if (fp_out)
174  {
175  close(pout[0]);
176  close(pout[1]);
177  }
178 
179  if (fp_err)
180  {
181  close(perr[0]);
182  close(perr[1]);
183  }
184 
185  return -1;
186  }
187 
188  if (fp_out)
189  {
190  close(pout[1]);
191  *fp_out = fdopen(pout[0], "r");
192  }
193 
194  if (fp_in)
195  {
196  close(pin[0]);
197  *fp_in = fdopen(pin[1], "w");
198  }
199 
200  if (fp_err)
201  {
202  close(perr[1]);
203  *fp_err = fdopen(perr[0], "r");
204  }
205 
206  return pid;
207 }
208 
217 pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
218 {
219  return mutt_create_filter_fd(s, fp_in, fp_out, fp_err, -1, -1, -1);
220 }
221 
228 int mutt_wait_filter(pid_t pid)
229 {
230  int rc;
231 
232  waitpid(pid, &rc, 0);
234  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
235 
236  return rc;
237 }
238 
253 {
254  int rc;
255 
256 #ifdef USE_IMAP
257  rc = imap_wait_keepalive(pid);
258 #else
259  waitpid(pid, &rc, 0);
260 #endif
262  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
263 
264  return rc;
265 }
pid_t mutt_create_filter(const char *s, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:217
Window management.
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
Pass files through external commands (filters)
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
IMAP network mailbox.
#define EXEC_SHELL
Definition: mutt.h:139
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:40
pid_t mutt_create_filter_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:65
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:84
int mutt_wait_filter(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:228
int mutt_wait_interactive_filter(pid_t pid)
Wait after an interactive filter.
Definition: filter.c:252
Convenience wrapper for the library headers.
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1076
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:167