Skip to content

[wasi] Path.GetTempFileName and Directory.CreateTempSubdirectory fail: MksTemps/MkdTemp are stubbed on WASI #134943

Closed

Description

@lewing

Description

On WASI, Path.GetTempFileName() always throws, and the exception message says the operation succeeded:

System.IO.IOException : Success : '/tmp/'
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirError)
   at System.IO.Path.GetTempFileName()

GetTempFileName calls SystemNative_MksTemps. wasi-libc provides neither mkstemps nor mkstemp (HAVE_MKSTEMPS and HAVE_MKSTEMP are 0 for wasi), so the shim takes its WASI fallback, which returns -1 without setting errno:

// src/native/libs/System.Native/pal_io.c
#elif TARGET_WASI
    assert_msg(false, "Not supported on WASI", 0);
    result = -1;

SystemNative_MkdTemp, used by Directory.CreateTempSubdirectory, has the same shape: it returns NULL on WASI without setting errno.

The temp directory is usable: with the test harness's --dir=. preopen, /tmp resolves to the app bundle's tmp directory. Only the unique-name creation is missing.

This fails any code that creates temp files. In the CoreCLR WASI library test runs on #134813 it accounts for about 160 failures across System.Data.Common, System.CodeDom, Microsoft.Extensions.Configuration.Functional, System.ComponentModel.Composition, System.ServiceModel.Syndication, System.Diagnostics.TextWriterTraceListener, System.Reflection.Metadata, System.Memory.Data and Microsoft.Extensions.Configuration.FileExtensions.

Proposed fix

Implement both entry points for WASI in pal_io.c using primitives wasi-libc supports, the same way libc implements mkstemp:

  • SystemNative_MksTemps: validate the template (at least six X before the suffix, otherwise EINVAL), then loop a bounded number of times:
    • fill the XXXXXX from getentropy (backed by wasi:random), mapped to [A-Za-z0-9]
    • open(pathTemplate, O_RDWR | O_CREAT | O_EXCL, 0600)
    • return the descriptor on success, retry on EEXIST, return -1 with errno preserved on any other error
    • after the attempts run out, fail with EEXIST
  • SystemNative_MkdTemp: the same loop with mkdir(pathTemplate, 0700).
  • Set errno on every failure path, so a remaining failure produces a meaningful exception instead of "Success".

Filling the template can go in a small helper shared by both entry points. Tests that already cover Path.GetTempFileName and Directory.CreateTempSubdirectory exercise the change once they run on WASI.

Note

This issue was drafted with the help of GitHub Copilot.

Activity

  1. dotnet-policy-service commented on Sep 30, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
    See info in area-owners.md if you want to be subscribed.

  2. dotnet-policy-service commented on Sep 30, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @dotnet/area-system-io
    See info in area-owners.md if you want to be subscribed.

  3. MihuBot commented on Sep 30, 2026

    @MihuBot

    I'm a bot. Here is a possible related and/or duplicate issue (I may be wrong):

  4. added
    os-wasiRelated to WASI variant of arch-wasm
    and removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 30, 2026
  5. added this to the 12.0.0 milestone on Sep 30, 2026
  6. added
    disabled-testThe test is disabled in source code against the issue
    on Oct 5, 2026
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

    arch-wasmWebAssembly architecturearea-System.IOdisabled-testThe test is disabled in source code against the issueos-wasiRelated to WASI variant of arch-wasm

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions