--- lbbs/src/net_server.c 2025/05/09 11:21:11 1.19 +++ lbbs/src/net_server.c 2025/05/11 02:42:38 1.23 @@ -23,9 +23,12 @@ #include "log.h" #include "io.h" #include "fork.h" -#include "tcplib.h" #include "menu.h" +#include +#include +#include #include +#include #include #include #include @@ -53,20 +56,30 @@ int net_server(const char *hostaddr, in_ } sin.sin_family = AF_INET; - sin.sin_addr.s_addr = - (strnlen(hostaddr, sizeof(hostaddr)) > 0 ? inet_addr(hostaddr) : INADDR_ANY); + sin.sin_addr.s_addr = (hostaddr[0] != '\0' ? inet_addr(hostaddr) : INADDR_ANY); sin.sin_port = htons(port); + // Reuse address and port + flags = 1; + if (setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)) < 0) + { + log_error("setsockopt SO_REUSEADDR error (%d)\n", errno); + } + if (setsockopt(socket_server, SOL_SOCKET, SO_REUSEPORT, &flags, sizeof(flags)) < 0) + { + log_error("setsockopt SO_REUSEPORT error (%d)\n", errno); + } + if (bind(socket_server, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - log_error("Bind address %s:%u failed\n", - inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + log_error("Bind address %s:%u failed (%d)\n", + inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), errno); exit(2); } if (listen(socket_server, 10) < 0) { - log_error("Socket listen failed\n"); + log_error("Socket listen failed (%d)\n", errno); exit(3); } @@ -87,18 +100,18 @@ int net_server(const char *hostaddr, in_ { sigprocmask(SIG_BLOCK, &nsigset, &osigset); - while (SYS_child_exit_count > 0) + while ((SYS_child_exit || SYS_server_exit) && SYS_child_process_count > 0) { siginfo.si_pid = 0; ret = waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG); if (ret == 0 && siginfo.si_pid > 0) { - SYS_child_exit_count--; SYS_child_process_count--; log_std("Child process (%d) exited\n", siginfo.si_pid); } else if (ret == 0) { + SYS_child_exit = 0; break; } else if (ret < 0) @@ -108,7 +121,16 @@ int net_server(const char *hostaddr, in_ } } - if (SYS_menu_reload) + if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) + { + log_std("Notify %d child process to exit\n", SYS_child_process_count); + if (kill(0, SIGTERM) < 0) + { + log_error("Send SIGTERM signal failed (%d)\n", errno); + } + } + + if (SYS_menu_reload && !SYS_server_exit) { if (reload_menu(&bbs_menu) < 0) { @@ -126,8 +148,8 @@ int net_server(const char *hostaddr, in_ FD_ZERO(&testfds); FD_SET(socket_server, &testfds); - timeout.tv_sec = 1; - timeout.tv_usec = 0; + timeout.tv_sec = 0; + timeout.tv_usec = 100 * 1000; // 0.1 second ret = select(FD_SETSIZE, &testfds, NULL, NULL, &timeout);