src/server/daemon/main.c

Sat, 14 Jan 2017 11:27:55 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 14 Jan 2017 11:27:55 +0100
changeset 146
a9591a91c004
parent 142
55298bc9ed28
child 156
724e107983e9
permissions
-rw-r--r--

fixes server user init

/*
 * 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;
}

mercurial