-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
E.PERM
should not be an unexpected error for std.posix.socket
#20524
Comments
I'd rather vote for .PERM => return error.OperationNotPermitted From POSIX
GNU glibc [2]
Similar but distinct imho. [1] https://pubs.opengroup.org/onlinepubs/9699919799/download/index.html |
On second look EPERM might actually be unexpected strictly speaking. POSIX
https://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html |
By the spec no error can be considered unexpected, as an implementation can return any error it wants and still be POSIX compliant. |
One question this raises for me at least then is if that is good at all
Or, alternatively, if I'm only speaking as someone using Zig btw. I have zero authority on Zig or the standard lib. I just happen to be also using |
The relevent line in
The posix spec cannot be relied upon if you're trying to determine what errors a call returns in practice; only the OS documentation can be relied on and even then its sometimes murky. On Linux the problem is the aforementioned line which makes it hard to easily know what set of errors any socket related function can return, MacOS
Manpages like Anyway, more about this specific error: In this case you are using
So, the additional errors we get are EFAULT, EOPNOTSUPP, EPROTO and the relevant EPERM. This means you would need to look at the relevant #include <errno.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
int main(void) {
int sockfd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
if (sockfd == -1) {
int err = errno;
fprintf(stderr, "Could not create socket: %s (OS error %d)\n", strerror(err), err);
exit(1);
}
struct sockaddr_ll addr;
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_ifindex = 0xFFFF; /* An invalid interface index */
int err = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
if (err) {
int err = errno;
fprintf(stderr, "Could not bind: %s (OS error %d)\n", strerror(err), err);
exit(1);
}
return 0;
} (This is on Linux) When you call Zig's So, I see basically four solutions:
|
Here's the const std = @import("std");
const posix = std.posix;
const mem = std.mem;
const testing = std.testing;
test "ENODEV on bind" {
const ETH_P_ALL: u16 = 3;
const sockfd = try posix.socket(posix.AF.PACKET, posix.SOCK.DGRAM, mem.nativeToBig(u32, ETH_P_ALL));
var addr = mem.zeroes(posix.sockaddr.ll);
addr.family = posix.AF.PACKET;
addr.protocol = mem.nativeToBig(u16, ETH_P_ALL);
addr.ifindex = 0xFFFF; // An invalid interface index
// This should give ENODEV
const err = posix.bind(sockfd, @ptrCast(&addr), @sizeOf(@TypeOf(addr)));
// But this case is not handled in `std.posix.bind`
try testing.expectError(error.NoDevice, err);
} Running this with |
Zig Version
0.14.0-dev.66+1fdf13a14
Steps to Reproduce and Observed Output
this test outputs the following when not run with sudo:
errno 1 corresponds to
E.PERM
(permission denied when creating socket)This errno is expected because creating a raw socket generally requires elevated privileges.
this is because std.posix.socket does not expect
.PERM
:https://github.com/ziglang/zig/blob/master/lib/std/posix.zig#L3519
when
.PERM
is is actually expected.So the switch should probably have the following in it:
Expected Output
we expect
std.posix.socket
to returnerror.PermissionDenied
when the syscall returnsE.PERM
.The text was updated successfully, but these errors were encountered: