NeoMutt  2020-11-20
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.

Macros

#define EXEC_SHELL   "/bin/sh"
 

Functions

pid_t filter_create (const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
 Set up filter program. More...
 
pid_t filter_create_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...
 
int filter_wait (pid_t pid)
 Wait for the exit of a process and return its status. 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.

Macro Definition Documentation

◆ EXEC_SHELL

#define EXEC_SHELL   "/bin/sh"

Definition at line 27 of file filter.h.

Function Documentation

◆ filter_create()

pid_t filter_create ( const char *  cmd,
FILE **  fp_in,
FILE **  fp_out,
FILE **  fp_err 
)

Set up filter program.

Parameters
[in]cmdCommand 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 206 of file filter.c.

207 {
208  return filter_create_fd(cmd, fp_in, fp_out, fp_err, -1, -1, -1);
209 }
pid_t filter_create_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:61
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ filter_create_fd()

pid_t filter_create_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.

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

63 {
64  int pin[2], pout[2], perr[2], pid;
65 
66  if (fp_in)
67  {
68  *fp_in = NULL;
69  if (pipe(pin) == -1)
70  return -1;
71  }
72 
73  if (fp_out)
74  {
75  *fp_out = NULL;
76  if (pipe(pout) == -1)
77  {
78  if (fp_in)
79  {
80  close(pin[0]);
81  close(pin[1]);
82  }
83  return -1;
84  }
85  }
86 
87  if (fp_err)
88  {
89  *fp_err = NULL;
90  if (pipe(perr) == -1)
91  {
92  if (fp_in)
93  {
94  close(pin[0]);
95  close(pin[1]);
96  }
97  if (fp_out)
98  {
99  close(pout[0]);
100  close(pout[1]);
101  }
102  return -1;
103  }
104  }
105 
107 
108  pid = fork();
109  if (pid == 0)
110  {
112 
113  if (fp_in)
114  {
115  close(pin[1]);
116  dup2(pin[0], 0);
117  close(pin[0]);
118  }
119  else if (fdin != -1)
120  {
121  dup2(fdin, 0);
122  close(fdin);
123  }
124 
125  if (fp_out)
126  {
127  close(pout[0]);
128  dup2(pout[1], 1);
129  close(pout[1]);
130  }
131  else if (fdout != -1)
132  {
133  dup2(fdout, 1);
134  close(fdout);
135  }
136 
137  if (fp_err)
138  {
139  close(perr[0]);
140  dup2(perr[1], 2);
141  close(perr[1]);
142  }
143  else if (fderr != -1)
144  {
145  dup2(fderr, 2);
146  close(fderr);
147  }
148 
149  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
150  _exit(127);
151  }
152  else if (pid == -1)
153  {
155 
156  if (fp_in)
157  {
158  close(pin[0]);
159  close(pin[1]);
160  }
161 
162  if (fp_out)
163  {
164  close(pout[0]);
165  close(pout[1]);
166  }
167 
168  if (fp_err)
169  {
170  close(perr[0]);
171  close(perr[1]);
172  }
173 
174  return -1;
175  }
176 
177  if (fp_out)
178  {
179  close(pout[1]);
180  *fp_out = fdopen(pout[0], "r");
181  }
182 
183  if (fp_in)
184  {
185  close(pin[0]);
186  *fp_in = fdopen(pin[1], "w");
187  }
188 
189  if (fp_err)
190  {
191  close(perr[1]);
192  *fp_err = fdopen(perr[0], "r");
193  }
194 
195  return pid;
196 }
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
#define EXEC_SHELL
Definition: filter.h:27
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
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:

◆ filter_wait()

int filter_wait ( 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 217 of file filter.c.

218 {
219  int rc = 0;
220 
221  waitpid(pid, &rc, 0);
223  rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
224 
225  return rc;
226 }
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: