Map /dev/null to the Windows null device - #568
Conversation
On Windows, /dev/null was opened as the relative path \dev\null. Where a dev
directory happened to exist on the current drive — as it does whenever sources
live under C:\Dev — a redirection created and truncated dev\null and kept the
output the script meant to discard, and a getline read whatever that file held.
Where it did not exist, the redirection was a fatal error and getline aborted
the script. /dev/null is not one of the four special filenames gawk documents,
but it is a real device on every Unix system, so "> /dev/null" is a common
idiom in portable scripts, and gawk's Windows port maps the name to NUL.
JRT now translates the name where a redirection, a getline, or an ARGV operand
is opened, so print and printf discard their output and create no file, getline
reports end of input, close() succeeds, and /dev/null as an operand reads as an
empty input file. Only the name is translated: redirections stay keyed by the
spelling the script used, so close("/dev/null") still reports the redirection it
opened. The per-file main input loop that BEGINFILE and ENDFILE select stats
each operand before opening it, and Windows does not report its null device as
an existing file, so that loop now recognizes the name instead of concluding
that the file is missing.
This fixes GawkIT.test_delargv and GawkIT.test_iobug1, which both failed with
FileNotFound \dev\null on a machine with no C:\dev directory.
Closes #567
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex please review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eec0f0b752
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
From the Codex review. The per-file main input loop that BEGINFILE, ENDFILE and nextfile select stats each operand before opening it, and Windows reports its null device as nonexistent under either spelling, so an operand named NUL was still reported as a missing file there — while the plain main input loop, which opens the operand without stat'ing it first, read it happily. isNullDeviceName now answers for both names the platform accepts, so the bypass covers NUL on Windows. The translation itself stays gawk-exact: only /dev/null is rewritten, since Windows already opens NUL as the device. AwkTestSupport gains windowsOnly() for the tests this needs, the mirror of the existing posixOnly(): the boolean POSIX flag becomes a PlatformRequirement, so the two gates share one code path and one skip message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex please review again |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Closes #567.
Problem
On Windows,
/dev/nullwas opened as the relative path\dev\null:devdirectory happened to exist on the current drive (as it does whenever sources live underC:\Dev), a redirection created and truncateddev\nulland kept the output the script meant to discard, and agetlineread back whatever that file held;getlineaborted the script./dev/nullis not one of the four special filenames gawk documents under Special Files (those were #556), but it is a real device on every Unix system, so> "/dev/null"is a common idiom in portable AWK scripts, and gawk's Windows port maps the name toNUL.Change
JRTtranslates the name at the three places a script-supplied filename is opened — the output sink,getline < file, and theARGVfile list — so on Windows:print > "/dev/null"andprintf > "/dev/null"discard their output and create no file;getline < "/dev/null"reports end of input (0);close("/dev/null")succeeds;/dev/nullas an operand reads as an empty input file.Only the name is translated. Redirections stay keyed by the spelling the script used, so
close("/dev/null")still reports the redirection it opened, and>/>>remain ordinary opens of a real device. Like gawk, only the Unix spelling is translated: Windows already opensNULunder its own name.The per-file main input loop that
BEGINFILE/ENDFILEselect stats each operand before opening it, and Windows does not report its null device as an existing file, so that loop now recognizes the name instead of reportingNo such file or directoryinERRNO.On POSIX platforms nothing changes: the name is the device already.
Verification
NullDeviceTest(10 tests, asserting on both platforms, noposixOnly()): output discarded, nothing readable back,>>accumulates nothing,getlinereports end of input,close()semantics,/dev/nullas a lone operand and between two real files,BEGINFILE/ENDFILEseeing it as a readable empty file, and one test pinning that no regular file is created. 8 of the 10 fail on Windows without the fix.mvn clean verify site: 800 unit tests pass; checkstyle, PMD, and SpotBugs report zero findings; no new Javadoc warnings.GawkIT.test_delargvandGawkIT.test_iobug1now pass. Both fail withFileNotFoundException: \dev\nullwithout this change (verified after removing the strayC:\dev\nullthat the bug itself had left behind on the test machine — with that file present, the two tests passed for the wrong reason). Totals are otherwise unchanged.🤖 Generated with Claude Code