Sat, 18 Feb 2017 13:27:25 +0100
adds public aio and poll api and asynchronous send_range function
aio and poll api is only implemented on solaris yet
send_file saf uses send_range_aio for single range requests
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2013 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #include <pthread.h> #include "../util/pool.h" #include "../public/nsapi.h" #include "../util/plist.h" #include "../util/date.h" #include "webserver.h" #include "log.h" #include "httprequest.h" #include "httplistener.h" #include "configmanager.h" static int std_pipe_fds[2]; static WSBool is_daemon; void test() { time_t t = time(NULL); pool_handle_t *pool = pool_create(); sstr_t date = date_format_http(t, pool); printf("%s\n", date.ptr); } WSBool main_is_daemon(void) { return is_daemon; } /* * SIGUSR1: reload the configuration files */ void sig_usr1_reload(int sig) { log_ereport(LOG_INFORM, "sig reload"); if(cfgmgr_load_config(NULL) != 0) { log_ereport(LOG_FAILURE, "cannot reload config"); } // start newly created listeners start_all_listener(); signal(SIGUSR1, sig_usr1_reload); } /* * SIGTERM: stop the server */ void sig_term(int sig) { webserver_shutdown(); exit(EXIT_SUCCESS); } void* log_pipe_thread(void *data) { //FILE *log_out = fopen("log.txt", "a"); char buf[1024]; ssize_t r; while((r = read(std_pipe_fds[0], buf, 1024)) > 0) { //fwrite(buf, 1, r, log_out); //fflush(log_out); } //fclose(log_out); return NULL; } int main(int argc, char **argv) { //test(); /* if the -c parameter is specified, we don't create a daemon */ is_daemon = 1; for(int i=0;i<argc;i++) { char *p = argv[i]; if(p[0] == '-' && p[1] == 'c') { is_daemon = 0; break; } } if(is_daemon) { /* create daemon */ pid_t pid = fork(); if(pid < 0) { return EXIT_FAILURE; } else if(pid > 0) { return EXIT_SUCCESS; } if(setsid() < 0) { fprintf(stderr, "setsid failed\n"); return EXIT_FAILURE; } printf("start daemon\n"); for(int i=0;i<3;i++) { close(i); } /* stdio redirection */ /* create pipes */ if(pipe(std_pipe_fds) != 0) { perror("pipe"); return EXIT_FAILURE; } //FILE *ws_out = fdopen(std_pipe_fds[1], "w"); //*stdout = *ws_out; //*stderr = *ws_out; //dup2(std_pipe_fds[1], 1); //dup2(std_pipe_fds[1], 2); pthread_t tid; pthread_create(&tid, NULL, log_pipe_thread, NULL); } pool_init(NULL, NULL, NULL); /* add signal handler */ signal(SIGUSR1, sig_usr1_reload); signal(SIGTERM, sig_term); signal(SIGINT, sig_term); struct sigaction act; ZERO(&act, sizeof(struct sigaction)); act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, NULL); /* start webserver */ log_ereport(LOG_INFORM, "startup"); int status; status = webserver_init(); if(status != 0) { log_ereport(LOG_FAILURE, "Cannot initialize server."); return EXIT_FAILURE; } status = webserver_run(); if(status != 0) { log_ereport(LOG_FAILURE, "Cannot run server."); return EXIT_FAILURE; } /* TODO: join threads (or not?) */ while(1) { if(is_daemon) { fflush(stdout); fflush(stderr); } sleep(10000); if(0) { break; } } return EXIT_SUCCESS; }