github.com/afumu/libc@v0.0.6/musl/src/network/recvmsg.c (about) 1 #include <sys/socket.h> 2 #include <limits.h> 3 #include <time.h> 4 #include <sys/time.h> 5 #include <string.h> 6 #include "syscall.h" 7 8 hidden void __convert_scm_timestamps(struct msghdr *, socklen_t); 9 10 void __convert_scm_timestamps(struct msghdr *msg, socklen_t csize) 11 { 12 if (SCM_TIMESTAMP == SCM_TIMESTAMP_OLD) return; 13 if (!msg->msg_control || !msg->msg_controllen) return; 14 15 struct cmsghdr *cmsg, *last=0; 16 long tmp; 17 long long tvts[2]; 18 int type = 0; 19 20 for (cmsg=CMSG_FIRSTHDR(msg); cmsg; cmsg=CMSG_NXTHDR(msg, cmsg)) { 21 if (cmsg->cmsg_level==SOL_SOCKET) switch (cmsg->cmsg_type) { 22 case SCM_TIMESTAMP_OLD: 23 if (type) break; 24 type = SCM_TIMESTAMP; 25 goto common; 26 case SCM_TIMESTAMPNS_OLD: 27 type = SCM_TIMESTAMPNS; 28 common: 29 memcpy(&tmp, CMSG_DATA(cmsg), sizeof tmp); 30 tvts[0] = tmp; 31 memcpy(&tmp, CMSG_DATA(cmsg) + sizeof tmp, sizeof tmp); 32 tvts[1] = tmp; 33 break; 34 } 35 last = cmsg; 36 } 37 if (!last || !type) return; 38 if (CMSG_SPACE(sizeof tvts) > csize-msg->msg_controllen) { 39 msg->msg_flags |= MSG_CTRUNC; 40 return; 41 } 42 msg->msg_controllen += CMSG_SPACE(sizeof tvts); 43 cmsg = CMSG_NXTHDR(msg, last); 44 cmsg->cmsg_level = SOL_SOCKET; 45 cmsg->cmsg_type = type; 46 cmsg->cmsg_len = CMSG_LEN(sizeof tvts); 47 memcpy(CMSG_DATA(cmsg), &tvts, sizeof tvts); 48 } 49 50 ssize_t recvmsg(int fd, struct msghdr *msg, int flags) 51 { 52 ssize_t r; 53 socklen_t orig_controllen = msg->msg_controllen; 54 #if LONG_MAX > INT_MAX 55 struct msghdr h, *orig = msg; 56 if (msg) { 57 h = *msg; 58 h.__pad1 = h.__pad2 = 0; 59 msg = &h; 60 } 61 #endif 62 r = socketcall_cp(recvmsg, fd, msg, flags, 0, 0, 0); 63 if (r >= 0) __convert_scm_timestamps(msg, orig_controllen); 64 #if LONG_MAX > INT_MAX 65 if (orig) *orig = h; 66 #endif 67 return r; 68 }