NeoMutt  2019-11-11
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 65 of file filter.c.

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  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
154  _exit(127);
155  }
156  else if (pid == -1)
157  {
159 
160  if (fp_in)
161  {
162  close(pin[0]);
163  close(pin[1]);
164  }
165 
166  if (fp_out)
167  {
168  close(pout[0]);
169  close(pout[1]);
170  }
171 
172  if (fp_err)
173  {
174  close(perr[0]);
175  close(perr[1]);
176  }
177 
178  return -1;
179  }
180 
181  if (fp_out)
182  {
183  close(pout[1]);
184  *fp_out = fdopen(pout[0], "r");
185  }
186 
187  if (fp_in)
188  {
189  close(pin[0]);
190  *fp_in = fdopen(pin[1], "w");
191  }
192 
193  if (fp_err)
194  {
195  close(perr[1]);
196  *fp_err = fdopen(perr[0], "r");
197  }
198 
199  return pid;
200 }
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:168
+ 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 210 of file filter.c.

211 {
212  return mutt_create_filter_fd(s, fp_in, fp_out, fp_err, -1, -1, -1);
213 }
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
+ 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 221 of file filter.c.

222 {
223  int rc;
224 
225  waitpid(pid, &rc, 0);
227  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
228 
229  return rc;
230 }
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 245 of file filter.c.

246 {
247  int rc;
248 
249 #ifdef USE_IMAP
250  rc = imap_wait_keepalive(pid);
251 #else
252  waitpid(pid, &rc, 0);
253 #endif
255  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
256 
257  return rc;
258 }
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:1086
+ Here is the call graph for this function: