NeoMutt  2019-12-07-60-g0cfa53
Teaching an old dog new tricks
DOXYGEN
filter.c File Reference

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

#include "config.h"
#include <stdbool.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include "mutt/mutt.h"
#include "mutt.h"
#include "filter.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 **fp_in, FILE **fp_out, FILE **fp_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 **fp_in, FILE **fp_out, FILE **fp_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

◆ mutt_create_filter_fd()

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)

Parameters
[in]cmdCommand line to invoke using sh -c
[out]fp_inFile stream pointing to stdin for the command process, can be NULL
[out]fp_outFile stream pointing to stdout for the command process, can be NULL
[out]fp_errFile stream pointing to stderr for the command process, can be NULL
[in]fdinIf in is NULL and fdin is not -1 then fdin will be used as stdin for the command process
[in]fdoutIf out is NULL and fdout is not -1 then fdout will be used as stdout for the command process
[in]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, fp_in, fp_out, and fp_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], pid;
68 
69  if (fp_in)
70  {
71  *fp_in = NULL;
72  if (pipe(pin) == -1)
73  return -1;
74  }
75 
76  if (fp_out)
77  {
78  *fp_out = NULL;
79  if (pipe(pout) == -1)
80  {
81  if (fp_in)
82  {
83  close(pin[0]);
84  close(pin[1]);
85  }
86  return -1;
87  }
88  }
89 
90  if (fp_err)
91  {
92  *fp_err = NULL;
93  if (pipe(perr) == -1)
94  {
95  if (fp_in)
96  {
97  close(pin[0]);
98  close(pin[1]);
99  }
100  if (fp_out)
101  {
102  close(pout[0]);
103  close(pout[1]);
104  }
105  return -1;
106  }
107  }
108 
110 
111  pid = fork();
112  if (pid == 0)
113  {
115 
116  if (fp_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 (fp_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 (fp_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  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
153  _exit(127);
154  }
155  else if (pid == -1)
156  {
158 
159  if (fp_in)
160  {
161  close(pin[0]);
162  close(pin[1]);
163  }
164 
165  if (fp_out)
166  {
167  close(pout[0]);
168  close(pout[1]);
169  }
170 
171  if (fp_err)
172  {
173  close(perr[0]);
174  close(perr[1]);
175  }
176 
177  return -1;
178  }
179 
180  if (fp_out)
181  {
182  close(pout[1]);
183  *fp_out = fdopen(pout[0], "r");
184  }
185 
186  if (fp_in)
187  {
188  close(pin[0]);
189  *fp_in = fdopen(pin[1], "w");
190  }
191 
192  if (fp_err)
193  {
194  close(perr[1]);
195  *fp_err = fdopen(perr[0], "r");
196  }
197 
198  return pid;
199 }
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
#define EXEC_SHELL
Definition: mutt.h:124
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_create_filter()

pid_t mutt_create_filter ( const char *  s,
FILE **  fp_in,
FILE **  fp_out,
FILE **  fp_err 
)

Set up filter program.

Parameters
[in]sCommand string
[out]fp_inFILE pointer of stdin
[out]fp_outFILE pointer of stdout
[out]fp_errFILE pointer of stderr
Return values
numPID of filter

Definition at line 209 of file filter.c.

210 {
211  return mutt_create_filter_fd(s, fp_in, fp_out, fp_err, -1, -1, -1);
212 }
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:64
+ Here is the caller graph for this function:

◆ mutt_wait_filter()

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 220 of file filter.c.

221 {
222  int rc;
223 
224  waitpid(pid, &rc, 0);
226  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
227 
228  return rc;
229 }
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
+ Here is the caller graph for this function:

◆ mutt_wait_interactive_filter()

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 244 of file filter.c.

245 {
246  int rc;
247 
248 #ifdef USE_IMAP
249  rc = imap_wait_keepalive(pid);
250 #else
251  waitpid(pid, &rc, 0);
252 #endif
254  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
255 
256  return rc;
257 }
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1090
+ Here is the call graph for this function: