Portable build, robustness fixes, expanded test suite#1
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
This PR modernizes hs to be architecture-independent on M2-Planet targets by routing kernel interactions through portable M2libc wrappers (removing arch-specific syscall/offset assumptions), while also hardening shell semantics (expansion, redirection, heredocs, set -e, subshells, traps) and significantly expanding the regression test suite and documentation to match current behavior.
Changes:
- Reworked core shell execution/parsing/expansion/redirection logic in
hs.cfor portability and robustness (including heredocs,trap EXIT, subshell isolation, redirect correctness, and arithmetic safety). - Added a broad golden regression suite covering
set -eedge cases, redirection parsing/dup, heredocs, pattern matching corner cases, arithmetic logical chaining, and signal-derived exit statuses. - Updated build and documentation to support cross-arch builds (
--arch) and to describe supported/missing shell features.
Reviewed changes
Copilot reviewed 100 out of 101 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/set_flags/errexit_andor.sh | New regression for set -e with &&/` |
| tests/set_flags/errexit_andor.out | Golden stdout for errexit_andor.sh. |
| tests/set_flags/errexit_andor.exit | Golden exit code for errexit_andor.sh. |
| tests/set_flags/errexit_andor_boundary.sh | New regression for set -e exemption boundaries (function/subshell vs brace/loop). |
| tests/set_flags/errexit_andor_boundary.out | Golden stdout for errexit_andor_boundary.sh. |
| tests/set_flags/errexit_andor_boundary.exit | Golden exit code for errexit_andor_boundary.sh. |
| tests/redirection/redir_target_split.sh | New regression ensuring redirect targets don’t field-split on whitespace-expanded vars. |
| tests/redirection/redir_target_split.out | Golden stdout for redir_target_split.sh. |
| tests/redirection/redir_target_split.exit | Golden exit code for redir_target_split.sh. |
| tests/redirection/input_dup.sh | New regression for <&0 input FD duplication in groups. |
| tests/redirection/input_dup.out | Golden stdout for input_dup.sh. |
| tests/redirection/input_dup.exit | Golden exit code for input_dup.sh. |
| tests/redirection/group_pipe_resync.sh | New regression for group redirects + pipe external output ordering (lseek resync). |
| tests/redirection/group_pipe_resync.out | Golden stdout for group_pipe_resync.sh. |
| tests/redirection/group_pipe_resync.exit | Golden exit code for group_pipe_resync.sh. |
| tests/redirection/fd_redirect_spacing.sh | New regression for attached-vs-spaced FD redirects and N<&M / N>&M. |
| tests/redirection/fd_redirect_spacing.out | Golden stdout for fd_redirect_spacing.sh. |
| tests/redirection/fd_redirect_spacing.exit | Golden exit code for fd_redirect_spacing.sh. |
| tests/pattern_matching/bracket_close.sh | New regression for POSIX bracket-expression ] literal/negation cases. |
| tests/pattern_matching/bracket_close.out | Golden stdout for bracket_close.sh. |
| tests/pattern_matching/bracket_close.exit | Golden exit code for bracket_close.sh. |
| tests/MANIFEST | Registers newly added tests so the runner executes them. |
| tests/heredoc/basic.sh | New basic heredoc regression. |
| tests/heredoc/basic.out | Golden stdout for basic.sh. |
| tests/heredoc/basic.exit | Golden exit code for basic.sh. |
| tests/heredoc/expand.sh | New regression for heredoc variable expansion. |
| tests/heredoc/expand.out | Golden stdout for expand.sh. |
| tests/heredoc/expand.exit | Golden exit code for expand.sh. |
| tests/heredoc/literal_squote.sh | New regression for single-quoted heredoc delimiter literal behavior. |
| tests/heredoc/literal_squote.out | Golden stdout for literal_squote.sh. |
| tests/heredoc/literal_squote.exit | Golden exit code for literal_squote.sh. |
| tests/heredoc/literal_dquote.sh | New regression for double-quoted heredoc delimiter literal behavior. |
| tests/heredoc/literal_dquote.out | Golden stdout for literal_dquote.sh. |
| tests/heredoc/literal_dquote.exit | Golden exit code for literal_dquote.sh. |
| tests/heredoc/escapes.sh | New regression for heredoc backslash escape handling. |
| tests/heredoc/escapes.out | Golden stdout for escapes.sh. |
| tests/heredoc/escapes.exit | Golden exit code for escapes.sh. |
| tests/heredoc/dash_strip.sh | New regression for <<- tab-stripping heredocs. |
| tests/heredoc/dash_strip.out | Golden stdout for dash_strip.sh. |
| tests/heredoc/dash_strip.exit | Golden exit code for dash_strip.sh. |
| tests/heredoc/dash_strip_literal.sh | New regression combining <<- with quoted delimiter (literal body). |
| tests/heredoc/dash_strip_literal.out | Golden stdout for dash_strip_literal.sh. |
| tests/heredoc/dash_strip_literal.exit | Golden exit code for dash_strip_literal.sh. |
| tests/heredoc/multi.sh | New regression for multiple heredocs on one command line. |
| tests/heredoc/multi.out | Golden stdout for multi.sh. |
| tests/heredoc/multi.exit | Golden exit code for multi.sh. |
| tests/heredoc/pipe.sh | New regression for heredoc feeding a pipeline. |
| tests/heredoc/pipe.out | Golden stdout for pipe.sh. |
| tests/heredoc/pipe.exit | Golden exit code for pipe.sh. |
| tests/heredoc/redirect_combo.sh | New regression for heredoc combined with output redirection. |
| tests/heredoc/redirect_combo.out | Golden stdout for redirect_combo.sh. |
| tests/heredoc/redirect_combo.exit | Golden exit code for redirect_combo.sh. |
| tests/heredoc/in_for.sh | New regression for heredocs inside for loops. |
| tests/heredoc/in_for.out | Golden stdout for in_for.sh. |
| tests/heredoc/in_for.exit | Golden exit code for in_for.sh. |
| tests/heredoc/in_if.sh | New regression for heredocs inside if. |
| tests/heredoc/in_if.out | Golden stdout for in_if.sh. |
| tests/heredoc/in_if.exit | Golden exit code for in_if.sh. |
| tests/heredoc/in_while.sh | New regression for heredocs inside while. |
| tests/heredoc/in_while.out | Golden stdout for in_while.sh. |
| tests/heredoc/in_while.exit | Golden exit code for in_while.sh. |
| tests/heredoc/in_function.sh | New regression for heredocs inside functions. |
| tests/heredoc/in_function.out | Golden stdout for in_function.sh. |
| tests/heredoc/in_function.exit | Golden exit code for in_function.sh. |
| tests/heredoc/empty_body.sh | New regression for empty heredoc body parsing/execution. |
| tests/heredoc/empty_body.out | Golden stdout for empty_body.sh. |
| tests/heredoc/empty_body.exit | Golden exit code for empty_body.sh. |
| tests/heredoc/no_split.sh | New regression ensuring heredoc expansions don’t field-split whitespace. |
| tests/heredoc/no_split.out | Golden stdout for no_split.sh. |
| tests/heredoc/no_split.exit | Golden exit code for no_split.sh. |
| tests/heredoc/inner_quotes.sh | New regression for quote characters inside expanding heredocs. |
| tests/heredoc/inner_quotes.out | Golden stdout for inner_quotes.sh. |
| tests/heredoc/inner_quotes.exit | Golden exit code for inner_quotes.sh. |
| tests/heredoc/backtick_subst.sh | New regression for backticks and $(...) inside expanding heredocs. |
| tests/heredoc/backtick_subst.out | Golden stdout for backtick_subst.sh. |
| tests/heredoc/backtick_subst.exit | Golden exit code for backtick_subst.sh. |
| tests/expansion/pattern_escape_strip.sh | New regression for escaped-pattern stripping in ${v#pat}/${v%pat}. |
| tests/expansion/pattern_escape_strip.out | Golden stdout for pattern_escape_strip.sh. |
| tests/expansion/pattern_escape_strip.exit | Golden exit code for pattern_escape_strip.sh. |
| tests/expansion/arith_logical_chain.sh | New regression for arithmetic logical operator chaining semantics. |
| tests/expansion/arith_logical_chain.out | Golden stdout for arith_logical_chain.sh. |
| tests/expansion/arith_logical_chain.exit | Golden exit code for arith_logical_chain.sh. |
| tests/errors/subshell_signal.sh | New regression for signal-terminated child exit statuses (128+signo). |
| tests/errors/subshell_signal.out | Golden stdout for subshell_signal.sh. |
| tests/errors/subshell_signal.exit | Golden exit code for subshell_signal.sh. |
| tests/control_flow/comment_paren.sh | New regression for comment text not affecting subshell paren depth. |
| tests/control_flow/comment_paren.out | Golden stdout for comment_paren.sh. |
| tests/control_flow/comment_paren.exit | Golden exit code for comment_paren.sh. |
| tests/builtins/umask.sh | New regression for umask builtin set/query behavior. |
| tests/builtins/umask.out | Golden stdout for umask.sh. |
| tests/builtins/umask.exit | Golden exit code for umask.sh. |
| tests/builtins/trap_exit_subshell.sh | New regression that subshell/cmdsub exits don’t trigger parent EXIT trap. |
| tests/builtins/trap_exit_subshell.out | Golden stdout for trap_exit_subshell.sh. |
| tests/builtins/trap_exit_subshell.exit | Golden exit code for trap_exit_subshell.sh. |
| tests/builtins/exec_args.sh | New regression for exec argv shifting correctness. |
| tests/builtins/exec_args.out | Golden stdout for exec_args.sh. |
| tests/builtins/exec_args.exit | Golden exit code for exec_args.sh. |
| README.md | Updates feature/support matrix and behavior notes (heredocs, redirects, patterns, missing features). |
| hs.c | Major portability/robustness work: heredocs, redirects, subshells, traps, expansions, set -e, etc. |
| build.sh | Adds --arch build outputs separation and more robust flag parsing. |
| ARCHITECTURE.md | Updates internals documentation and portability constraints to match new implementation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Make hs architecture-independent: every kernel interaction goes through a plain M2libc wrapper, with no inline assembly, raw syscall numbers, or struct offsets. One source builds for any M2-Planet target via `./build.sh --arch <arch>`; the riscv64 and aarch64 cross-builds run under qemu-user. File-type tests (-f/-d/-s) use a portable open()/read() probe; filename globbing and -L/-h symlink tests are not supported (they need getdents64/lstat, which have no portable libc form). Harden the shell across arithmetic ($((...)) evaluation and divide-by-zero), redirection (fd-prefix parsing, <& input dup, open-failure handling, compound-group redirects), heredocs, word splitting, and bounds checks. Add a larger golden-file regression suite and rewrite README.md and ARCHITECTURE.md to describe the shell as it stands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make hs architecture-independent: every kernel interaction goes through a plain M2libc wrapper, with no inline assembly, raw syscall numbers, or struct offsets. One source builds for any M2-Planet target via
./build.sh --arch <arch>; the riscv64 and aarch64 cross-builds run under qemu-user. File-type tests (-f/-d/-s) use a portable open()/read() probe; filename globbing and -L/-h symlink tests are not supported (they need getdents64/lstat, which have no portable libc form).Harden the shell across arithmetic ($((...)) evaluation and divide-by-zero), redirection (fd-prefix parsing, <& input dup, open-failure handling, compound-group redirects), heredocs, word splitting, and bounds checks.
Add a larger golden-file regression suite and rewrite README.md and ARCHITECTURE.md to describe the shell as it stands.