[llvm] [lit] Add stream-injectable run() core to builtin cat (PR #204711)
Prasoon Kumar via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 18:20:08 PDT 2026
https://github.com/prasoon054 updated https://github.com/llvm/llvm-project/pull/204711
>From ce2061dd68b8b0e5ea5b4dcb3e3b27e2ac196eb2 Mon Sep 17 00:00:00 2001
From: Prasoon Kumar <prasoonkumar054 at gmail.com>
Date: Fri, 19 Jun 2026 06:51:04 +0530
Subject: [PATCH] [lit] Add stream-injectable run() core to builtin cat
Pull cat's logic out into run(argv, stdin, stdout, stderr, cwd) so it
takes explicit streams instead of touching sys.std* directly. main()
just calls run() with the real process streams, so nothing changes
for the spawned-script path.
Needed before cat can run in-process inside the lit worker
Also switched file reads to raw bytes throughout, since the old
text-mode read + win32 msvcrt.setmode was only there for sys.stdout's
encoding, which doesn't apply once we pass in a binary stream
directly. Error messages still report the original filename, not the
cwd-joined path.
Signed-off-by: Prasoon Kumar <prasoonkumar054 at gmail.com>
---
llvm/utils/lit/lit/builtin_commands/cat.py | 74 ++++++++++++----------
1 file changed, 40 insertions(+), 34 deletions(-)
diff --git a/llvm/utils/lit/lit/builtin_commands/cat.py b/llvm/utils/lit/lit/builtin_commands/cat.py
index 2797e0cbb4154..fc7d1229bc674 100644
--- a/llvm/utils/lit/lit/builtin_commands/cat.py
+++ b/llvm/utils/lit/lit/builtin_commands/cat.py
@@ -1,4 +1,5 @@
import getopt
+import os
import sys
from io import StringIO
@@ -26,7 +27,23 @@ def convertToCaretAndMNotation(data):
return newdata.getvalue().encode()
-def main(argv):
+def run(argv, stdin, stdout, stderr, cwd):
+ """In-process cat.
+
+ Since it never calls sys.exit, this is safe to run inside the lit worker as well as
+ from the standalone main below.
+
+ Args:
+ argv: A list of command-line arguments. The first element is the command name,
+ followed by options or filenames.
+ stdin: Binary input stream used if no files are specified.
+ stdout: Binary output stream for the concatenated content.
+ stderr: Binary error stream for error messages.
+ cwd: The shell's current working directory, used to resolve relative file paths.
+
+ Returns:
+ An integer representing the exit code (0 for success, 1 for errors).
+ """
arguments = argv[1:]
short_options = "v"
long_options = ["show-nonprinting"]
@@ -35,49 +52,38 @@ def main(argv):
try:
options, filenames = getopt.gnu_getopt(arguments, short_options, long_options)
except getopt.GetoptError as err:
- sys.stderr.write("Unsupported: 'cat': %s\n" % str(err))
- sys.exit(1)
+ stderr.write(b"Unsupported: 'cat': %s\n" % str(err).encode())
+ return 1
for option, value in options:
if option == "-v" or option == "--show-nonprinting":
show_nonprinting = True
- writer = getattr(sys.stdout, "buffer", None)
- if writer is None:
- writer = sys.stdout
- if sys.platform == "win32":
- import os, msvcrt
-
- msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
if len(filenames) == 0:
- sys.stdout.write(sys.stdin.read())
- sys.exit(0)
+ stdout.write(stdin.read())
+ return 0
+
for filename in filenames:
+ path = filename
+ contents = None
+ if not os.path.isabs(path):
+ path = os.path.join(cwd, path)
try:
- contents = None
- is_text = False
- try:
- if sys.platform != "win32":
- fileToCat = open(filename, "r")
- contents = fileToCat.read()
- is_text = True
- except:
- pass
-
- if contents is None:
- fileToCat = open(filename, "rb")
+ with open(path, "rb") as fileToCat:
contents = fileToCat.read()
-
- if show_nonprinting:
- contents = convertToCaretAndMNotation(contents)
- elif is_text:
- contents = contents.encode()
- writer.write(contents)
- sys.stdout.flush()
- fileToCat.close()
except IOError as error:
- sys.stderr.write(str(error))
- sys.exit(1)
+ error.filename = filename
+ stderr.write(str(error).encode())
+ return 1
+ if show_nonprinting:
+ contents = convertToCaretAndMNotation(contents)
+ stdout.write(contents)
+ return 0
+
+
+def main(argv):
+ out = getattr(sys.stdout, "buffer", sys.stdout)
+ sys.exit(run(argv, sys.stdin.buffer, out, sys.stderr.buffer, os.getcwd()))
if __name__ == "__main__":
More information about the llvm-commits
mailing list