71 lines
1.7 KiB
C
71 lines
1.7 KiB
C
|
#include <signal.h>
|
||
|
#include <assert.h>
|
||
|
#include <stdio.h>
|
||
|
#include <errno.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
#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;
|
||
|
}
|