47 #include "httplistener.h" |
49 #include "httplistener.h" |
48 #include "srvctrl.h" |
50 #include "srvctrl.h" |
49 |
51 |
50 #include "configmanager.h" |
52 #include "configmanager.h" |
51 |
53 |
52 static int std_pipe_fds[2]; |
54 #define LOG_THREAD_STACK_SIZE 32768 |
|
55 #define LOG_THREAD_MAX_POLL_FAILS 10 |
|
56 #define LOG_THREAD_READ_BUF 2048 |
|
57 |
|
58 static int std_out[2]; |
|
59 static int std_err[2]; |
53 static WSBool is_daemon; |
60 static WSBool is_daemon; |
54 |
61 |
55 void test() { |
62 void test() { |
56 time_t t = time(NULL); |
63 time_t t = time(NULL); |
57 pool_handle_t *pool = pool_create(); |
64 pool_handle_t *pool = pool_create(); |
91 void sig_term(int sig) { |
98 void sig_term(int sig) { |
92 webserver_shutdown(); |
99 webserver_shutdown(); |
93 //exit(EXIT_SUCCESS); |
100 //exit(EXIT_SUCCESS); |
94 } |
101 } |
95 |
102 |
|
103 static void set_pipe_nonblocking(int fd) { |
|
104 int flags = 0; |
|
105 flags = fcntl(fd, F_GETFL, 0); |
|
106 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); |
|
107 } |
|
108 |
|
109 static char log_pipe_readbuf[LOG_THREAD_READ_BUF]; |
|
110 static char log_pipe_stdout_buf[LOG_THREAD_READ_BUF]; |
|
111 static char log_pipe_stderr_buf[LOG_THREAD_READ_BUF]; |
|
112 static size_t log_pipe_stdout_tmp_pos = 0; |
|
113 static size_t log_pipe_stderr_tmp_pos = 0; |
|
114 |
|
115 static int log_pipe(const char *name, int fd, char *buf, size_t *pos) { |
|
116 ssize_t r = read(fd, log_pipe_readbuf, 2); |
|
117 if(r <= 0) { |
|
118 return 1; |
|
119 } |
|
120 |
|
121 char *tmp = buf; |
|
122 int tmplen = *pos; |
|
123 |
|
124 int s = 0; |
|
125 for(int i=0;i<r;i++) { |
|
126 if(log_pipe_readbuf[i] == '\n') { |
|
127 if(tmplen + i-s > 0) { |
|
128 log_message(name, "%.*s%.*s", tmplen, tmp, i-s, log_pipe_readbuf + s); |
|
129 } |
|
130 tmplen = 0; |
|
131 *pos = 0; |
|
132 s = i+1; |
|
133 } |
|
134 } |
|
135 |
|
136 int remaining = r - s; |
|
137 if(tmplen + remaining >= LOG_THREAD_READ_BUF) { |
|
138 log_message(name, "%.*s%.*s", tmplen, tmp, remaining, log_pipe_readbuf + s); |
|
139 *pos = 0; |
|
140 } else if(remaining > 0) { |
|
141 memcpy(buf + *pos, log_pipe_readbuf + s, remaining); |
|
142 *pos += remaining; |
|
143 } |
|
144 |
|
145 return 0; |
|
146 } |
|
147 |
96 void* log_pipe_thread(void *data) { |
148 void* log_pipe_thread(void *data) { |
97 //FILE *log_out = fopen("log.txt", "a"); |
149 set_pipe_nonblocking(std_out[0]); |
98 |
150 set_pipe_nonblocking(std_err[0]); |
99 char buf[1024]; |
151 |
100 ssize_t r; |
152 struct pollfd fds[2]; |
101 while((r = read(std_pipe_fds[0], buf, 1024)) > 0) { |
153 fds[0].fd = std_out[0]; |
102 //fwrite(buf, 1, r, log_out); |
154 fds[0].events = POLLIN; |
103 //fflush(log_out); |
155 fds[1].fd = std_err[0]; |
104 } |
156 fds[1].events = POLLIN; |
105 |
157 |
106 //fclose(log_out); |
158 int poll_fails = 0; |
107 |
159 for(;;) { |
|
160 if(poll(fds, 1, 1000000) < 0) { |
|
161 if(errno == EINTR) { |
|
162 continue; |
|
163 } |
|
164 log_ereport(LOG_FAILURE, "log thread poll failed: %s", strerror(errno)); |
|
165 if(poll_fails++ > LOG_THREAD_MAX_POLL_FAILS) { |
|
166 break; |
|
167 } |
|
168 } |
|
169 |
|
170 // check stdout |
|
171 if(fds[0].revents & POLLIN) { |
|
172 if(log_pipe("stdout", fds[0].fd, log_pipe_stdout_buf, &log_pipe_stdout_tmp_pos)) { |
|
173 break; |
|
174 } |
|
175 } |
|
176 |
|
177 // check stderr |
|
178 if(fds[1].revents & POLLIN) { |
|
179 if(log_pipe("stderr", fds[0].fd, log_pipe_stderr_buf, &log_pipe_stderr_tmp_pos)) { |
|
180 break; |
|
181 } |
|
182 } |
|
183 } |
|
184 |
|
185 log_ereport(LOG_INFORM, "log thread end"); |
|
186 |
108 return NULL; |
187 return NULL; |
109 } |
188 } |
110 |
189 |
111 int main(int argc, char **argv) { |
190 int main(int argc, char **argv) { |
112 //test(); |
191 //test(); |
113 |
192 |
114 /* if the -c parameter is specified, we don't create a daemon */ |
193 // if the -c parameter is specified, we don't create a daemon |
115 is_daemon = 1; |
194 is_daemon = 1; |
116 for(int i=0;i<argc;i++) { |
195 for(int i=0;i<argc;i++) { |
117 char *p = argv[i]; |
196 char *p = argv[i]; |
118 if(p[0] == '-' && p[1] == 'c') { |
197 if(p[0] == '-' && p[1] == 'c') { |
119 is_daemon = 0; |
198 is_daemon = 0; |
120 break; |
199 break; |
121 } |
200 } |
122 } |
201 } |
123 if(is_daemon) { |
202 if(is_daemon) { |
124 /* create daemon */ |
203 // create daemon |
125 pid_t pid = fork(); |
204 pid_t pid = fork(); |
126 if(pid < 0) { |
205 if(pid < 0) { |
127 return EXIT_FAILURE; |
206 return EXIT_FAILURE; |
128 } else if(pid > 0) { |
207 } else if(pid > 0) { |
129 return EXIT_SUCCESS; |
208 return EXIT_SUCCESS; |
137 |
216 |
138 for(int i=0;i<3;i++) { |
217 for(int i=0;i<3;i++) { |
139 close(i); |
218 close(i); |
140 } |
219 } |
141 |
220 |
142 /* stdio redirection */ |
221 // stdio redirection |
143 /* create pipes */ |
222 // create pipes |
144 if(pipe(std_pipe_fds) != 0) { |
223 if(pipe(std_out) != 0) { |
145 perror("pipe"); |
224 perror("pipe"); |
146 return EXIT_FAILURE; |
225 return EXIT_FAILURE; |
147 } |
226 } |
148 //FILE *ws_out = fdopen(std_pipe_fds[1], "w"); |
227 if(pipe(std_err) != 0) { |
149 //*stdout = *ws_out; |
228 perror("pipe"); |
150 //*stderr = *ws_out; |
229 return EXIT_FAILURE; |
151 //dup2(std_pipe_fds[1], 1); |
230 } |
152 //dup2(std_pipe_fds[1], 2); |
231 |
|
232 dup2(std_out[1], 1); |
|
233 dup2(std_err[1], 2); |
|
234 close(std_err[1]); |
|
235 |
|
236 // set log thread stack size |
|
237 pthread_attr_t tattr; |
|
238 pthread_attr_init(&tattr); |
|
239 pthread_attr_setstacksize(&tattr, LOG_THREAD_STACK_SIZE); |
153 |
240 |
154 pthread_t tid; |
241 pthread_t tid; |
155 pthread_create(&tid, NULL, log_pipe_thread, NULL); |
242 pthread_create(&tid, &tattr, log_pipe_thread, NULL); |
156 } |
243 } |
157 |
244 |
158 pool_init(NULL, NULL, NULL); |
245 pool_init(NULL, NULL, NULL); |
159 |
246 |
160 /* add signal handler */ |
247 // add signal handler |
161 signal(SIGUSR1, sig_usr1_reload); |
248 signal(SIGUSR1, sig_usr1_reload); |
162 signal(SIGTERM, sig_term); |
249 signal(SIGTERM, sig_term); |
163 signal(SIGINT, sig_term); |
250 signal(SIGINT, sig_term); |
164 |
251 |
165 struct sigaction act; |
252 struct sigaction act; |
166 ZERO(&act, sizeof(struct sigaction)); |
253 ZERO(&act, sizeof(struct sigaction)); |
167 act.sa_handler = SIG_IGN; |
254 act.sa_handler = SIG_IGN; |
168 sigaction(SIGPIPE, &act, NULL); |
255 sigaction(SIGPIPE, &act, NULL); |
169 |
256 |
170 /* start webserver */ |
257 // start webserver |
171 log_ereport(LOG_INFORM, "startup"); |
258 log_ereport(LOG_INFORM, "startup"); |
172 |
259 |
173 int status; |
260 int status; |
174 status = webserver_init(); |
261 status = webserver_init(); |
175 if(status != 0) { |
262 if(status != 0) { |