UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <signal.h> 34 #include <errno.h> 35 #include <pthread.h> 36 37 #include "../util/pool.h" 38 #include "../public/nsapi.h" 39 #include "../util/plist.h" 40 #include "../util/date.h" 41 42 #include "../../ucx/string.h" 43 44 #include "webserver.h" 45 #include "log.h" 46 #include "httprequest.h" 47 #include "httplistener.h" 48 #include "srvctrl.h" 49 50 #include "configmanager.h" 51 52 static int std_pipe_fds[2]; 53 static WSBool is_daemon; 54 55 void test() { 56 time_t t = time(NULL); 57 pool_handle_t *pool = pool_create(); 58 sstr_t date = date_format_http(t, pool); 59 printf("%s\n", date.ptr); 60 } 61 62 63 WSBool main_is_daemon(void) { 64 return is_daemon; 65 } 66 67 /* 68 * SIGUSR1: reload the configuration files 69 */ 70 void sig_usr1_reload(int sig) { 71 log_ereport(LOG_INFORM, "sig reload"); 72 73 if(cfgmgr_load_config(NULL) != 0) { 74 log_ereport(LOG_FAILURE, "cannot reload config"); 75 } 76 // start newly created listeners 77 start_all_listener(); 78 79 signal(SIGUSR1, sig_usr1_reload); 80 } 81 82 /* 83 * SIGTERM: stop the server 84 */ 85 void sig_term(int sig) { 86 webserver_shutdown(); 87 //exit(EXIT_SUCCESS); 88 } 89 90 void* log_pipe_thread(void *data) { 91 //FILE *log_out = fopen("log.txt", "a"); 92 93 char buf[1024]; 94 ssize_t r; 95 while((r = read(std_pipe_fds[0], buf, 1024)) > 0) { 96 //fwrite(buf, 1, r, log_out); 97 //fflush(log_out); 98 } 99 100 //fclose(log_out); 101 102 return NULL; 103 } 104 105 int main(int argc, char **argv) { 106 //test(); 107 108 /* if the -c parameter is specified, we don't create a daemon */ 109 is_daemon = 1; 110 for(int i=0;i<argc;i++) { 111 char *p = argv[i]; 112 if(p[0] == '-' && p[1] == 'c') { 113 is_daemon = 0; 114 break; 115 } 116 } 117 if(is_daemon) { 118 /* create daemon */ 119 pid_t pid = fork(); 120 if(pid < 0) { 121 return EXIT_FAILURE; 122 } else if(pid > 0) { 123 return EXIT_SUCCESS; 124 } 125 126 if(setsid() < 0) { 127 fprintf(stderr, "setsid failed\n"); 128 return EXIT_FAILURE; 129 } 130 printf("start daemon\n"); 131 132 for(int i=0;i<3;i++) { 133 close(i); 134 } 135 136 /* stdio redirection */ 137 /* create pipes */ 138 if(pipe(std_pipe_fds) != 0) { 139 perror("pipe"); 140 return EXIT_FAILURE; 141 } 142 //FILE *ws_out = fdopen(std_pipe_fds[1], "w"); 143 //*stdout = *ws_out; 144 //*stderr = *ws_out; 145 //dup2(std_pipe_fds[1], 1); 146 //dup2(std_pipe_fds[1], 2); 147 148 pthread_t tid; 149 pthread_create(&tid, NULL, log_pipe_thread, NULL); 150 } 151 152 pool_init(NULL, NULL, NULL); 153 154 /* add signal handler */ 155 signal(SIGUSR1, sig_usr1_reload); 156 signal(SIGTERM, sig_term); 157 signal(SIGINT, sig_term); 158 159 struct sigaction act; 160 ZERO(&act, sizeof(struct sigaction)); 161 act.sa_handler = SIG_IGN; 162 sigaction(SIGPIPE, &act, NULL); 163 164 /* start webserver */ 165 log_ereport(LOG_INFORM, "startup"); 166 167 int status; 168 status = webserver_init(); 169 if(status != 0) { 170 log_ereport(LOG_FAILURE, "cannot initialize server."); 171 return EXIT_FAILURE; 172 } 173 174 status = webserver_run(); 175 if(status != 0) { 176 log_ereport(LOG_FAILURE, "cannot run server."); 177 return EXIT_FAILURE; 178 } 179 180 if(srvctrl_wait()) { 181 return EXIT_FAILURE; 182 } 183 184 /* TODO: join threads (or not?) */ 185 /* 186 while(1) { 187 if(is_daemon) { 188 fflush(stdout); 189 fflush(stderr); 190 } 191 sleep(10000); 192 if(0) { 193 break; 194 } 195 } 196 */ 197 198 return EXIT_SUCCESS; 199 } 200 201