Skip to content

std.posix: recvmsg #24603

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft

Conversation

cursedquail
Copy link
Contributor

@cursedquail cursedquail commented Jul 27, 2025

Lifted from #19751 verbatim - thanks to @truemedian for the implementation 😅. That PR has been closed, and even though the larger effort around io has been subsumed by Andrew's writer refactoring, I didn't see this in the wrangle-writer-buffering branch. I decided it was probably ok to resurrect this bit of code.

I did spot-check the errors against the man pages and made sure all the listed errors in that page are present here - although I'll admit I don't truly grasp why some errors are marked as unreachable? I suppose we assume that this function will be called with proper arguments, and any issues around that will be caught in debug builds, where those unreachables will be printed with a stacktrace

Closes #20660

Lifted from ziglang#19751 verbatim - thanks to @truemedian for the
implementation. That PR has been closed, and even though the larger
effort around io has been subsumed by Andrew's writer refactoring, I
didn't see this in the wrangle-writer-buffering branch. I decided it was
probably ok to resurrect this bit of code.

Anyways, I'm doing some work with wayland, which uses recvmsg in a few
places. This _should_ help with the error checking for that.
@dec05eba
Copy link
Contributor

dec05eba commented Jul 30, 2025

To completely close #20660 it should also be possible to send and receive file descriptors, which is done in C with CMSG macro and cmsghdr struct, which appears to have different definitions on different architectures/os.
This is what I have to do in my zig program that uses recvmsg with file descriptors to make it work on x86_64 linux:

const SCM_RIGHTS: i32 = 1;

const cmsghdr = extern struct {
    len: usize, // TODO: This size is different on different OS'
    level: i32,
    type: i32,
};

inline fn cmsg_align(size: usize) usize {
    return std.mem.alignForward(usize, size, @sizeOf(usize));
}

inline fn cmsg_space(size: usize) usize {
    return cmsg_align(@sizeOf(cmsghdr)) + cmsg_align(size);
}

inline fn cmsg_len(size: usize) usize {
    return cmsg_align(@sizeOf(cmsghdr)) + size;
}

and then to set the data in the code:

var cmsgbuf: [cmsg_space(@sizeOf(std.posix.fd_t) * max_fds)]u8 align(@alignOf(cmsghdr)) = undefined;
var cmsg: *cmsghdr = @ptrCast(&cmsgbuf);
cmsg.level = std.posix.SOL.SOCKET;
cmsg.type = SCM_RIGHTS;
cmsg.len = @intCast(cmsg_len(@sizeOf(std.posix.fd_t) * fds_to_send.len));

var fds = std.mem.bytesAsSlice(std.posix.fd_t, cmsgbuf[@sizeOf(cmsghdr)..]);
@memcpy(fds[0..fds_to_send.len], fds_to_send);

it would be nice if zig could provide a nicer interface to this in std.posix. But I guess this should be done in a separate commit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

std.posix.recvmsg() missing
2 participants