src/server/daemon/main.c

changeset 434
ff576305ae6e
parent 415
d938228c382e
child 443
ef3c8a0e1fee
equal deleted inserted replaced
433:39fe86ae4db0 434:ff576305ae6e
31 #include <stdlib.h> 31 #include <stdlib.h>
32 #include <unistd.h> 32 #include <unistd.h>
33 #include <signal.h> 33 #include <signal.h>
34 #include <errno.h> 34 #include <errno.h>
35 #include <pthread.h> 35 #include <pthread.h>
36 #include <fcntl.h>
37 #include <poll.h>
36 38
37 #include "../util/pool.h" 39 #include "../util/pool.h"
38 #include "../public/nsapi.h" 40 #include "../public/nsapi.h"
39 #include "../util/plist.h" 41 #include "../util/plist.h"
40 #include "../util/date.h" 42 #include "../util/date.h"
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) {

mercurial