ProvSQL C/C++ API
Adding support for provenance and uncertainty management to PostgreSQL databases
Loading...
Searching...
No Matches
external_tool.h
Go to the documentation of this file.
1/**
2 * @file external_tool.h
3 * @brief Helpers for invoking external command-line tools.
4 *
5 * @c run_external_tool() runs a shell command line with the
6 * @c provsql.tool_search_path GUC, if set, prepended to @c $PATH for the
7 * duration of the call (the server's pre-existing @c PATH is restored
8 * afterwards). The command runs in its own process group so that a
9 * statement_timeout / pg_cancel_backend can stop it: on a pending cancel
10 * the whole group is @c SIGKILLed. Used by the d-DNNF compilers (d4, c2d,
11 * minic2d, dsharp), the model counters, and the graph-easy DOT renderer.
12 *
13 * @c find_external_tool() walks the same locations and reports whether a
14 * given binary is present and executable, so callers can fail with an
15 * actionable error before composing a command line.
16 *
17 * @c format_external_tool_status() decodes a @c system() return value
18 * into a human-readable message that distinguishes "tool not found"
19 * (shell exit 127), "tool not executable" (126), "killed by signal", and
20 * "ran and exited nonzero".
21 *
22 * In the standalone @c tdkc build (when @c TDKC is defined) the GUC layer is
23 * unavailable; the helpers degenerate to a plain @c std::system() call and
24 * a no-op @c find_external_tool.
25 */
26#ifndef PROVSQL_EXTERNAL_TOOL_H
27#define PROVSQL_EXTERNAL_TOOL_H
28
29#include <string>
30
31#ifdef TDKC
32#include <cstdlib>
33inline int run_external_tool(const std::string &cmdline) {
34 return std::system(cmdline.c_str());
35}
36inline std::string find_external_tool(const std::string &) {
37 // No GUC layer in tdkc; assume present and let system() handle missing.
38 return "/dev/null";
39}
40inline std::string format_external_tool_status(int, const std::string &tool) {
41 return "Error executing " + tool;
42}
43#else
44/**
45 * @brief Run a shell command line in its own process group, optionally
46 * extending @c PATH, interruptible by query cancel / statement_timeout.
47 *
48 * If @c provsql_tool_search_path is non-empty, it is prepended (with @c :)
49 * to @c $PATH for the duration and restored afterwards. The command runs
50 * via @c /bin/sh @c -c as a process-group leader; while it runs the parent
51 * polls for a pending cancel/terminate and, if one fires, @c SIGKILLs the
52 * whole group (reaching tools that fork workers) and lets
53 * @c CHECK_FOR_INTERRUPTS raise it.
54 *
55 * @param cmdline Shell command line, passed verbatim to @c /bin/sh -c.
56 * @return A @c wait(2) status (decode with @c WIFEXITED etc., as a
57 * @c system() return), or -1 if @c fork failed.
58 */
59int run_external_tool(const std::string &cmdline);
60
61/**
62 * @brief Locate an external tool by name.
63 *
64 * Searches @c provsql_tool_search_path (colon-separated), then @c $PATH, for
65 * an executable file matching @p name (via @c access(X_OK)). Returns the
66 * full path on success, or the empty string if nothing matches.
67 *
68 * Names containing a slash are treated as paths and tested directly without
69 * any directory walk.
70 *
71 * @param name Bare executable name (e.g. @c "d4") or a path.
72 * @return Resolved path, or @c "" if @p name is not found.
73 */
74std::string find_external_tool(const std::string &name);
75
76/**
77 * @brief Decode a @c system() return value into a human-readable message.
78 *
79 * @param rv Return value from @c system() (or @c run_external_tool()).
80 * @param tool Tool name, used as the message subject.
81 * @return Empty string when @p rv indicates success; otherwise a
82 * message that distinguishes "not found at runtime"
83 * (shell exit 127), "not executable" (126), "killed by
84 * signal N", "exited with status N", or @c system()
85 * itself failing.
86 */
87std::string format_external_tool_status(int rv, const std::string &tool);
88
89namespace provsql { struct ToolRecord; }
90
91/**
92 * @brief True iff a registry tool can currently be used.
93 *
94 * A @c kcmcp record needs a configured @c endpoint (no live connect probe,
95 * mirroring how a CLI tool only needs its binary on PATH). A @c cli record
96 * needs its @c binary (when set) and every dependency to resolve on the
97 * backend's PATH via @c find_external_tool. This is the single availability
98 * predicate consulted both by the compile/wmc tool selection and by the
99 * @c provsql.tools view.
100 */
101bool toolAvailable(const provsql::ToolRecord &rec);
102#endif
103
104#endif
int run_external_tool(const std::string &cmdline)
Run a shell command line in its own process group, optionally extending PATH, interruptible by query ...
std::string format_external_tool_status(int rv, const std::string &tool)
Decode a system() return value into a human-readable message.
bool toolAvailable(const provsql::ToolRecord &rec)
True iff a registry tool can currently be used.
std::string find_external_tool(const std::string &name)
Locate an external tool by name.
One registered external tool.