Skip to content

Regression: sysopen rejects O_CREAT|O_EXCL without explicit access mode #1431

Description

@fglock

Summary

File::Temp::MoreUtils 0.005 regressed on PerlOnJava because sysopen rejects a valid Perl flag combination when no explicit read/write access flag is supplied.

Regression metadata

  • CPAN run: 20260918-141920-96054
  • Distribution: File-Temp-MoreUtils-0.005
  • Previous pass: 2026-08-29 at commit 19c285d26
  • Failing test: t/01-basic.t, subtest tempfile_named
  • Reproduces on both JVM and interpreter backends

Reproduction

The upstream module calls:

sysopen $fh, $name, O_CREAT | O_CREAT | O_EXCL

The duplicate O_CREAT is harmless. The important compatibility point is that no explicit O_RDONLY, O_WRONLY, or O_RDWR flag is present. Perl treats the absent access bits as the default read-only mode while still allowing creation with O_CREAT | O_EXCL.

Minimal reproducer:

use Fcntl ':DEFAULT';
my $path = '/tmp/perlonjava-sysopen-check';
my $ok = sysopen(my $fh, $path, O_CREAT | O_CREAT | O_EXCL);
print defined($ok) ? "created\\n" : "failed: $!\\n";

For comparison, adding O_WRONLY makes the call succeed on PerlOnJava:

sysopen $fh, $path, O_WRONLY | O_CREAT | O_EXCL;

Expected result

System Perl passes the complete upstream suite. The tempfile_named test creates a.1, then continues through the filename-suffix and directory cases.

Actual result

PerlOnJava fails at the first creation attempt:

tempfile_named(): Can't create temporary file 'a.1'

The CPAN regression record reports one failed test program and one failed subtest. The focused test fails identically on both JVM and interpreter backends.

The minimal reproducer confirms that O_CREAT | O_EXCL fails under PerlOnJava, while O_WRONLY | O_CREAT | O_EXCL succeeds. This is independent of the temporary-directory location and is not a permissions, service, or platform-prerequisite failure.

Likely root cause

PerlOnJava's sysopen implementation appears to require an explicit access mode when translating Perl open flags to Java file-opening options. Standard Perl permits the access bits to be omitted, interpreting them as read-only. PerlOnJava should preserve that default while still honoring O_CREAT, O_EXCL, and the other creation flags.

Acceptance criteria

  • sysopen with O_CREAT | O_EXCL and no explicit access flag succeeds on both backends, matching system Perl.
  • Existing O_RDONLY, O_WRONLY, and O_RDWR behavior remains correct.
  • O_EXCL continues to report an existing target as an expected collision rather than a generic creation failure.
  • File::Temp::MoreUtils 0.005 passes its complete upstream test suite on both backends.
  • Add focused project-owned regression tests for omitted access mode with O_CREAT, O_EXCL, and repeated filename attempts.
  • Re-run the CPAN regression to confirm recovery from the previous pass boundary.

Evidence

  • System Perl: PASS for File::Temp::MoreUtils 0.005.
  • PerlOnJava: FAIL in tempfile_named on JVM and interpreter.
  • The package is pure Perl and uses core Fcntl, File::Temp, and sysopen; no native extension or external service is involved.
  • No exact existing GitHub issue was found for this sysopen flag combination.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:cpan-portCPAN compatibility ports and providersarea:ioFiles handles paths and networkingbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions