mutt stable branch with some hacks
at master 191 lines 3.5 kB view raw
1/* 2 * Copyright (C) 1996-2000 Michael R. Elkins. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19#if HAVE_CONFIG_H 20# include "config.h" 21#endif 22 23#include "mutt.h" 24#include "mutt_curses.h" 25 26#include <unistd.h> 27#include <stdlib.h> 28#include <sys/wait.h> 29 30/* Invokes a command on a pipe and optionally connects its stdin and stdout 31 * to the specified handles. 32 */ 33pid_t 34mutt_create_filter_fd (const char *cmd, FILE **in, FILE **out, FILE **err, 35 int fdin, int fdout, int fderr) 36{ 37 int pin[2], pout[2], perr[2], thepid; 38 char columns[11]; 39 40 if (in) 41 { 42 *in = 0; 43 if (pipe (pin) == -1) 44 return (-1); 45 } 46 47 if (out) 48 { 49 *out = 0; 50 if (pipe (pout) == -1) 51 { 52 if (in) 53 { 54 close (pin[0]); 55 close (pin[1]); 56 } 57 return (-1); 58 } 59 } 60 61 if (err) 62 { 63 *err = 0; 64 if (pipe (perr) == -1) 65 { 66 if (in) 67 { 68 close (pin[0]); 69 close (pin[1]); 70 } 71 if (out) 72 { 73 close (pout[0]); 74 close (pout[1]); 75 } 76 return (-1); 77 } 78 } 79 80 mutt_block_signals_system (); 81 82 if ((thepid = fork ()) == 0) 83 { 84 mutt_unblock_signals_system (0); 85 86 if (in) 87 { 88 close (pin[1]); 89 dup2 (pin[0], 0); 90 close (pin[0]); 91 } 92 else if (fdin != -1) 93 { 94 dup2 (fdin, 0); 95 close (fdin); 96 } 97 98 if (out) 99 { 100 close (pout[0]); 101 dup2 (pout[1], 1); 102 close (pout[1]); 103 } 104 else if (fdout != -1) 105 { 106 dup2 (fdout, 1); 107 close (fdout); 108 } 109 110 if (err) 111 { 112 close (perr[0]); 113 dup2 (perr[1], 2); 114 close (perr[1]); 115 } 116 else if (fderr != -1) 117 { 118 dup2 (fderr, 2); 119 close (fderr); 120 } 121 122 if (MuttIndexWindow && (MuttIndexWindow->cols > 0)) 123 { 124 snprintf (columns, sizeof (columns), "%d", MuttIndexWindow->cols); 125 setenv ("COLUMNS", columns, 1); 126 } 127 128 execl (EXECSHELL, "sh", "-c", cmd, NULL); 129 _exit (127); 130 } 131 else if (thepid == -1) 132 { 133 mutt_unblock_signals_system (1); 134 135 if (in) 136 { 137 close (pin[0]); 138 close (pin[1]); 139 } 140 141 if (out) 142 { 143 close (pout[0]); 144 close (pout[1]); 145 } 146 147 if (err) 148 { 149 close (perr[0]); 150 close (perr[1]); 151 } 152 153 return (-1); 154 } 155 156 if (out) 157 { 158 close (pout[1]); 159 *out = fdopen (pout[0], "r"); 160 } 161 162 if (in) 163 { 164 close (pin[0]); 165 *in = fdopen (pin[1], "w"); 166 } 167 168 if (err) 169 { 170 close (perr[1]); 171 *err = fdopen (perr[0], "r"); 172 } 173 174 return (thepid); 175} 176 177pid_t mutt_create_filter (const char *s, FILE **in, FILE **out, FILE **err) 178{ 179 return (mutt_create_filter_fd (s, in, out, err, -1, -1, -1)); 180} 181 182int mutt_wait_filter (pid_t pid) 183{ 184 int rc; 185 186 waitpid (pid, &rc, 0); 187 mutt_unblock_signals_system (1); 188 rc = WIFEXITED (rc) ? WEXITSTATUS (rc) : -1; 189 190 return rc; 191}