Skip to content

Add tee builtin#1

Open
owen499 wants to merge 1 commit into
masterfrom
feat/builtin-tee
Open

Add tee builtin#1
owen499 wants to merge 1 commit into
masterfrom
feat/builtin-tee

Conversation

@owen499

@owen499 owen499 commented Apr 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • POSIX-subset tee builtin: tee [-a] [file...] — fan stdin out to stdout and any number of files (default 256 cap)
  • Wired into check_builtin() dispatch so it runs in-process without forking an external binary
  • Added srcs/builtin/tee.c to the Makefile

Behavior

  • Reads stdin in 4096-byte chunks until EOF, mirroring each chunk to stdout and to every successfully opened file
  • -a switches O_TRUNCO_APPEND; default mode is 0644
  • Per-file open errors print minishell: tee: <path>: <strerror> to stderr and set g_status = 1, but do not abort the remaining writers

42 Norm compliance

  • 5 functions, each ≤25 lines and ≤5 locals
  • No new globals, reuses existing libft helpers (ft_strequ, ft_putstr_fd, ft_putendl_fd) and g_status

Test plan

  • make builds clean on Linux (macOS clang has unrelated -Wunused-but-set-variable noise in pre-existing files)
  • echo hi | ./minishell -c 'tee out.txt' writes hi to both stdout and out.txt
  • printf 'a\nb\n' | ./minishell -c 'tee -a log.txt' appends without truncating prior content
  • echo x | ./minishell -c 'tee /root/no' prints permission-denied error and continues; exit status reflects failure

Summary by cubic

Adds a POSIX-style tee builtin to fan stdin to stdout and files, with append support. Runs in-process to avoid spawning an external tee, improving pipeline performance.

  • New Features
    • Command: tee [-a] [file...]; reads in 4096-byte chunks; writes to stdout and up to 256 files (0644 default mode).
    • -a appends instead of truncating; per-file open errors print to stderr, continue, and set g_status=1.
    • Integrated into check_builtin() to run in-process and avoid forking.

Written for commit 5c1a554. Summary will update on new commits. Review in cubic

Implements POSIX-subset tee (`tee [-a] [file...]`) as a builtin so
pipelines can fan out stdin to stdout and one or more files without
forking an external binary. Supports -a for append mode and reports
per-file open errors via stderr while still writing successfully
opened files.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="srcs/builtin/tee.c">

<violation number="1" location="srcs/builtin/tee.c:63">
P2: Return values of `write()` are ignored, which can silently lose data on partial writes or I/O errors. At minimum, a failed `write(1, …)` (broken stdout pipe) should stop the loop, and failed file writes should set `g_status = 1` — consistent with the error reporting you already do for `open()` failures.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment thread srcs/builtin/tee.c
r = read(0, buf, sizeof(buf));
while (r > 0)
{
write(1, buf, r);

@cubic-dev-ai cubic-dev-ai Bot Apr 28, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Return values of write() are ignored, which can silently lose data on partial writes or I/O errors. At minimum, a failed write(1, …) (broken stdout pipe) should stop the loop, and failed file writes should set g_status = 1 — consistent with the error reporting you already do for open() failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At srcs/builtin/tee.c, line 63:

<comment>Return values of `write()` are ignored, which can silently lose data on partial writes or I/O errors. At minimum, a failed `write(1, …)` (broken stdout pipe) should stop the loop, and failed file writes should set `g_status = 1` — consistent with the error reporting you already do for `open()` failures.</comment>

<file context>
@@ -0,0 +1,101 @@
+	r = read(0, buf, sizeof(buf));
+	while (r > 0)
+	{
+		write(1, buf, r);
+		i = -1;
+		while (++i < n)
</file context>
Fix with Cubic

@owen499

owen499 commented Apr 28, 2026

Copy link
Copy Markdown
Owner Author

@cubic-dev-ai plz review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Apr 28, 2026

Copy link
Copy Markdown

@cubic-dev-ai plz review this PR

@owen499 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant