Klaus Demo nginx / c8e9f26
implement "-s signal" option for Unix Igor Sysoev 13 years ago
9 changed file(s) with 119 addition(s) and 88 deletion(s). Raw diff Collapse all Expand all
187187 static ngx_uint_t ngx_show_configure;
188188 static u_char *ngx_conf_file;
189189 static u_char *ngx_conf_params;
190 #if (NGX_WIN32)
191190 static char *ngx_signal;
192 #endif
193191
194192
195193 static char **ngx_os_environ;
212210
213211 if (ngx_show_help) {
214212 ngx_log_stderr(
215 "Usage: nginx [-?hvVt]"
216 #if (NGX_WIN32)
217 " [-s signal]"
218 #endif
219 " [-c filename] [-g directives]" CRLF CRLF
213 "Usage: nginx [-?hvVt] [-s signal] [-c filename] "
214 "[-g directives]" CRLF CRLF
220215 "Options:" CRLF
221216 " -?,-h : this help" CRLF
222217 " -v : show version and exit" CRLF
223218 " -V : show version and configure options then exit"
224219 CRLF
225220 " -t : test configuration and exit" CRLF
226 #if (NGX_WIN32)
227 " -s signal : send signal to a master process" CRLF
228 #endif
221 " -s signal : send signal to a master process: "
222 "stop, quit, reopen, reload" CRLF
229223 " -c filename : set configuration file (default: "
230224 NGX_CONF_PATH ")" CRLF
231225 " -g directives : set global directives out of configuration "
336330 ngx_process = NGX_PROCESS_MASTER;
337331 }
338332
339 #if (NGX_WIN32)
340
341333 if (ngx_signal) {
342334 return ngx_signal_process(cycle, ngx_signal);
343335 }
344336
345 #else
337 #if !(NGX_WIN32)
346338
347339 if (ngx_init_signals(cycle->log) != NGX_OK) {
348340 return 1;
684676 ngx_log_stderr("the option \"-g\" requires parameter");
685677 return NGX_ERROR;
686678
687 #if (NGX_WIN32)
688679 case 's':
689680 if (*p) {
690681 ngx_signal = (char *) p;
708699
709700 ngx_log_stderr("invalid option: \"-s %s\"", ngx_signal);
710701 return NGX_ERROR;
711 #endif
712702
713703 default:
714704 ngx_log_stderr("invalid option: \"%c\"", *(p - 1));
568568 }
569569 }
570570
571 if (ngx_open_listening_sockets(cycle) != NGX_OK) {
572 goto failed;
573 }
574
575 if (!ngx_test_config) {
576 ngx_configure_listening_socket(cycle);
571 if (ngx_process != NGX_PROCESS_SIGNALLER) {
572 if (ngx_open_listening_sockets(cycle) != NGX_OK) {
573 goto failed;
574 }
575
576 if (!ngx_test_config) {
577 ngx_configure_listening_socket(cycle);
578 }
577579 }
578580
579581
982984 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
983985 ngx_delete_file_n " \"%s\" failed", name);
984986 }
987 }
988
989
990 ngx_int_t
991 ngx_signal_process(ngx_cycle_t *cycle, char *sig)
992 {
993 ssize_t n;
994 ngx_int_t pid;
995 ngx_file_t file;
996 ngx_core_conf_t *ccf;
997 u_char buf[NGX_INT64_LEN + 2];
998
999 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
1000
1001 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
1002
1003 file.name = ccf->pid;
1004 file.log = cycle->log;
1005
1006 file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
1007 NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
1008
1009 if (file.fd == NGX_INVALID_FILE) {
1010 ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
1011 ngx_open_file_n " \"%s\" failed", file.name.data);
1012 return 1;
1013 }
1014
1015 n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
1016
1017 if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
1018 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
1019 ngx_close_file_n " \"%s\" failed", file.name.data);
1020 }
1021
1022 if (n == NGX_ERROR) {
1023 return 1;
1024 }
1025
1026 while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
1027
1028 pid = ngx_atoi(buf, ++n);
1029
1030 if (pid == NGX_ERROR) {
1031 ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
1032 "invalid PID number \"%*s\" in \"%s\"",
1033 n, buf, file.name.data);
1034 return 1;
1035 }
1036
1037 return ngx_os_signal_process(cycle, sig, pid);
1038
9851039 }
9861040
9871041
115115 ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle);
116116 ngx_int_t ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log);
117117 void ngx_delete_pidfile(ngx_cycle_t *cycle);
118 ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
118119 void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
119120 char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
120121 ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
3636 ngx_int_t ngx_os_specific_init(ngx_log_t *log);
3737 void ngx_os_specific_status(ngx_log_t *log);
3838 ngx_int_t ngx_daemon(ngx_log_t *log);
39 ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid);
3940
4041
4142 ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size);
1212 typedef struct {
1313 int signo;
1414 char *signame;
15 char *name;
1516 void (*handler)(int signo);
1617 } ngx_signal_t;
1718
3536 ngx_signal_t signals[] = {
3637 { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
3738 "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
39 "reload",
3840 ngx_signal_handler },
3941
4042 { ngx_signal_value(NGX_REOPEN_SIGNAL),
4143 "SIG" ngx_value(NGX_REOPEN_SIGNAL),
44 "reopen",
4245 ngx_signal_handler },
4346
4447 { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
4548 "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
49 "",
4650 ngx_signal_handler },
4751
4852 { ngx_signal_value(NGX_TERMINATE_SIGNAL),
4953 "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
54 "stop",
5055 ngx_signal_handler },
5156
5257 { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
5358 "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
59 "quit",
5460 ngx_signal_handler },
5561
5662 { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
5763 "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
64 "",
5865 ngx_signal_handler },
5966
60 { SIGALRM, "SIGALRM", ngx_signal_handler },
61
62 { SIGINT, "SIGINT", ngx_signal_handler },
63
64 { SIGIO, "SIGIO", ngx_signal_handler },
65
66 { SIGCHLD, "SIGCHLD", ngx_signal_handler },
67
68 { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
69
70 { 0, NULL, NULL }
67 { SIGALRM, "SIGALRM", "", ngx_signal_handler },
68
69 { SIGINT, "SIGINT", "", ngx_signal_handler },
70
71 { SIGIO, "SIGIO", "", ngx_signal_handler },
72
73 { SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
74
75 { SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN },
76
77 { 0, NULL, "", NULL }
7178 };
7279
7380
539546 ngx_abort();
540547 }
541548 }
549
550
551 ngx_int_t
552 ngx_os_signal_process(ngx_cycle_t *cycle, char *name, ngx_int_t pid)
553 {
554 ngx_signal_t *sig;
555
556 for (sig = signals; sig->signo != 0; sig++) {
557 if (ngx_strcmp(name, sig->name) == 0) {
558 if (kill(pid, sig->signo) != -1) {
559 return 0;
560 }
561
562 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
563 "kill(%P, %d) failed", pid, sig->signo);
564 }
565 }
566
567 return 1;
568 }
1818 #define NGX_CMD_REOPEN 5
1919
2020
21 #define NGX_PROCESS_SINGLE 0
22 #define NGX_PROCESS_MASTER 1
23 #define NGX_PROCESS_WORKER 2
21 #define NGX_PROCESS_SINGLE 0
22 #define NGX_PROCESS_MASTER 1
23 #define NGX_PROCESS_WORKER 2
24 #define NGX_PROCESS_SIGNALLER 3
2425
2526
2627 void ngx_master_process_cycle(ngx_cycle_t *cycle);
99
1010 #include <ngx_config.h>
1111 #include <ngx_core.h>
12
1213
1314 #define NGX_IO_SENDFILE 1
1415
3132
3233 ngx_int_t ngx_os_init(ngx_log_t *log);
3334 void ngx_os_status(ngx_log_t *log);
35 ngx_int_t ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid);
3436
3537 ssize_t ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
3638 ssize_t ngx_overlapped_wsarecv(ngx_connection_t *c, u_char *buf, size_t size);
10051005
10061006
10071007 ngx_int_t
1008 ngx_signal_process(ngx_cycle_t *cycle, char *sig)
1009 {
1010 size_t n;
1011 HANDLE ev;
1012 ngx_int_t rc, pid;
1013 ngx_file_t file;
1014 ngx_core_conf_t *ccf;
1015 u_char buf[NGX_INT64_LEN + 2];
1016 char evn[NGX_PROCESS_SYNC_NAME];
1017
1018 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
1019
1020 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
1021
1022 file.name = ccf->pid;
1023 file.log = cycle->log;
1024
1025 file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
1026 NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
1027
1028 if (file.fd == NGX_INVALID_FILE) {
1029 ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
1030 ngx_open_file_n " \"%s\" failed", file.name.data);
1031 return 1;
1032 }
1033
1034 rc = 1;
1035
1036 n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
1037
1038 if (n == NGX_ERROR) {
1039 goto failed;
1040 }
1041
1042 while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
1043
1044 pid = ngx_atoi(buf, ++n);
1045
1046 if (pid == NGX_ERROR) {
1047 ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
1048 "invalid PID number \"%*s\" in \"%s\"",
1049 n, buf, file.name.data);
1050 goto failed;
1051 }
1008 ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_int_t pid)
1009 {
1010 HANDLE ev;
1011 ngx_int_t rc;
1012 char evn[NGX_PROCESS_SYNC_NAME];
10521013
10531014 ngx_sprintf((u_char *) evn, "ngx_%s_%ul%Z", sig, pid);
10541015
10561017 if (ev == NULL) {
10571018 ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
10581019 "OpenEvent(\"%s\") failed", evn);
1059 goto failed;
1020 return 1;
10601021 }
10611022
10621023 if (SetEvent(ev) == 0) {
10631024 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
10641025 "SetEvent(\"%s\") failed", evn);
1026 rc = 1;
1027
10651028 } else {
10661029 rc = 0;
10671030 }
10681031
10691032 ngx_close_handle(ev);
1070
1071 failed:
1072
1073 if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
1074 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
1075 ngx_close_file_n " \"%s\" failed", file.name.data);
1076 }
10771033
10781034 return rc;
10791035 }
1919
2020 void ngx_master_process_cycle(ngx_cycle_t *cycle);
2121 void ngx_single_process_cycle(ngx_cycle_t *cycle);
22 ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
2322 void ngx_close_handle(HANDLE h);
2423
2524