Browse Source

work on server_run

master
Georg Hopp 14 years ago
parent
commit
fb0dd8ad89
  1. 9
      include/server.h
  2. 140
      src/server_run.c
  3. 9
      src/signalHandling.c
  4. 4
      src/socket_accept.c
  5. 2
      tests/Makefile.am
  6. 22
      tests/serverTest.c

9
include/server.h

@ -9,6 +9,8 @@
#include "cclass.h"
typedef void (*server_read_hook)(const char *);
CLASS(SERVER) {
LOGGER logger;
SOCK sock;
@ -22,12 +24,13 @@ CLASS(SERVER) {
unsigned int rpos;
unsigned int wpos;
} conns[FD_SETSIZE];
};
server_read_hook read_hook;
};
void server_run(SERVER this);
void server_close(SERVER this);
void server_shutdown(SERVER this);
//void server_close(SERVER this);
//void server_shutdown(SERVER this);
#endif // __SERVER_H__

140
src/server_run.c

@ -0,0 +1,140 @@
#include <sys/select.h> /* for select system call and related */
#include <string.h> /* for memset and stuff */
#include <stdlib.h> /* for exit */
#include <errno.h> /* for errno */
#include <unistd.h>
#include "include/logger.h"
#include "include/server.h"
#include "include/socket.h"
#include "include/signalHandling.h"
#undef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
static
fd_set
server_select(SERVER this) {
fd_set rfds;
memcpy(&rfds, &(this->fdset), sizeof(fd_set));
/*
* wait for handles to become ready
*/
if (-1 == select((this->max_fd)+1, &rfds, NULL, NULL, NULL))
{
switch (errno) {
default:
case EBADF:
case EINVAL:
case ENOMEM:
doShutdown = 1;
/* Fallthrough */
case EINTR:
logger_log(this->logger, LOGGER_CRIT,
"select systemcall failed: [%s] - service terminated",
strerror(errno));
exit(EXIT_FAILURE); /* @TODO do real shutdown here */
}
}
return rfds;
}
static
void
server_handle_accept(SERVER this, fd_set * rfds)
{
if (FD_ISSET(this->sock->handle, rfds)) {
int fd;
char remoteAddr[16] = "";
SOCK acc;
acc = sock_accept(this->sock, remoteAddr);
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);
} else {
delete(&acc);
}
FD_CLR(this->sock->handle, rfds);
}
}
static
void
server_close_conn(SERVER this, unsigned int handle)
{
delete(&((this->conns)[handle].sock));
FD_CLR(handle, &(this->fdset));
}
static
int
server_read(SERVER this, fd_set * rfds)
{
unsigned int i;
size_t _read;
char buffer[1024];
for (i=3; i<=this->max_fd; i++) {
if (FD_ISSET(i, rfds)) {
memset(buffer, 0, 1024);
switch (_read = read(i, buffer, 1023)) {
case 0:
/*
* normal close: write remaining data
*/
/* FALLTHROUGH */
case -1:
/*
* read failure / close connection
* FALLTHROUGH
*/
server_close_conn(this, i);
break;
default:
if (NULL != this->read_hook) {
this->read_hook(buffer);
}
break;
}
}
}
return 0;
}
void
server_run(SERVER this)
{
/*
* @TODO again a hint...add verbosity to logger....
*/
logger_log(this->logger, LOGGER_INFO, "service started");
while (!doShutdown) /* until error or signal */
{
fd_set rfds;
int i;
rfds = server_select(this);
/*
* handle accept
*/
server_handle_accept(this, &rfds);
/* handle reads */
server_read(this, &rfds);
}
}
// vim: set ts=4 sw=4:

9
src/signalHandling.c

@ -1,16 +1,13 @@
#include <signal.h> /* for signal() and signal names */
#include "include/monitor.h"
volatile int doShutdown;
void terminate(int signum)
{
signal(signum, SIG_IGN);
syslogMonitor(LOG_INFO, MON_CRITICAL, "signals",
"caugth deadly signal %d", signum);
syslogMonitor(LOG_INFO, MON_FAILURE, "signals",
"caugth deadly signal %d - service terminated", signum);
/*
* @TODO do logging here
*/
doShutdown = 1;
}

4
src/socket_accept.c

@ -15,8 +15,8 @@
SOCK
sock_accept(SOCK this, char remoteAddr[16])
{
SOCK sock; /* Socket for client */
unsigned int len; /* Length of client address data structure */
SOCK sock; /* Socket for client */
unsigned int len; /* Length of client address data structure */
/* Set the size of the in-out parameter */
len = sizeof(this->addr);

2
tests/Makefile.am

@ -15,7 +15,7 @@ loggerTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I .
socketTest_SOURCES = $(SOURCES) socketTest.c ../src/logger.c ../src/socket.c ../src/socket_listen.c ../src/socket_accept.c ../src/socket_connect.c
socketTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I .
serverTest_SOURCES = $(SOURCES) serverTest.c ../src/logger.c ../src/socket.c ../src/socket_listen.c ../src/socket_accept.c ../src/server.c
serverTest_SOURCES = $(SOURCES) serverTest.c ../src/logger.c ../src/socket.c ../src/socket_listen.c ../src/socket_accept.c ../src/server.c ../src/server_run.c ../src/signalHandling.c
serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I .
EXTRA_DIST = runtest.h mock/class.h

22
tests/serverTest.c

@ -12,6 +12,16 @@
int level = -1;
char * msg = NULL;
char * buffer = NULL;
static void
read_hook(const char * _buffer)
{
if (NULL != _buffer) {
buffer = malloc(strlen(_buffer) + 1);
strcpy(buffer, _buffer);
}
}
static void
logfnct_mock(int _level, const char * _msg)
@ -40,6 +50,8 @@ __setUp()
ASSERT_EQUAL(TEST_PORT, server->sock->port);
ASSERT_EQUAL(server->max_fd, server->sock->handle);
server->read_hook = read_hook;
return TEST_OK;
}
int (* const setUp)() = __setUp;
@ -76,16 +88,6 @@ testDummy()
return TEST_OK;
}
static
int
testAccept()
{
/*
* @TODO ...
*/
return TEST_OK;
}
const testfunc tests[] = {
testDummy
};

Loading…
Cancel
Save