proper ending
authorLaurent Mazet <mazet@softndesign.org>
Fri, 19 May 2023 21:38:41 +0000 (23:38 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Fri, 19 May 2023 21:38:41 +0000 (23:38 +0200)
server.c
server.h
signal.c [deleted file]
signal.h [deleted file]
webserver.c

index 574e54a53830b2dc24029dac66f1d015a9ac2518..4ead290052798a3d3aa746b3fcabefe4e0f6aa7e 100644 (file)
--- a/server.c
+++ b/server.c
@@ -1,8 +1,5 @@
-/* depend: */
-/* cflags: */
-/* linker: color.o debug.o */
-
 #include <assert.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -15,8 +12,6 @@
 #include <fcntl.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
-//#include <sys/types.h>
-//#include <sys/socket.h>
 #include <sys/select.h>
 #endif
 #include <unistd.h>
 
 #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
 
 /* 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;
index 9e9f7254b7c8e0515915bc435bad1a6bb1de75d7..2e29b6e7e17070c559377f7a99fc8d7ee4da75b7 100644 (file)
--- 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 (file)
index bdeb7a9..0000000
--- a/signal.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <signal.h>
-#include <stdio.h>
-
-#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 (file)
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__ */
index 0110f279d315e5ce455634a33778a8f7327ceb98..8209ab86432233c0559f50ca55e6ca58a840dc81 100644 (file)
@@ -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 <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <signal.h>
 
 #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: */