|
|
@ -1,4 +1,4 @@ |
|
|
#include <sys/select.h> /* for select system call and related */ |
|
|
|
|
|
|
|
|
#include <poll.h> /* for select system call and related */ |
|
|
#include <string.h> /* for memset and stuff */ |
|
|
#include <string.h> /* for memset and stuff */ |
|
|
#include <stdlib.h> /* for exit */ |
|
|
#include <stdlib.h> /* for exit */ |
|
|
#include <errno.h> /* for errno */ |
|
|
#include <errno.h> /* for errno */ |
|
|
@ -13,17 +13,14 @@ |
|
|
#define MAX(x,y) ((x) > (y) ? (x) : (y)) |
|
|
#define MAX(x,y) ((x) > (y) ? (x) : (y)) |
|
|
|
|
|
|
|
|
static |
|
|
static |
|
|
fd_set |
|
|
|
|
|
|
|
|
int |
|
|
server_select(SERVER this) { |
|
|
server_select(SERVER this) { |
|
|
fd_set rfds; |
|
|
|
|
|
|
|
|
|
|
|
memcpy(&rfds, &(this->fdset), sizeof(fd_set)); |
|
|
|
|
|
|
|
|
int events; |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* wait for handles to become ready |
|
|
* wait for handles to become ready |
|
|
*/ |
|
|
*/ |
|
|
if (-1 == select((this->max_fd)+1, &rfds, NULL, NULL, NULL)) |
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
if (-1 == (events = poll(this->fds, this->nfds, -1))) { |
|
|
switch (errno) { |
|
|
switch (errno) { |
|
|
default: |
|
|
default: |
|
|
case EBADF: |
|
|
case EBADF: |
|
|
@ -36,56 +33,48 @@ server_select(SERVER this) { |
|
|
logger_log(this->logger, LOGGER_CRIT, |
|
|
logger_log(this->logger, LOGGER_CRIT, |
|
|
"select systemcall failed: [%s] - service terminated", |
|
|
"select systemcall failed: [%s] - service terminated", |
|
|
strerror(errno)); |
|
|
strerror(errno)); |
|
|
exit(EXIT_FAILURE); /* @TODO do real shutdown here */ |
|
|
|
|
|
|
|
|
//exit(EXIT_FAILURE); /* @TODO do real shutdown here */ |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return rfds; |
|
|
|
|
|
|
|
|
return events; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static |
|
|
static |
|
|
void |
|
|
void |
|
|
server_handle_accept(SERVER this, fd_set * rfds) |
|
|
|
|
|
|
|
|
server_handle_accept(SERVER this) |
|
|
{ |
|
|
{ |
|
|
if (FD_ISSET(this->sock->handle, rfds)) { |
|
|
|
|
|
int fd; |
|
|
|
|
|
|
|
|
if (0 != ((this->fds)[0].revents & POLLIN)) { |
|
|
char remoteAddr[16] = ""; |
|
|
char remoteAddr[16] = ""; |
|
|
SOCK acc; |
|
|
SOCK acc; |
|
|
|
|
|
|
|
|
acc = sock_accept(this->sock, remoteAddr); |
|
|
acc = sock_accept(this->sock, remoteAddr); |
|
|
|
|
|
|
|
|
if (-1 != acc->handle) { |
|
|
if (-1 != acc->handle) { |
|
|
((this->conns)[acc->handle].sock)->handle = fd; // save the socket handle |
|
|
|
|
|
FD_SET(fd, &(this->fdset)); |
|
|
|
|
|
this->max_fd = MAX(fd, this->max_fd); |
|
|
|
|
|
|
|
|
(this->conns)[this->nfds].sock = acc; // save the socket handle |
|
|
|
|
|
(this->fds)[this->nfds].fd = acc->handle; |
|
|
|
|
|
(this->fds)[this->nfds].events = POLLIN; |
|
|
|
|
|
this->nfds++; |
|
|
} else { |
|
|
} else { |
|
|
delete(&acc); |
|
|
delete(&acc); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
FD_CLR(this->sock->handle, rfds); |
|
|
|
|
|
|
|
|
(this->fds)[0].revents |= POLLIN; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static |
|
|
|
|
|
void |
|
|
|
|
|
server_close_conn(SERVER this, unsigned int handle) |
|
|
|
|
|
{ |
|
|
|
|
|
delete(&((this->conns)[handle].sock)); |
|
|
|
|
|
FD_CLR(handle, &(this->fdset)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
static |
|
|
int |
|
|
int |
|
|
server_read(SERVER this, fd_set * rfds) |
|
|
|
|
|
|
|
|
server_read(SERVER this) |
|
|
{ |
|
|
{ |
|
|
unsigned int i; |
|
|
unsigned int i; |
|
|
size_t _read; |
|
|
|
|
|
char buffer[1024]; |
|
|
|
|
|
|
|
|
size_t _read; |
|
|
|
|
|
char buffer[1024]; |
|
|
|
|
|
|
|
|
for (i=3; i<=this->max_fd; i++) { |
|
|
|
|
|
if (FD_ISSET(i, rfds)) { |
|
|
|
|
|
|
|
|
for (i=1; i<this->nfds; i++) { |
|
|
|
|
|
if (0 != ((this->fds)[i].revents & POLLIN)) { |
|
|
memset(buffer, 0, 1024); |
|
|
memset(buffer, 0, 1024); |
|
|
switch (_read = read(i, buffer, 1023)) { |
|
|
|
|
|
|
|
|
switch (_read = read((this->fds)[i].fd, buffer, 1023)) { |
|
|
case 0: |
|
|
case 0: |
|
|
/* |
|
|
/* |
|
|
* normal close: write remaining data |
|
|
* normal close: write remaining data |
|
|
@ -101,6 +90,7 @@ server_read(SERVER this, fd_set * rfds) |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
|
|
|
(this->fds)[i].revents |= POLLIN; |
|
|
if (NULL != this->read_hook) { |
|
|
if (NULL != this->read_hook) { |
|
|
this->read_hook(buffer); |
|
|
this->read_hook(buffer); |
|
|
} |
|
|
} |
|
|
@ -116,24 +106,27 @@ void |
|
|
server_run(SERVER this) |
|
|
server_run(SERVER this) |
|
|
{ |
|
|
{ |
|
|
/* |
|
|
/* |
|
|
* @TODO again a hint...add verbosity to logger.... |
|
|
|
|
|
|
|
|
* @TODO again...add verbosity to logger.... |
|
|
*/ |
|
|
*/ |
|
|
logger_log(this->logger, LOGGER_INFO, "service started"); |
|
|
logger_log(this->logger, LOGGER_INFO, "service started"); |
|
|
|
|
|
|
|
|
while (!doShutdown) /* until error or signal */ |
|
|
while (!doShutdown) /* until error or signal */ |
|
|
{ |
|
|
{ |
|
|
fd_set rfds; |
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
rfds = server_select(this); |
|
|
|
|
|
|
|
|
int events; |
|
|
|
|
|
/* |
|
|
|
|
|
* @TODO take return value of poll into account with |
|
|
|
|
|
* further handling! |
|
|
|
|
|
*/ |
|
|
|
|
|
events = server_select(this); |
|
|
|
|
|
if (doShutdown) break; |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* handle accept |
|
|
* handle accept |
|
|
*/ |
|
|
*/ |
|
|
server_handle_accept(this, &rfds); |
|
|
|
|
|
|
|
|
server_handle_accept(this); |
|
|
|
|
|
|
|
|
/* handle reads */ |
|
|
/* handle reads */ |
|
|
server_read(this, &rfds); |
|
|
|
|
|
|
|
|
server_read(this); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|