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