Bug 15952
Summary: | man page cmsg(3) inconsistency | ||
---|---|---|---|
Product: | Documentation | Reporter: | Christopher Head (bugs) |
Component: | man-pages | Assignee: | documentation_man-pages (documentation_man-pages) |
Status: | RESOLVED CODE_FIX | ||
Severity: | normal | CC: | alan, jbowman, mtk.manpages |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
URL: | http://bugs.gentoo.org/show_bug.cgi?id=318801 | ||
Kernel Version: | Subsystem: | ||
Regression: | No | Bisected commit-id: |
Description
Christopher Head
2010-05-09 22:56:01 UTC
I believe the prose section is correct and the sample code is incorrect. There's a nice chart of the data structure in rfc 2292, section 4.3. (Sorry, that's section 4.2 of rfc 2292.) It looks like there's more detail in Appendix A of rfc 3542 (section 20.2): "While sending an application may or may not include padding at the end of last ancillary data in msg_controllen and implementations must accept both as valid." This seems to indicate that the sample code could be correct either way, but only because there's only one control message in the buffer. I think it's still confusing, and should be changed to show msg.msg_controllen initialized with a value coming from CMSG_SPACE. (Or at least to make clear why we can get away with using cmsg_len in this case.) Still present It seems to me that at the time this report was made, there were at least *two* problems with this code snippet: msg.msg_control = buf; [1] msg.msg_controllen = sizeof buf; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD); /* Initialize the payload: */ fdptr = (int *) CMSG_DATA(cmsg); memcpy(fdptr, myfds, NUM_FD * sizeof(int)); /* Sum of the length of all control messages in the buffer: */ [2] msg.msg_controllen = cmsg->cmsg_len; One of these is the problem referred to in this bug, at the line marked [2]. But the other is that there's a general confusion in the code where msg.msg_controllen is being initialized twice. Since the time of the report, the code has changed a little because on some other reports, but the problem line [2] still exists. The solution is I believe to remove line [2] and modify line [1] (which was already done as a result of the other changes), as shown in this revised code snippet: struct msghdr msg = {0}; struct cmsghdr *cmsg; int myfds[NUM_FD]; /* Contains the file descriptors to pass. */ union { /* ancillary data buffer, wrapped in a union in order to ensure it is suitably aligned */ char buf[CMSG_SPACE(sizeof myfds)]; struct cmsghdr align; } u; int *fdptr; msg.msg_control = u.buf; msg.msg_controllen = sizeof u.buf; cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int) * NUM_FD); /* Initialize the payload: */ fdptr = (int *) CMSG_DATA(cmsg); memcpy(fdptr, myfds, NUM_FD * sizeof(int)); I've made this change, which I believe addresses the problem, so I'm closing this bug. Please reopen, if you believe there is still a problem. |