Index gzip-compressed SVG files
[xapian.git] / xapian-applications / omega / runfilter.h
blob0488c5d30d3b946e7173b04f38997d3c1d3f9231
1 /** @file
2 * @brief run an external filter and capture its output in a std::string.
3 */
4 /* Copyright (C) 2007,2013,2015 Olly Betts
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef OMEGA_INCLUDED_RUNFILTER_H
22 #define OMEGA_INCLUDED_RUNFILTER_H
24 #include <string>
25 #include <cstdio>
27 /// Exception thrown if we encounter a read error.
28 struct ReadError {
29 const char * msg;
30 int status;
31 explicit ReadError(const char * m) : msg(m) { }
32 explicit ReadError(int s) : msg(NULL), status(s) { }
33 std::string str() const { if (msg) return msg; char buf[32]; std::sprintf(buf, "0x%08x", status); return buf; }
36 /// Exception thrown if the filter program isn't found.
37 struct NoSuchFilter { };
39 /** Analyse if a command needs the shell.
41 * The return value of this function can be passed as the second argument of
42 * run_filter()/stdout_to_string().
44 bool command_needs_shell(const char * p);
46 /// Initialise the runfilter module.
47 void runfilter_init();
49 /** Run command @a cmd, optionally capturing its stdout.
51 * @param fd_in FD for piped input, or -1 for input from file.
52 * @param cmd The command to run.
53 * @param use_shell If false, try to avoid using a shell to run the command.
54 * @param out Pointer to std::string to put stdout in or NULL to
55 * discard stdout. (default: NULL)
56 * @param alt_status Exit status to treat as success in addition to 0
57 * (default: Only treat exit status 0 as success).
59 * Note: use_shell=false mode makes some assumptions about the command:
61 * * only single quotes are used (double quotes and backslash quoting are
62 * not currently handled, aside from in the four character sequence '\''
63 * within single quotes).
64 * * the following redirections are supported, but they must be unquoted and
65 * appear exactly as shown, and each be a separate word in the command:
66 * >/dev/null 2>/dev/null 2>&1 1>&2
67 * * environment variables set before the command are handled correctly,
68 * for example: LANG=C some-command
70 * The command_needs_shell() function above can be used to check a command,
71 * but is somewhat more conservative than what this function actually
72 * supports.
74 * Currently the shell is only actually avoided for systems with both fork()
75 * and socketpair(). Other systems will ignore use_shell and always use the
76 * same code path (which may or may not involve some analog of the Unix
77 * shell).
79 * If the command isn't installed (detected by exit status 127) then
80 * NoSuchFilter is thrown.
82 * If the command fails to completed successfully (detected by an exit status
83 * other than 0 or alt_status) then ReadError is thrown.
85 void run_filter(int fd_in,
86 const std::string& cmd,
87 bool use_shell,
88 std::string* out = nullptr,
89 int alt_status = 0);
91 static inline void
92 run_filter(const std::string& cmd,
93 bool use_shell,
94 std::string* out = nullptr,
95 int alt_status = 0)
97 run_filter(-1, cmd, use_shell, out, alt_status);
100 /** Run command @a cmd, capture its stdout, and return it as a std::string.
102 * This is a simple wrapper around run_filter().
104 static inline std::string
105 stdout_to_string(const std::string& cmd, bool use_shell, int alt_status = 0)
107 std::string out;
108 run_filter(cmd, use_shell, &out, alt_status);
109 return out;
112 #endif // OMEGA_INCLUDED_RUNFILTER_H