commit e265dd06984e4208214afd6e1415a162a37e73a4
Author: Pavel Sanda <[email protected]>
Date: Tue Sep 8 21:42:02 2026 +0200
Probe the python interpreter without a shell
Reroute python_call() and python_info() to startscriptArgv() so
os.cpp is left with no runCommand().
Adds new os::pythonArgvForm() for the argv-form callers.
Tier 01 DiD / argv 03a: python argv probe
https://www.mail-archive.com/[email protected]/msg226780.html
Assisted-by: Claude Opus 5
---
src/support/os.cpp | 48 +++++++++++++++++++++++++++++++++++++++++-------
src/support/os.h | 5 +++++
2 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/src/support/os.cpp b/src/support/os.cpp
index 08c3f347d6..a368f037e5 100644
--- a/src/support/os.cpp
+++ b/src/support/os.cpp
@@ -19,6 +19,7 @@
#include "support/debug.h"
#include "support/filetools.h"
#include "support/qstring_helpers.h"
+#include "support/Systemcall.h"
#include <QDir>
@@ -58,20 +59,33 @@ int timeout_ms()
static string const python_call(string const & binary, bool verbose = false)
{
- const string version_info = " -c \"import sys;
print(sys.version_info[:2], end='')\"";
+ const string version_script = "import sys; print(sys.version_info[:2],
end='')";
// Default to "python3" if no binary is given.
if (binary.empty())
return "python3";
if (verbose)
lyxerr << "Examining " << binary << "\n";
- // Check whether this is a python 2 or 3 binary.
- cmd_ret const out = runCommand(binary + version_info);
+ // Check whether this is a python 2 or 3 binary. The candidate may be
+ // a bare name ("python3"), a name plus argument ("py -3") or a quoted
+ // absolute path found with walking-path fallback; split it into argv
+ // so the probe never goes through a shell.
+ vector<string> argv = splitCommandTokens(binary);
+ if (argv.empty())
+ return string();
+ string const program = argv.front();
+ argv.erase(argv.begin());
+ argv.push_back("-c");
+ argv.push_back(version_script);
+
+ Systemcall one;
+ string result;
+ int const ret = one.startscriptArgv(program, argv, &result);
smatch sm;
try {
static regex const python_reg("\\((\\d*), (\\d*)\\)");
- if (!out.valid || !regex_match(out.result, sm, python_reg))
+ if (ret != Systemcall::OK || !regex_match(result, sm,
python_reg))
return string();
} catch(regex_error const & /*e*/) {
LYXERR0("Regex error! This should not happen.");
@@ -88,7 +102,7 @@ static string const python_call(string const & binary, bool
verbose = false)
return string();
if (verbose)
- lyxerr << "Found Python " << out.result << "\n";
+ lyxerr << "Found Python " << result << "\n";
return binary;
}
@@ -162,12 +176,32 @@ bool hasPython()
return !(python_call(python()).empty());
}
+vector<string> pythonArgvForm()
+{
+ return splitCommandTokens(python());
+}
+
+
+// consumers: About dialog
string const python_info()
{
- const string info_version = " -c \"import sys; print('{}
({})'.format(sys.version.split()[0],sys.executable), end='')\"";
+ const string info_script = "import sys; print('{}
({})'.format(sys.version.split()[0],sys.executable), end='')";
if (!hasPython())
return("None");
- return (runCommand(python() + info_version).result);
+
+ vector<string> argv = pythonArgvForm();
+ if (argv.empty())
+ return("None");
+ string const program = argv.front();
+ argv.erase(argv.begin());
+ argv.push_back("-c");
+ argv.push_back(info_script);
+
+ Systemcall one;
+ string result;
+ if (one.startscriptArgv(program, argv, &result) != Systemcall::OK)
+ return("None");
+ return result;
}
} // namespace os
diff --git a/src/support/os.h b/src/support/os.h
index 1b664e4444..c4c6e10419 100644
--- a/src/support/os.h
+++ b/src/support/os.h
@@ -16,6 +16,7 @@
#include "support/docstring.h"
#include <cstddef>
+#include <vector>
namespace lyx {
@@ -62,6 +63,10 @@ int timeout_ms();
/// @param reset True if the python path should be recomputed
std::string const python(bool reset = false);
+/// Take python() output and split it into program + leading arguments, for
invocation
+/// via Systemcall::startscriptArgv (no shell, no command-line re-parsing).
+std::vector<std::string> pythonArgvForm();
+
/// Check for availability of the python interpreter
bool hasPython();
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs