[PATCH] clang-tools: Import os for broken pipe handling
From: houtinghang
Date: Wed Sep 23 2026 - 10:38:04 EST
The BrokenPipeError handler in run-clang-tools.py calls os.open() and
os.dup2() without importing os. When the analysis pool raises this
exception, the handler raises NameError instead of redirecting stdout
and exiting with status 1.
Import os and add a regression test that injects BrokenPipeError from
Pool.map(), then checks the redirection and exit status.
Fixes: 87c7ee67deb7 ("scripts: handle BrokenPipeError for python scripts")
Assisted-by: LLM
Signed-off-by: houtinghang <ue081723@xxxxxxxxx>
---
Testing: python scripts/clang-tools/run-clang-tools_test.py -v
The test fails before the import with NameError and passes after it.
Tested with Python 3.13 on Windows using exception injection; no complete
kernel build or real clang-tidy pipeline test was performed.
AI disclosure: Codex found the missing import, wrote the fix and test,
ran the test, reviewed the diff, and drafted this message in response to
a request to find, fix, review and submit a Linux kernel bug.
scripts/clang-tools/run-clang-tools.py | 1 +
scripts/clang-tools/run-clang-tools_test.py | 41 +++++++++++++++++++++
2 files changed, 42 insertions(+)
create mode 100644 scripts/clang-tools/run-clang-tools_test.py
diff --git a/scripts/clang-tools/run-clang-tools.py b/scripts/clang-tools/run-clang-tools.py
index e78be82..79d58b3 100755
--- a/scripts/clang-tools/run-clang-tools.py
+++ b/scripts/clang-tools/run-clang-tools.py
@@ -12,6 +12,7 @@ compile_commands.json.
import argparse
import json
import multiprocessing
+import os
import subprocess
import sys
diff --git a/scripts/clang-tools/run-clang-tools_test.py b/scripts/clang-tools/run-clang-tools_test.py
new file mode 100644
index 0000000..207b866
--- /dev/null
+++ b/scripts/clang-tools/run-clang-tools_test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""Tests for run-clang-tools.py."""
+
+import importlib.util
+import os
+from pathlib import Path
+import unittest
+from unittest import mock
+
+
+spec = importlib.util.spec_from_file_location(
+ "run_clang_tools", Path(__file__).with_name("run-clang-tools.py"))
+run_clang_tools = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(run_clang_tools)
+
+
+class TestRunClangTools(unittest.TestCase):
+ def test_broken_pipe_redirects_stdout_and_exits(self):
+ args = mock.Mock(path="compile_commands.json")
+ with mock.patch.object(run_clang_tools, "parse_arguments", return_value=args), \
+ mock.patch("builtins.open", mock.mock_open(read_data="[]")), \
+ mock.patch.object(run_clang_tools.multiprocessing, "Lock"), \
+ mock.patch.object(run_clang_tools.multiprocessing, "Pool") as pool, \
+ mock.patch("os.open", return_value=42) as open_devnull, \
+ mock.patch("os.dup2") as dup2, \
+ mock.patch.object(run_clang_tools.sys, "stdout") as stdout:
+ pool.return_value.__enter__.return_value.map.side_effect = BrokenPipeError
+ stdout.fileno.return_value = 1
+
+ with self.assertRaises(SystemExit) as raised:
+ run_clang_tools.main()
+
+ self.assertEqual(raised.exception.code, 1)
+ open_devnull.assert_called_once_with(os.devnull, os.O_WRONLY)
+ dup2.assert_called_once_with(42, 1)
+
+
+if __name__ == "__main__":
+ unittest.main()
base-commit: fe2ec83746e501645709761605c2464a44fd2929
--
2.52.0.windows.1