NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
filter.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stdbool.h>
31#include <stdlib.h>
32#include <sys/wait.h>
33#include <unistd.h>
34#include "filter.h"
35#include "envlist.h"
36#include "signal2.h"
37
61pid_t filter_create_fd(const char *cmd, FILE **fp_in, FILE **fp_out,
62 FILE **fp_err, int fdin, int fdout, int fderr)
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}
197
206pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
207{
208 return filter_create_fd(cmd, fp_in, fp_out, fp_err, -1, -1, -1);
209}
210
217int filter_wait(pid_t pid)
218{
219 int rc = 0;
220
221 waitpid(pid, &rc, 0);
223 rc = WIFEXITED(rc) ? WEXITSTATUS(rc) : -1;
224
225 return rc;
226}
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169
Private copy of the environment variables.
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
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
Pass files through external commands (filters)
#define EXEC_SHELL
Definition: filter.h:27
Signal handling.
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