HW12/socket_wrapper.c

63 lines
1.5 KiB
C
Raw Normal View History

2020-12-04 08:06:26 +09:00
#include <signal.h>
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
2020-12-04 13:39:58 +09:00
#include <poll.h>
2020-12-04 08:06:26 +09:00
#include "socket_wrapper.h"
int getBufferSizeFrom(int sock){
int buffer_sz;
socklen_t len = sizeof(buffer_sz);
2020-12-04 14:25:10 +09:00
//getsockopt is thread-safe
2020-12-04 08:06:26 +09:00
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;
}
ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout)
{
ssize_t ret;
2020-12-04 13:39:58 +09:00
int poll_ret;
struct pollfd fd_single;
fd_single.fd = fd;
fd_single.events = POLL_IN;
poll_ret = (poll(&fd_single,1,timeout * 1000));
if (poll_ret < 0) return -1;
else if(poll_ret == 0) return -2;
switch (fd_single.revents){
case POLLHUP: //We'll treat hangups state like timeouts state.
return -2;
case POLLERR:
case POLLNVAL:
return -1;
case POLL_IN:
2020-12-04 14:25:10 +09:00
ret = recv(fd,buf,n,0);
assert(ret != 0);
return ret;
2020-12-04 13:39:58 +09:00
default:
assert(0 && "unreachable");
2020-12-04 08:06:26 +09:00
}
2020-12-04 14:25:10 +09:00
assert(0 && "unreachable");
2020-12-04 08:06:26 +09:00
}
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;
}