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

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

#include <stdio.h>
#include <unistd.h>
+ Include dependency graph for filter.h:
+ This graph shows which files directly or indirectly include this file:

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

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.h.

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 call graph for this function:
+ 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 call graph for this function:
+ 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: