| 959 | } |
| 960 | |
| 961 | int MtFrame::recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout) |
| 962 | { |
| 963 | MtFrame* mtframe = MtFrame::Instance(); |
| 964 | utime64_t start = mtframe->GetLastClock(); |
| 965 | MicroThread* thread = mtframe->GetActiveThread(); |
| 966 | utime64_t now = 0; |
| 967 | |
| 968 | if(fd<0 || !buf || len<1) |
| 969 | { |
| 970 | errno = EINVAL; |
| 971 | MTLOG_ERROR("recvfrom failed, errno: %d (%m)", errno); |
| 972 | return -10; |
| 973 | } |
| 974 | |
| 975 | if (timeout <= -1) |
| 976 | { |
| 977 | timeout = 0x7fffffff; |
| 978 | } |
| 979 | |
| 980 | while (true) |
| 981 | { |
| 982 | now = mtframe->GetLastClock(); |
| 983 | if ((int)(now - start) > timeout) |
| 984 | { |
| 985 | errno = ETIME; |
| 986 | return -1; |
| 987 | } |
| 988 | |
| 989 | KqueuerObj epfd; |
| 990 | epfd.SetOsfd(fd); |
| 991 | epfd.EnableInput(); |
| 992 | epfd.SetOwnerThread(thread); |
| 993 | if (!mtframe->KqueueSchedule(NULL, &epfd, timeout)) |
| 994 | { |
| 995 | MTLOG_DEBUG("epoll schedule failed, errno: %d", errno); |
| 996 | return -2; |
| 997 | } |
| 998 | |
| 999 | mt_hook_syscall(recvfrom); |
| 1000 | int n = ff_hook_recvfrom(fd, buf, len, flags, from, fromlen); |
| 1001 | if (n < 0) |
| 1002 | { |
| 1003 | if (errno == EINTR) { |
| 1004 | continue; |
| 1005 | } |
| 1006 | |
| 1007 | if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) |
| 1008 | { |
| 1009 | MTLOG_ERROR("recvfrom failed, errno: %d", errno); |
| 1010 | return -3; |
| 1011 | } |
| 1012 | } |
| 1013 | else |
| 1014 | { |
| 1015 | return n; |
| 1016 | } |
| 1017 | } |
| 1018 |
nothing calls this directly
no test coverage detected