/* WebROaR - Ruby Application Server - http://webroar.in/ * Copyright (C) 2009 WebROaR * * This file is part of WebROaR. * * WebROaR is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * WebROaR is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with WebROaR. If not, see . */ #include #include #include #include // wr_server object static wr_svr_t *server; /** Cleanup and destroy the Server */ static inline void cleanup(wr_svr_t *server) { LOG_FUNCTION // Delete 'webroar.sock' file remove(WR_TMP_SOCK_FILE); // Stop event loop ev_unloop(server->ebb_svr.loop, EVUNLOOP_ALL); // Destroy the Server structure wr_svr_free(server); // Delete 'webroar.pid' file remove(WR_PID_FILE); LOG_INFO("Shutting down network server. No more request can be served"); // Destroy logger object close_logger(); } /** Daemonize the process */ static inline void daemonize() { LOG_FUNCTION /* Our process ID and Session ID */ pid_t pid, sid; pid_t saved_pid = -1; if(saved_pid > 0) { printf("SERVER IS ALREADY RUNNING WITH PID %i",saved_pid); exit(-1); } LOG_DEBUG(4,"Calling fork"); /* Fork off the parent process */ pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { exit(EXIT_SUCCESS); } /* Open any logs here */ /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { /* Log the failure */ exit(EXIT_FAILURE); } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); int i=open("/dev/null",O_RDWR); /* open stdin and connect to /dev/null */ LOG_DEBUG(DEBUG,"i=%d",i); int j = dup(i); /* stdout */ LOG_DEBUG(DEBUG,"j=%d",j); j = dup(i); /* stderr */ LOG_DEBUG(DEBUG,"j=%d",j); //Log current pid char str[WR_SHORT_STR_LEN]; int pid_FD=open(WR_PID_FILE,O_RDWR|O_CREAT,0640); LOG_DEBUG(4,"FD for PID is %i",pid_FD); if (pid_FD<0) { LOG_ERROR(5,"CANNOT OPEN PID FILE:%s",strerror(errno)); exit(1); /* can not open */ } int lpk = lockf(pid_FD,F_TLOCK,0); if (lpk<0) { printf("SERVER ALREADY RUNNING..\n"); //can not lock exit(-1); } /* first instance continues */ sprintf(str,"%d\n",getpid()); int x = write(pid_FD,str,strlen(str)); /* record pid to lockfile */ close(pid_FD); signal(SIGCHLD, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); /* Close out the standard file descriptors */ LOG_DEBUG(4,"Daemonize Server Done"); } /** Handle interrupt signal */ void sigproc() { LOG_DEBUG(4,"**************Caught Interrupt Signal************"); // lear keep alive flag. server->is_running = 0; } int main(int argc, char *argv[]) { int retval = 0; wr_conf_t *conf=NULL; char *WR_ROOT = argv[1]; //Initialize logger if(initialize_logger(WR_LOG_FILE) == 0) { LOG_DEBUG(DEBUG,"Logging started in %s file",WR_LOG_FILE); } else { printf("Logger initialization failed. Please make sure you have write permission on '/var/log/webroar' directory."); } //Allocate and initialize configuration structure conf = wr_conf_read(WR_ROOT); if(conf == NULL ) { LOG_ERROR(FATAL,"Configuration reading failed."); printf("Server not started.\nProblem with reading the configuration file. Kindly refer the log files for details.\n"); return -1; } #ifdef L_DEBUG set_log_severity(DEBUG); #else set_log_severity(conf->server->log_level); #endif // Add Admin Panel wr_conf_admin_panel_add(conf); //TODO: Windows Portability? signal(SIGINT, sigproc); signal(SIGPIPE, SIG_IGN); signal(SIGHUP,sigproc); /* catch hangup signal */ signal(SIGTERM,sigproc); /* catch terminate signal */ // Initialize and start the Server to accept requests retval = wr_svr_init(&server, conf); if(retval<0) { LOG_ERROR(FATAL,"Initialization of network server failed."); printf("Server not started. Kindly refer the log files for details.\n"); return retval; } LOG_INFO("Network server successfully initialized on port %d",server->conf->server->port); // Set keep alive flag server->is_running = 1; // Initialize contol port/sock path to recive control messages retval = wr_ctl_init(server); if(retval < 0) { LOG_ERROR(FATAL,"Controller Initialization failed."); printf("Server not started. Kindly refer the log files for details.\n"); wr_svr_free(server); return retval; } LOG_INFO("Controller initialized"); // Fork processes and start 'webroar-workers's wr_app_init(server); //Daemonize the Server daemonize(); LOG_DEBUG(4,"Done daemon"); // Start event loop while(server->is_running) { ev_loop(server->ebb_svr.loop,EVLOOP_ONESHOT); } // Cleanup LOG_DEBUG(DEBUG,"Call cleanup"); cleanup(server); return 0; }