#include #include #include #include #include #include #include "socket_wrapper.h" int getBufferSizeFrom(int sock){ int buffer_sz; socklen_t len = sizeof(buffer_sz); if(getsockopt(sock,SOL_SOCKET,SO_SNDBUF,&buffer_sz,&len) < 0){ perror("failed to get sock buffer size: getsockopt"); buffer_sz = DEFAULT_BUF_SIZE;/*set to default*/ } if(buffer_sz < MINIMUM_BUF_SIZE) buffer_sz = MINIMUM_BUF_SIZE; return buffer_sz; } static uint64_t timer_ticks = 0; static void alarm_handler(int signum){ timer_ticks++; } void register_alarm(){ struct sigaction sigact; sigact.sa_flags = SA_INTERRUPT; sigemptyset(&sigact.sa_mask); sigaddset(&sigact.sa_mask,SIGALRM); sigact.sa_handler = alarm_handler; sigaction(SIGALRM, &sigact ,NULL); } ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout) { ssize_t ret; uint64_t cur = timer_ticks; int die_count = 0; for(;;){ alarm(timeout); ret = recv(fd,buf,n,0); if (ret < 0 && errno == EINTR && cur != timer_ticks) return -2; alarm(0); if (ret == 0){ usleep(100000); die_count++; if(die_count > timeout*10){ return -2; } } else break; } return ret; } ssize_t recv_until_byte(int fd,void * buf, size_t n,int timeout){ ssize_t cur = 0; uint8_t * b = buf; while (cur < n) { ssize_t r = timeout_recv(fd,&b[cur],n-cur,timeout); if (r < 0){ return r; } cur += r; } assert(cur == n); return cur; }