| 45 |
#include <sys/wait.h> |
#include <sys/wait.h> |
| 46 |
#include <systemd/sd-daemon.h> |
#include <systemd/sd-daemon.h> |
| 47 |
|
|
| 48 |
|
#define WAIT_CHILD_PROCESS_EXIT_TIMEOUT 5 // second |
| 49 |
|
#define WAIT_CHILD_PROCESS_KILL_TIMEOUT 1 // second |
| 50 |
|
|
| 51 |
struct process_sockaddr_t |
struct process_sockaddr_t |
| 52 |
{ |
{ |
| 53 |
pid_t pid; |
pid_t pid; |
| 125 |
static int fork_server(void) |
static int fork_server(void) |
| 126 |
{ |
{ |
| 127 |
ssh_event event; |
ssh_event event; |
| 128 |
|
long int ssh_timeout = 0; |
| 129 |
int pid; |
int pid; |
| 130 |
int i; |
int i; |
| 131 |
int ret; |
int ret; |
| 177 |
ssh_callbacks_init(&cb); |
ssh_callbacks_init(&cb); |
| 178 |
ssh_set_server_callbacks(SSH_session, &cb); |
ssh_set_server_callbacks(SSH_session, &cb); |
| 179 |
|
|
| 180 |
|
ssh_timeout = 60; // second |
| 181 |
|
if (ssh_options_set(SSH_session, SSH_OPTIONS_TIMEOUT, &ssh_timeout) < 0) |
| 182 |
|
{ |
| 183 |
|
log_error("Error setting SSH options: %s\n", ssh_get_error(SSH_session)); |
| 184 |
|
goto cleanup; |
| 185 |
|
} |
| 186 |
|
|
| 187 |
if (ssh_handle_key_exchange(SSH_session)) |
if (ssh_handle_key_exchange(SSH_session)) |
| 188 |
{ |
{ |
| 189 |
log_error("ssh_handle_key_exchange() error: %s\n", ssh_get_error(SSH_session)); |
log_error("ssh_handle_key_exchange() error: %s\n", ssh_get_error(SSH_session)); |
| 209 |
log_error("SSH auth error, tried %d times\n", cb_data.tries); |
log_error("SSH auth error, tried %d times\n", cb_data.tries); |
| 210 |
goto cleanup; |
goto cleanup; |
| 211 |
} |
} |
| 212 |
|
|
| 213 |
|
ssh_timeout = 0; |
| 214 |
|
if (ssh_options_set(SSH_session, SSH_OPTIONS_TIMEOUT, &ssh_timeout) < 0) |
| 215 |
|
{ |
| 216 |
|
log_error("Error setting SSH options: %s\n", ssh_get_error(SSH_session)); |
| 217 |
|
goto cleanup; |
| 218 |
|
} |
| 219 |
} |
} |
| 220 |
|
|
| 221 |
// Redirect Input |
// Redirect Input |
| 276 |
struct epoll_event ev, events[MAX_EVENTS]; |
struct epoll_event ev, events[MAX_EVENTS]; |
| 277 |
int nfds, epollfd; |
int nfds, epollfd; |
| 278 |
siginfo_t siginfo; |
siginfo_t siginfo; |
| 279 |
|
int notify_child_exit = 0; |
| 280 |
|
time_t tm_notify_child_exit = time(NULL); |
| 281 |
int sd_notify_stopping = 0; |
int sd_notify_stopping = 0; |
| 282 |
MENU_SET bbs_menu_new; |
MENU_SET bbs_menu_new; |
| 283 |
int i, j; |
int i, j; |
| 420 |
|
|
| 421 |
if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) |
if (SYS_server_exit && !SYS_child_exit && SYS_child_process_count > 0) |
| 422 |
{ |
{ |
| 423 |
log_common("Notify %d child process to exit\n", SYS_child_process_count); |
if (notify_child_exit == 0) |
|
if (kill(0, SIGTERM) < 0) |
|
| 424 |
{ |
{ |
| 425 |
log_error("Send SIGTERM signal failed (%d)\n", errno); |
sd_notifyf(0, "STATUS=Notify %d child process to exit", SYS_child_process_count); |
| 426 |
|
log_common("Notify %d child process to exit\n", SYS_child_process_count); |
| 427 |
|
|
| 428 |
|
if (kill(0, SIGTERM) < 0) |
| 429 |
|
{ |
| 430 |
|
log_error("Send SIGTERM signal failed (%d)\n", errno); |
| 431 |
|
} |
| 432 |
|
|
| 433 |
|
notify_child_exit = 1; |
| 434 |
|
tm_notify_child_exit = time(NULL); |
| 435 |
} |
} |
| 436 |
|
else if (notify_child_exit == 1 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_EXIT_TIMEOUT) |
| 437 |
|
{ |
| 438 |
|
sd_notifyf(0, "STATUS=Kill %d child process", SYS_child_process_count); |
| 439 |
|
|
| 440 |
|
for (i = 0; i < BBS_max_client; i++) |
| 441 |
|
{ |
| 442 |
|
if (process_sockaddr_pool[i].pid != 0) |
| 443 |
|
{ |
| 444 |
|
log_error("Kill child process (pid=%d)\n", process_sockaddr_pool[i].pid); |
| 445 |
|
if (kill(process_sockaddr_pool[i].pid, SIGKILL) < 0) |
| 446 |
|
{ |
| 447 |
|
log_error("Send SIGKILL signal failed (%d)\n", errno); |
| 448 |
|
} |
| 449 |
|
} |
| 450 |
|
} |
| 451 |
|
|
| 452 |
sd_notifyf(0, "STATUS=Waiting for %d child process to exit", SYS_child_process_count); |
notify_child_exit = 2; |
| 453 |
|
tm_notify_child_exit = time(NULL); |
| 454 |
|
} |
| 455 |
|
else if (notify_child_exit == 2 && time(NULL) - tm_notify_child_exit >= WAIT_CHILD_PROCESS_KILL_TIMEOUT) |
| 456 |
|
{ |
| 457 |
|
log_error("Main process prepare to exit without waiting for %d child process any longer\n", SYS_child_process_count); |
| 458 |
|
SYS_child_process_count = 0; |
| 459 |
|
} |
| 460 |
} |
} |
| 461 |
|
|
| 462 |
if (SYS_conf_reload && !SYS_server_exit) |
if (SYS_conf_reload && !SYS_server_exit) |