From 7d4815a19c66771a0b8bc969ab1c2555b192e9f9 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Fri, 19 May 2023 23:38:41 +0200 Subject: [PATCH] proper ending --- server.c | 133 +++++++++++++++++++++++++++++++++++++--------------- server.h | 11 ++--- signal.c | 21 --------- signal.h | 7 --- webserver.c | 38 ++++----------- 5 files changed, 107 insertions(+), 103 deletions(-) delete mode 100644 signal.c delete mode 100644 signal.h diff --git a/server.c b/server.c index 574e54a..4ead290 100644 --- a/server.c +++ b/server.c @@ -1,8 +1,5 @@ -/* depend: */ -/* cflags: */ -/* linker: color.o debug.o */ - #include +#include #include #include #include @@ -15,8 +12,6 @@ #include #include #include -//#include -//#include #include #endif #include @@ -25,19 +20,14 @@ #include "server.h" -/* compat */ +/* types */ #ifdef _WIN32 /* Windows */ -#define PF_INET AF_INET -#define ERRNO (WSAGetLastError ()) +typedef SOCKET socket_t; #else /* Posix */ -#define closesocket close -#define ERRNO errno -#define SOCKET_ERROR -1 +typedef int socket_t; #endif -/* types */ - /* constants */ #define BACKLOG 5 @@ -46,8 +36,30 @@ /* macros */ +#ifdef _WIN32 /* Windows */ +#define PF_INET AF_INET +#define ERRNO (WSAGetLastError ()) +#else /* Posix */ +#define closesocket close +#define ERRNO errno +#define SOCKET_ERROR -1 +#define INVALID_SOCKET -1 +#endif + /* gobal variables */ +socket_t sock = INVALID_SOCKET; +socket_t conn = INVALID_SOCKET; + +/* stop server */ + +void stop_server (int sig) +{ + VERBOSE (INFO, PRINT ("Signal: %d\n", sig)); + terminate_network_context (); + exit (0); +} + /* init network context */ void init_network_context (void) @@ -55,15 +67,24 @@ void init_network_context (void) #ifdef _WIN32 /* Windows */ WSADATA WSAData; WSAStartup (MAKEWORD(2,0), &WSAData); + assert (INVALID_SOCKET == (socket_t)-1); assert (SOCKET_ERROR == -1); #endif + + signal (SIGINT, &stop_server); + signal (SIGQUIT, &stop_server); + signal (SIGABRT, &stop_server); + signal (SIGSEGV, &stop_server); + signal (SIGTERM, &stop_server); } /* terminate network context */ void terminate_network_context (void) { + closesocket (sock); + closesocket (conn); #ifdef _WIN32 /* Windows */ WSACleanup (); #endif @@ -71,15 +92,22 @@ void terminate_network_context (void) /* open listening socket */ -socket_t open_listening_socket (int port) +int open_listening_socket (int port) { int val = 1; VERBOSE (DEBUG, PRINT ("Opening socket\n")); //socket_t sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP); - socket_t sock = socket (AF_INET, SOCK_STREAM, 0); + if (sock != INVALID_SOCKET) { + int rc = closesocket (sock); + if (rc == SOCKET_ERROR) { + VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); + } + sock = INVALID_SOCKET; + } + sock = socket (AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { - return -1; + return 0; } struct sockaddr_in addr = {0}; @@ -98,7 +126,8 @@ socket_t open_listening_socket (int port) if (rc == SOCKET_ERROR) { VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); } - return -1; + sock = INVALID_SOCKET; + return 0; } VERBOSE (DEBUG, PRINT ("Configuring socket\n")); @@ -112,7 +141,8 @@ socket_t open_listening_socket (int port) if (rc == SOCKET_ERROR) { VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); } - return -1; + sock = INVALID_SOCKET; + return 0; } rc = listen (sock, BACKLOG); @@ -122,71 +152,91 @@ socket_t open_listening_socket (int port) if (rc == SOCKET_ERROR) { VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); } - return -1; + sock = INVALID_SOCKET; + return 0; } - return sock; + return 1; } /* accept incomming connection */ -socket_t accept_incoming_connection (socket_t sock) +int accept_incoming_connection (void) { - socket_t connection = accept (sock, NULL, 0); - if (connection == INVALID_SOCKET) { - return INVALID_SOCKET; + if (sock == INVALID_SOCKET) { + VERBOSE (ERROR, PERROR ("Can't accept connection from closed socket\n")); + return 0; + } + + if (conn != INVALID_SOCKET) { + int rc = closesocket (conn); + if (rc == SOCKET_ERROR) { + VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); + } + conn = INVALID_SOCKET; + } + conn = accept (sock, NULL, 0); + if (conn == INVALID_SOCKET) { + return 0; } #ifndef _WIN32 /* POSIX */ - fcntl (connection, F_SETFL, O_NONBLOCK); + fcntl (conn, F_SETFL, O_NONBLOCK); #endif int val = 1; - int rc = setsockopt (connection, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val)); + int rc = setsockopt (conn, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof (val)); if (rc < 0) { VERBOSE (ERROR, PERROR ("error: %s\n", "setsockopt/TCP_NODELAY")); - closesocket (connection); + closesocket (conn); if (rc == SOCKET_ERROR) { VERBOSE (ERROR, PERROR ("error: close %d\n", ERRNO)); } - return INVALID_SOCKET; + conn = INVALID_SOCKET; + return 0; } - return connection; + return 1; } -/* close listening socket */ +/* close connection socket */ -void close_socket (socket_t sock) +void close_connection (void) { - int rc = closesocket (sock); + int rc = closesocket (conn); if (rc == SOCKET_ERROR) { VERBOSE (ERROR, PERROR ("error: %d\n", ERRNO)); } + conn = INVALID_SOCKET; } /* receive data from socket */ -int receive_data (socket_t sock, unsigned char **pdata) +int receive_data (unsigned char **pdata) { unsigned char buffer[BUFFER_SIZE] = {0}; unsigned char *data = NULL; int len = 0; + if (conn == INVALID_SOCKET) { + VERBOSE (ERROR, PERROR ("Can't read data from closed socket\n")); + return 0; + } + while (1) { /* timeout management */ fd_set rfds; struct timeval tv = { 0, TIMEOUT }; FD_ZERO (&rfds); - FD_SET (sock, &rfds); + FD_SET (conn, &rfds); - int retval = select (sock + 1, &rfds, NULL, NULL, &tv); + int retval = select (conn + 1, &rfds, NULL, NULL, &tv); if (retval != 1) { /* 0 or SOCKET_ERROR */ break; } /* read from socket */ - int rc = read (sock, buffer, BUFFER_SIZE); + int rc = read (conn, buffer, BUFFER_SIZE); if (rc == 0) { /* sock closed */ if (data) { @@ -219,12 +269,17 @@ int receive_data (socket_t sock, unsigned char **pdata) /* send data onto socket */ -int send_data (socket_t sock, unsigned char *data, int len) +int send_data (unsigned char *data, int len) { int index = 0; + if (conn == INVALID_SOCKET) { + VERBOSE (ERROR, PERROR ("Can't read data from closed socket\n")); + return 0; + } + while (index < len) { - int rc = write (sock, data + index, len - index); + int rc = write (conn, data + index, len - index); if (rc == 0) { /* sock closed */ index = 0; diff --git a/server.h b/server.h index 9e9f725..2e29b6e 100644 --- a/server.h +++ b/server.h @@ -6,19 +6,18 @@ typedef SOCKET socket_t; #else /* Posix */ typedef int socket_t; -#define INVALID_SOCKET -1 #endif void init_network_context (void); void terminate_network_context (void); -socket_t open_listening_socket (int port); -socket_t accept_incoming_connection (socket_t sock); +int open_listening_socket (int port); +int accept_incoming_connection (void); -void close_socket (socket_t sock); +void close_connection (void); -int receive_data (socket_t sock, unsigned char **pdata); -int send_data (socket_t sock, unsigned char *data, int len); +int receive_data (unsigned char **pdata); +int send_data (unsigned char *data, int len); #endif /* __SERVER_H__ */ diff --git a/signal.c b/signal.c deleted file mode 100644 index bdeb7a9..0000000 --- a/signal.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -#include "signal.h" - -void _signal_handler (int sig) { - printf ("signal: %d\n", sig); -} - -void (*sigh_hangup) (int) = &_signal_handler; -void (*sigh_terminate) (int) = &_signal_handler; - -void __attribute__((constructor)) init_signal (void) -{ -#ifdef _POSIX - signal (SIGHUP, sigh_hangup); -#endif /* _POSIX */ - signal (SIGTERM, sigh_terminate); -} - -/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode */ diff --git a/signal.h b/signal.h deleted file mode 100644 index f4f3309..0000000 --- a/signal.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SIGNAL_H__ -#define __SIGNAL_H__ - -extern void (*sigh_hangup) (int); -extern void (*sigh_terminate) (int); - -#endif /* __SIGNAL_H__ */ diff --git a/webserver.c b/webserver.c index 0110f27..8209ab8 100644 --- a/webserver.c +++ b/webserver.c @@ -1,17 +1,15 @@ /* depend: */ /* cflags: */ -/* linker: color.o debug.o http.o server.o signal.o */ +/* linker: color.o debug.o http.o server.o */ #include #include #include #include -#include #include "debug.h" #include "http.h" #include "server.h" -#include "signal.h" /* types */ @@ -25,8 +23,6 @@ char *progname = NULL; int port = 8080; -socket_t sock = INVALID_SOCKET; -socket_t conn = INVALID_SOCKET; /* help function */ @@ -41,18 +37,6 @@ int usage (int ret) return ret; } -void stop_server (__attribute__((unused)) int sig) -{ - if (conn != INVALID_SOCKET) { - close_socket (conn); - } - if (sock != INVALID_SOCKET) { - close_socket (sock); - } - terminate_network_context (); - exit (0); -} - /* main function */ int main (int argc, char *argv[]) @@ -109,19 +93,15 @@ int main (int argc, char *argv[]) VERBOSE (DEBUG, PRINT ("Initializing socket\n")); init_network_context (); - sock = open_listening_socket (port); - if (sock == INVALID_SOCKET) { + if (open_listening_socket (port) == 0) { VERBOSE (ERROR, PERROR ("Can't open listening socket\n")); return 1; } VERBOSE (INFO, PRINT ("Listening socket on port %d\n", port)); - signal (SIGTERM, &stop_server); - /* main loop */ while (1) { - conn = accept_incoming_connection (sock); - if (conn == INVALID_SOCKET) { + if (accept_incoming_connection () == 0) { usleep (1e5); continue; } @@ -130,7 +110,7 @@ int main (int argc, char *argv[]) unsigned char *data = {0}; - int len = receive_data (conn, &data); + int len = receive_data (&data); if (len == 0) { VERBOSE (WARNING, PRINT ("Connection closed by peer (rx)\n")); } else if (len < 0) { @@ -142,7 +122,7 @@ int main (int argc, char *argv[]) VERBOSE (DEBUG, PRINT ("Processing %s\n", data)); len = processing (data, len, &data); - int rc = send_data (conn, data, len); + int rc = send_data (data, len); if (rc == 0) { VERBOSE (WARNING, PRINT ("Connection closed by peer (tx)\n")); } else if (rc < 0) { @@ -154,12 +134,10 @@ int main (int argc, char *argv[]) if (data) { free (data); } - close_socket (conn); - conn = INVALID_SOCKET; + close_connection (); } VERBOSE (DEBUG, PRINT ("Closing socket\n")); - close_socket (sock); terminate_network_context (); return 2; @@ -173,8 +151,8 @@ int main (int argc, char *argv[]) // test: webserver.exe -v 2>&1 | grep -q 'missing verbose level' // test: webserver.exe -p 2>&1 | grep -q 'missing port number' // test: webserver.exe -p -1 2>&1 | grep -q 'incorrect port number' -// test: webserver.exe > test.log & pid=$!; sleep 1; kill -9 $pid; grep -q 'Listening socket on port 8080' test.log -// test: webserver.exe -p 8000 > test.log & pid=$!; sleep 1; kill -9 $pid; grep -q 'Listening socket on port 8000' test.log +// test: webserver.exe > test.log & pid=$!; sleep 1; kill -QUIT $pid; grep -q 'Listening socket on port 8080' test.log +// test: webserver.exe -p 8000 > test.log & pid=$!; sleep 1; kill -ABRT $pid; grep -q 'Listening socket on port 8000' test.log // test: webserver.exe & pid=$!; sleep 1; kill -TERM $pid; ps aux | grep -q [w]ebserver.exe && kill -9 $pid || rc=1; test x$rc = x1 /* vim: set ts=4 sw=4 et: */ -- 2.30.2