NeoMutt  2018-07-16 +952-a2da0a
Teaching an old dog new tricks
DOXYGEN
filter.c File Reference

Pass files through external commands (filters) More...

#include "config.h"
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "mutt.h"
#include "filter.h"
#include "mutt_window.h"
#include "imap/imap.h"
+ Include dependency graph for filter.c:

Go to the source code of this file.

Functions

pid_t mutt_create_filter_fd (const char *cmd, FILE **in, FILE **out, FILE **err, int fdin, int fdout, int fderr)
 Run a command on a pipe (optionally connect stdin/stdout) More...
 
pid_t mutt_create_filter (const char *s, FILE **in, FILE **out, FILE **err)
 Set up filter program. More...
 
int mutt_wait_filter (pid_t pid)
 Wait for the exit of a process and return its status. More...
 
int mutt_wait_interactive_filter (pid_t pid)
 Wait after an interactive filter. More...
 

Detailed Description

Pass files through external commands (filters)

Authors
  • Michael R. Elkins.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file filter.c.

Function Documentation

pid_t mutt_create_filter_fd ( const char *  cmd,
FILE **  in,
FILE **  out,
FILE **  err,
int  fdin,
int  fdout,
int  fderr 
)

Run a command on a pipe (optionally connect stdin/stdout)

Parameters
cmdCommand line to invoke using sh -c
inFile stream pointing to stdin for the command process, can be NULL
outFile stream pointing to stdout for the command process, can be NULL
errFile stream pointing to stderr for the command process, can be NULL
fdinIf in is NULL and fdin is not -1 then fdin will be used as stdin for the command process
fdoutIf out is NULL and fdout is not -1 then fdout will be used as stdout for the command process
fderrIf error is NULL and fderr is not -1 then fderr will be used as stderr for the command process
Return values
numPID of the created process
-1Error creating pipes or forking

This function provides multiple mechanisms to handle IO sharing for the command process. File streams are prioritized over file descriptors if present.

mutt_create_filter_fd(commandline, NULL, NULL, NULL, -1, -1, -1);

Additionally, in, out, and err will point to FILE* streams representing the processes stdin, stdout, and stderr.

Definition at line 64 of file filter.c.

66 {
67  int pin[2], pout[2], perr[2], thepid;
68 
69  if (in)
70  {
71  *in = 0;
72  if (pipe(pin) == -1)
73  return -1;
74  }
75 
76  if (out)
77  {
78  *out = 0;
79  if (pipe(pout) == -1)
80  {
81  if (in)
82  {
83  close(pin[0]);
84  close(pin[1]);
85  }
86  return -1;
87  }
88  }
89 
90  if (err)
91  {
92  *err = 0;
93  if (pipe(perr) == -1)
94  {
95  if (in)
96  {
97  close(pin[0]);
98  close(pin[1]);
99  }
100  if (out)
101  {
102  close(pout[0]);
103  close(pout[1]);
104  }
105  return -1;
106  }
107  }
108 
110 
111  thepid = fork();
112  if (thepid == 0)
113  {
115 
116  if (in)
117  {
118  close(pin[1]);
119  dup2(pin[0], 0);
120  close(pin[0]);
121  }
122  else if (fdin != -1)
123  {
124  dup2(fdin, 0);
125  close(fdin);
126  }
127 
128  if (out)
129  {
130  close(pout[0]);
131  dup2(pout[1], 1);
132  close(pout[1]);
133  }
134  else if (fdout != -1)
135  {
136  dup2(fdout, 1);
137  close(fdout);
138  }
139 
140  if (err)
141  {
142  close(perr[0]);
143  dup2(perr[1], 2);
144  close(perr[1]);
145  }
146  else if (fderr != -1)
147  {
148  dup2(fderr, 2);
149  close(fderr);
150  }
151 
152  if (MuttIndexWindow && (MuttIndexWindow->cols > 0))
153  {
154  char columns[11];
155  snprintf(columns, sizeof(columns), "%d", MuttIndexWindow->cols);
156  mutt_envlist_set("COLUMNS", columns, 1);
157  }
158 
159  execle(EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
160  _exit(127);
161  }
162  else if (thepid == -1)
163  {
165 
166  if (in)
167  {
168  close(pin[0]);
169  close(pin[1]);
170  }
171 
172  if (out)
173  {
174  close(pout[0]);
175  close(pout[1]);
176  }
177 
178  if (err)
179  {
180  close(perr[0]);
181  close(perr[1]);
182  }
183 
184  return -1;
185  }
186 
187  if (out)
188  {
189  close(pout[1]);
190  *out = fdopen(pout[0], "r");
191  }
192 
193  if (in)
194  {
195  close(pin[0]);
196  *in = fdopen(pin[1], "w");
197  }
198 
199  if (err)
200  {
201  close(perr[1]);
202  *err = fdopen(perr[0], "r");
203  }
204 
205  return thepid;
206 }
void mutt_sig_unblock_system(bool catch)
Restore previously blocked signals.
Definition: signal.c:200
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:176
struct MuttWindow * MuttIndexWindow
Index Window.
Definition: mutt_window.c:39
#define EXECSHELL
Definition: mutt.h:205
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:84
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:165

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

pid_t mutt_create_filter ( const char *  s,
FILE **  in,
FILE **  out,
FILE **  err 
)

Set up filter program.

Parameters
[in]sCommand string
[out]inFILE pointer of stdin
[out]outFILE pointer of stdout
[out]errFILE pointer of stderr
Return values
numPID of filter

Definition at line 216 of file filter.c.

217 {
218  return mutt_create_filter_fd(s, in, out, err, -1, -1, -1);
219 }
pid_t mutt_create_filter_fd(const char *cmd, FILE **in, FILE **out, FILE **err, int fdin, int fdout, int fderr)
Run a command on a pipe (optionally connect stdin/stdout)
Definition: filter.c:64

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_wait_filter ( pid_t  pid)

Wait for the exit of a process and return its status.

Parameters
pidProcess id of the process to wait for
Return values
numExit status of the process identified by pid
-1Error

Definition at line 227 of file filter.c.

228 {
229  int rc;
230 
231  waitpid(pid, &rc, 0);
233  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
234 
235  return rc;
236 }
void mutt_sig_unblock_system(bool catch)
Restore previously blocked signals.
Definition: signal.c:200

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_wait_interactive_filter ( pid_t  pid)

Wait after an interactive filter.

Parameters
pidProcess id of the process to wait for
Return values
numExit status of the process identified by pid
-1Error

This is used for filters that are actually interactive commands with input piped in: e.g. in mutt_view_attachment(), a mailcap entry without copiousoutput and without a s.

For those cases, we treat it like a blocking system command, and poll IMAP to keep connections open.

Definition at line 251 of file filter.c.

252 {
253  int rc;
254 
255 #ifdef USE_IMAP
256  rc = imap_wait_keepalive(pid);
257 #else
258  waitpid(pid, &rc, 0);
259 #endif
261  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
262 
263  return rc;
264 }
void mutt_sig_unblock_system(bool catch)
Restore previously blocked signals.
Definition: signal.c:200
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1086

+ Here is the call graph for this function: