blob: 7498ae609e7b92b1d159257a0d36a7a5447e6560 [file] [log] [blame]
Igor Sysoevfa73aac2003-05-21 13:28:21 +00001
2#include <ngx_config.h>
3#include <ngx_core.h>
4
5
Igor Sysoev078d1b22004-06-30 15:30:41 +00006int ngx_ncpu;
Igor Sysoevfa73aac2003-05-21 13:28:21 +00007int ngx_max_sockets;
8int ngx_inherited_nonblocking;
9
10
Igor Sysoevd09f7a12004-06-15 17:47:16 +000011#if (NGX_POSIX_IO)
12
13ngx_os_io_t ngx_os_io = {
14 ngx_unix_recv,
15 ngx_readv_chain,
16 NULL,
17 ngx_writev_chain,
18 0
19};
20
21
22int ngx_os_init(ngx_log_t *log)
23{
24 return ngx_posix_init(log);
25}
26
27
28#endif
29
30
Igor Sysoevdc867cd2003-12-14 20:10:27 +000031void ngx_signal_handler(int signo);
Igor Sysoev7349bef2003-07-03 16:30:22 +000032
33
Igor Sysoevdc867cd2003-12-14 20:10:27 +000034typedef struct {
35 int signo;
36 char *signame;
Igor Sysoevdc867cd2003-12-14 20:10:27 +000037 void (*handler)(int signo);
38} ngx_signal_t;
39
40
41ngx_signal_t signals[] = {
Igor Sysoev3c3ca172004-01-05 20:55:48 +000042 { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
43 "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000044 ngx_signal_handler },
45
Igor Sysoev3c3ca172004-01-05 20:55:48 +000046 { ngx_signal_value(NGX_REOPEN_SIGNAL),
47 "SIG" ngx_value(NGX_REOPEN_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000048 ngx_signal_handler },
49
Igor Sysoev49783fc2004-01-13 16:43:23 +000050 { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
51 "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
Igor Sysoev3c3ca172004-01-05 20:55:48 +000052 ngx_signal_handler },
53
54 { ngx_signal_value(NGX_TERMINATE_SIGNAL),
55 "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000056 ngx_signal_handler },
57
58 { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
59 "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
Igor Sysoevdc867cd2003-12-14 20:10:27 +000060 ngx_signal_handler },
61
Igor Sysoev3c3ca172004-01-05 20:55:48 +000062 { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
63 "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
Igor Sysoev3c3ca172004-01-05 20:55:48 +000064 ngx_signal_handler },
65
Igor Sysoev81233322004-01-28 20:38:54 +000066 { SIGALRM, "SIGALRM", ngx_signal_handler },
67
Igor Sysoev80340f02004-01-13 21:33:59 +000068 { SIGINT, "SIGINT", ngx_signal_handler },
69
Igor Sysoev87350f22004-06-15 07:55:11 +000070 { SIGIO, "SIGIO", ngx_signal_handler },
71
Igor Sysoevf2954c32004-01-08 21:02:06 +000072 { SIGCHLD, "SIGCHLD", ngx_signal_handler },
Igor Sysoevdc867cd2003-12-14 20:10:27 +000073
Igor Sysoevf2954c32004-01-08 21:02:06 +000074 { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
Igor Sysoevdc867cd2003-12-14 20:10:27 +000075
Igor Sysoevf2954c32004-01-08 21:02:06 +000076 { 0, NULL, NULL }
Igor Sysoevdc867cd2003-12-14 20:10:27 +000077};
78
79
Igor Sysoevfa73aac2003-05-21 13:28:21 +000080int ngx_posix_init(ngx_log_t *log)
81{
Igor Sysoevdc867cd2003-12-14 20:10:27 +000082 ngx_signal_t *sig;
83 struct rlimit rlmt;
84 struct sigaction sa;
Igor Sysoevfa73aac2003-05-21 13:28:21 +000085
Igor Sysoev0ab91b92004-06-06 19:49:18 +000086 ngx_pagesize = getpagesize();
87
Igor Sysoev078d1b22004-06-30 15:30:41 +000088 if (ngx_ncpu == 0) {
89 ngx_ncpu = 1;
90 }
91
Igor Sysoevdc867cd2003-12-14 20:10:27 +000092 for (sig = signals; sig->signo != 0; sig++) {
93 ngx_memzero(&sa, sizeof(struct sigaction));
94 sa.sa_handler = sig->handler;
95 sigemptyset(&sa.sa_mask);
96 if (sigaction(sig->signo, &sa, NULL) == -1) {
97 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
98 "sigaction(%s) failed", sig->signame);
99 return NGX_ERROR;
100 }
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000101 }
102
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000103 if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
104 ngx_log_error(NGX_LOG_ALERT, log, errno,
105 "getrlimit(RLIMIT_NOFILE) failed)");
106 return NGX_ERROR;
107 }
108
109 ngx_log_error(NGX_LOG_INFO, log, 0,
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000110 "getrlimit(RLIMIT_NOFILE): " RLIM_T_FMT ":" RLIM_T_FMT,
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000111 rlmt.rlim_cur, rlmt.rlim_max);
112
113 ngx_max_sockets = rlmt.rlim_cur;
114
115#if (HAVE_INHERITED_NONBLOCK)
116 ngx_inherited_nonblocking = 1;
117#else
118 ngx_inherited_nonblocking = 0;
119#endif
120
121 return NGX_OK;
122}
123
124
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000125void ngx_signal_handler(int signo)
126{
Igor Sysoevf2954c32004-01-08 21:02:06 +0000127 char *action;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000128 struct timeval tv;
Igor Sysoev80340f02004-01-13 21:33:59 +0000129 ngx_int_t ignore;
Igor Sysoeva9030eb2004-01-06 16:49:34 +0000130 ngx_err_t err;
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000131 ngx_signal_t *sig;
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000132
Igor Sysoev80340f02004-01-13 21:33:59 +0000133 ignore = 0;
Igor Sysoev49783fc2004-01-13 16:43:23 +0000134
Igor Sysoeva9030eb2004-01-06 16:49:34 +0000135 err = ngx_errno;
136
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000137 for (sig = signals; sig->signo != 0; sig++) {
138 if (sig->signo == signo) {
139 break;
140 }
141 }
142
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000143 ngx_gettimeofday(&tv);
144 ngx_time_update(tv.tv_sec);
Igor Sysoeve89c4582003-12-19 08:15:11 +0000145
Igor Sysoevf2954c32004-01-08 21:02:06 +0000146 action = "";
147
148 switch (ngx_process) {
149
150 case NGX_PROCESS_MASTER:
Igor Sysoevd8e1f072004-01-22 06:47:28 +0000151 case NGX_PROCESS_SINGLE:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000152 switch (signo) {
153
154 case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
155 ngx_quit = 1;
Igor Sysoev5c8c52f2004-01-23 09:26:18 +0000156 action = ", shutting down";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000157 break;
158
159 case ngx_signal_value(NGX_TERMINATE_SIGNAL):
Igor Sysoev49783fc2004-01-13 16:43:23 +0000160 case SIGINT:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000161 ngx_terminate = 1;
162 action = ", exiting";
163 break;
164
Igor Sysoev49783fc2004-01-13 16:43:23 +0000165 case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
166 ngx_noaccept = 1;
167 action = ", stop the accepting connections";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000168 break;
169
170 case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
171 ngx_reconfigure = 1;
172 action = ", reconfiguring";
173 break;
174
175 case ngx_signal_value(NGX_REOPEN_SIGNAL):
Igor Sysoevc5371672004-02-04 20:30:08 +0000176 ngx_reopen = 1;
177 action = ", reopen logs";
178 break;
Igor Sysoevf2954c32004-01-08 21:02:06 +0000179
180 case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
Igor Sysoev92602942004-02-05 16:58:36 +0000181 if (getppid() > 1 || ngx_new_binary > 0) {
182
Igor Sysoev80340f02004-01-13 21:33:59 +0000183 /*
184 * Ignore the signal in the new binary if its parent is
185 * not the init process, i.e. the old binary's process
186 * is still running. Or ingore the signal in the old binary's
187 * process if the new binary's process is already running.
188 */
189
190 action = ", ignoring";
191 ignore = 1;
192 break;
193 }
194
Igor Sysoevf2954c32004-01-08 21:02:06 +0000195 ngx_change_binary = 1;
196 action = ", changing binary";
197 break;
198
Igor Sysoev81233322004-01-28 20:38:54 +0000199 case SIGALRM:
200 if (!ngx_terminate) {
201 ngx_timer = 1;
Igor Sysoev87350f22004-06-15 07:55:11 +0000202 action = ", shutting down old worker processes";
Igor Sysoev81233322004-01-28 20:38:54 +0000203 }
204
205 break;
206
Igor Sysoev87350f22004-06-15 07:55:11 +0000207 case SIGIO:
208 ngx_sigio = 1;
209 break;
210
Igor Sysoevf2954c32004-01-08 21:02:06 +0000211 case SIGCHLD:
212 ngx_reap = 1;
213 break;
214 }
215
216 break;
217
218 case NGX_PROCESS_WORKER:
219 switch (signo) {
220
221 case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
222 ngx_quit = 1;
Igor Sysoev5c8c52f2004-01-23 09:26:18 +0000223 action = ", shutting down";
Igor Sysoevf2954c32004-01-08 21:02:06 +0000224 break;
225
226 case ngx_signal_value(NGX_TERMINATE_SIGNAL):
Igor Sysoev49783fc2004-01-13 16:43:23 +0000227 case SIGINT:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000228 ngx_terminate = 1;
229 action = ", exiting";
230 break;
231
Igor Sysoevf2954c32004-01-08 21:02:06 +0000232 case ngx_signal_value(NGX_REOPEN_SIGNAL):
233 ngx_reopen = 1;
234 action = ", reopen logs";
235 break;
Igor Sysoevf2954c32004-01-08 21:02:06 +0000236
237 case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
Igor Sysoev49783fc2004-01-13 16:43:23 +0000238 case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
Igor Sysoevf2954c32004-01-08 21:02:06 +0000239 case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
Igor Sysoev87350f22004-06-15 07:55:11 +0000240 case SIGIO:
Igor Sysoevf2954c32004-01-08 21:02:06 +0000241 action = ", ignoring";
242 break;
243 }
244
245 break;
246 }
247
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000248 ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
Igor Sysoevf2954c32004-01-08 21:02:06 +0000249 "signal %d (%s) received%s", signo, sig->signame, action);
Igor Sysoeve89c4582003-12-19 08:15:11 +0000250
Igor Sysoev80340f02004-01-13 21:33:59 +0000251 if (ignore) {
252 ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0,
253 "the changing binary signal is ignored: "
254 "you should shutdown or terminate "
255 "before either old or new binary's process");
256 }
257
Igor Sysoevf2954c32004-01-08 21:02:06 +0000258 if (signo == SIGCHLD) {
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000259 ngx_process_get_status();
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000260 }
Igor Sysoeva9030eb2004-01-06 16:49:34 +0000261
262 ngx_set_errno(err);
Igor Sysoevdc867cd2003-12-14 20:10:27 +0000263}
264
265
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000266int ngx_posix_post_conf_init(ngx_log_t *log)
267{
268 ngx_fd_t pp[2];
269
270 if (pipe(pp) == -1) {
271 ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
272 return NGX_ERROR;
273 }
274
275 if (dup2(pp[1], STDERR_FILENO) == -1) {
276 ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
277 return NGX_ERROR;
278 }
279
280 if (pp[1] > STDERR_FILENO) {
281 if (close(pp[1]) == -1) {
282 ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
283 return NGX_ERROR;
284 }
285 }
286
287 return NGX_OK;
288}