Skip to content

Turn errno into an enum #4233

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lib/std/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ pub usingnamespace switch (builtin.os) {
else => struct {},
};

pub fn getErrno(rc: var) u16 {
if (rc == -1) {
return @intCast(u16, _errno().*);
} else {
return 0;
}
pub fn getErrno(rc: var) Errno {
const errno = if (rc == -1)
_errno().*
else
0;
return @intToEnum(Errno, @intCast(u12, errno));
}

/// The return type is `type` to force comptime function call execution.
Expand Down
13 changes: 6 additions & 7 deletions lib/std/event/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1256,9 +1256,8 @@ pub fn Watch(comptime V: type) type {

while (!self.os_data.cancelled) {
const rc = os.linux.read(self.os_data.inotify_fd, &event_buf, event_buf.len);
const errno = os.linux.getErrno(rc);
switch (errno) {
0 => {
switch (os.linux.getErrno(rc)) {
@intToEnum(os.linux.Errno, 0) => {
// can't use @bytesToSlice because of the special variable length name field
var ptr = event_buf[0..].ptr;
const end_ptr = ptr + event_buf.len;
Expand Down Expand Up @@ -1291,10 +1290,10 @@ pub fn Watch(comptime V: type) type {
ptr = @alignCast(@alignOf(os.linux.inotify_event), ptr + @sizeOf(os.linux.inotify_event) + ev.len);
}
},
os.linux.EINTR => continue,
os.linux.EINVAL => unreachable,
os.linux.EFAULT => unreachable,
os.linux.EAGAIN => {
.EINTR => continue,
.EINVAL => unreachable,
.EFAULT => unreachable,
.EAGAIN => {
global_event_loop.linuxWaitFd(self.os_data.inotify_fd, os.linux.EPOLLET | os.linux.EPOLLIN | os.EPOLLONESHOT);
},
else => unreachable,
Expand Down
6 changes: 3 additions & 3 deletions lib/std/event/loop.zig
Original file line number Diff line number Diff line change
Expand Up @@ -817,8 +817,8 @@ pub const Loop = struct {
@atomicStore(i32, &self.os_data.fs_queue_item, 1, AtomicOrder.SeqCst);
const rc = os.linux.futex_wake(&self.os_data.fs_queue_item, os.linux.FUTEX_WAKE, 1);
switch (os.linux.getErrno(rc)) {
0 => {},
os.EINVAL => unreachable,
@intToEnum(os.linux.Errno, 0) => {},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems clear to me that there should be a tag value of Errno which represents "no error" and has value 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that.... and then thought that getErrno returning an optional would work better: what do you think of that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's the correct data layout. These ABIs have 0 as an in-bound value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lacking that for now, #3806 could put 0 out of range, and hence make it so 0 is null

.EINVAL => unreachable,
else => unreachable,
}
},
Expand Down Expand Up @@ -880,7 +880,7 @@ pub const Loop = struct {
.linux => {
const rc = os.linux.futex_wait(&self.os_data.fs_queue_item, os.linux.FUTEX_WAIT, 0, null);
switch (os.linux.getErrno(rc)) {
0, os.EINTR, os.EAGAIN => continue,
@intToEnum(os.linux.Errno, 0), .EINTR, .EAGAIN => continue,
else => unreachable,
}
},
Expand Down
6 changes: 5 additions & 1 deletion lib/std/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,15 @@ pub fn formatType(
try output(context, "error.");
return output(context, @errorName(value));
},
.Enum => {
.Enum => |enumInfo| {
if (comptime std.meta.trait.hasFn("format")(T)) {
return value.format(fmt, options, context, Errors, output);
}

if (!enumInfo.is_exhaustive) {
return output(context, "TODO:non-exhaustive-enum");
}

try output(context, @typeName(T));
try output(context, ".");
return formatType(@tagName(value), "", options, context, Errors, output, max_depth);
Expand Down
10 changes: 5 additions & 5 deletions lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,11 @@ pub const Dir = struct {
if (self.index >= self.end_index) {
const rc = os.linux.getdents64(self.dir.fd, &self.buf, self.buf.len);
switch (os.linux.getErrno(rc)) {
0 => {},
os.EBADF => unreachable,
os.EFAULT => unreachable,
os.ENOTDIR => unreachable,
os.EINVAL => unreachable,
@intToEnum(os.linux.Errno, 0) => {},
.EBADF => unreachable,
.EFAULT => unreachable,
.ENOTDIR => unreachable,
.EINVAL => unreachable,
else => |err| return os.unexpectedErrno(err),
}
if (rc == 0) return null;
Expand Down
28 changes: 14 additions & 14 deletions lib/std/io/c_out_stream.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ pub const COutStream = struct {
const self = @fieldParentPtr(COutStream, "stream", out_stream);
const amt_written = std.c.fwrite(bytes.ptr, 1, bytes.len, self.c_file);
if (amt_written == bytes.len) return;
switch (std.c._errno().*) {
0 => unreachable,
os.EINVAL => unreachable,
os.EFAULT => unreachable,
os.EAGAIN => unreachable, // this is a blocking API
os.EBADF => unreachable, // always a race condition
os.EDESTADDRREQ => unreachable, // connect was never called
os.EDQUOT => return error.DiskQuota,
os.EFBIG => return error.FileTooBig,
os.EIO => return error.InputOutput,
os.ENOSPC => return error.NoSpaceLeft,
os.EPERM => return error.AccessDenied,
os.EPIPE => return error.BrokenPipe,
else => |err| return os.unexpectedErrno(@intCast(usize, err)),
switch (std.c.getErrno(-1)) {
@intToEnum(os.Errno, 0) => unreachable,
.EINVAL => unreachable,
.EFAULT => unreachable,
.EAGAIN => unreachable, // this is a blocking API
.EBADF => unreachable, // always a race condition
.EDESTADDRREQ => unreachable, // connect was never called
.EDQUOT => return error.DiskQuota,
.EFBIG => return error.FileTooBig,
.EIO => return error.InputOutput,
.ENOSPC => return error.NoSpaceLeft,
.EPERM => return error.AccessDenied,
.EPIPE => return error.BrokenPipe,
else => |err| return os.unexpectedErrno(err),
}
}
};
Loading