Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

errno(6): No such device or address is not handled in os.write #18240

Closed
plaukiu opened this issue Dec 9, 2023 · 3 comments · Fixed by #22113
Closed

errno(6): No such device or address is not handled in os.write #18240

plaukiu opened this issue Dec 9, 2023 · 3 comments · Fixed by #22113
Labels
bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals. standard library This issue involves writing Zig code for the standard library.
Milestone

Comments

@plaukiu
Copy link

plaukiu commented Dec 9, 2023

Zig Version

0.12.0-dev.1808+69195d0cd

Steps to Reproduce and Observed Behaviour

I am writing to a device file. The device gets disconnected before or mid-flush. Such writes return errno(6): No such device or address.. This is expected behaviour.

errno(6) is defined in linux/errno/generic.zig:

pub const E = enum(u16) {
    SUCCESS = 0,
    PERM = 1,
    NOENT = 2,
    SRCH = 3,
    INTR = 4,
    IO = 5,
    NXIO = 6, // <<< here
    // ...
}

But it is not handled in os.zig:

pub fn write(...) WriteError!void {
//...
while (true) {
        const rc = system.write(fd, bytes.ptr, adjusted_len);
        switch (errno(rc)) {
            .SUCCESS => return @as(usize, @intCast(rc)),
            .INTR => continue,
            .INVAL => return error.InvalidArgument,
            .FAULT => unreachable,
            .AGAIN => return error.WouldBlock,
            .BADF => return error.NotOpenForWriting, // can be a race condition.
            .DESTADDRREQ => unreachable, // `connect` was never called.
            .DQUOT => return error.DiskQuota,
            .FBIG => return error.FileTooBig,
            .IO => return error.InputOutput,
            .NOSPC => return error.NoSpaceLeft,
            .PERM => return error.AccessDenied,
            .PIPE => return error.BrokenPipe,
            .CONNRESET => return error.ConnectionResetByPeer,
            .BUSY => return error.DeviceBusy,
            // lacks .NXIO => return error.XXXX,
            else => |err| return unexpectedErrno(err), // <<< here
        }
    }

as it is not included as a variant of os.WriteError.

Instead of handling the error silently, as the error is expected, unexpectedErrno is called, printing a stack trace in debug mode, i.e. filling stderr with unintended and uninformative noise.

Expected Behavior

errno(6) is handled silently, without the noisy call to unexpectedErrno(errno)

@plaukiu plaukiu added the bug Observed behavior contradicts documented or intended behavior label Dec 9, 2023
@rootbeer
Copy link
Contributor

rootbeer commented Dec 9, 2023

See #17950 (comment) which is a comment on a similar bug (fsync returns EINVAL), that collects a bunch of the related bugs around Zig's incomplete errno mappings.

I'm of the opinion that Zig shouldn't be trying to "clean up" syscall errnos by trying to decide which errno are "legit" and which "can't happen", or even by giving them prettier names. (Handling EINTR seems reasonable, I guess.) My opinions aside (as I'm very much a bystander), the prevailing approach is to add new errno mappings as they come up (especially when driven by actual experience in real code, like yours), so I suspect a patch to add NXIO handling here would be accepted. AFAICT, the existing ENXIO in os.zig are mapped (in a seek context) to error.Unseekable, but that seems wrong here. There is an error.NoDevice that seems plausible (See https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html and/or https://www.gnu.org/software/libc/manual/html_node/Error-Codes.html), though that is more clearly a mapping from ENODEV ... (reading the descriptions these are really subtly different errno codes. I think ENODEV means the device could never exist, and ENIXIO implies the device might possibly exist, but isn't present now ... Don't quote me on that. Again, I vote for Zig not getting involved in any of this and letting errno be errno without (re-)interpretation.)

@andrewrk andrewrk added standard library This issue involves writing Zig code for the standard library. contributor friendly This issue is limited in scope and/or knowledge of Zig internals. labels Nov 24, 2024
@andrewrk andrewrk added this to the 0.14.0 milestone Nov 24, 2024
@andrewrk
Copy link
Member

fixed in c2db5d9

@alexrp
Copy link
Member

alexrp commented Nov 25, 2024

Reopening, see: #21983 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals. standard library This issue involves writing Zig code for the standard library.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants