xdasd_unix.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00039 #include "xdasd_main.h"
00040 #include "xdasd_log.h"
00041 #include "xdasd_cmdline.h"
00042 
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 #include <errno.h>
00047 #include <sys/types.h>
00048 #include <sys/stat.h>
00049 #include <signal.h>
00050 #include <unistd.h>
00051 
00066 static int xdasd_check_pid(const char * pidfile)
00067 {
00068    pid_t pid;
00069    FILE * f;
00070    char pidstr[14] = {0};
00071 
00072    
00073    if ((f = fopen(pidfile, "r")) != 0)
00074    {
00075       fgets(pidstr, sizeof(pidstr), f);
00076       pid = atoi(pidstr);
00077       if (pid && kill(pid, 0) == 0)
00078          return -1;  
00079       fclose(f);
00080    }
00081    return 0;
00082 }
00083 
00093 static int xdasd_write_pid(const char * pidfile, pid_t pid)
00094 {
00095    FILE * f;
00096 
00097    if ((f = fopen(pidfile, "w")) == 0)
00098       return -1;
00099 
00100    fprintf(f, "%i", (int)pid);
00101    fclose(f);
00102    return 0;
00103 }
00104 
00114 static int xdasd_daemonize(void)
00115 {
00116    int i;
00117    pid_t pid;
00118 
00119    switch (pid = fork())
00120    {
00121       case -1: return -1;  
00122       case  0: break;      
00123       default:             
00124          exit(0);
00125    }
00126 
00127    
00128    setsid();
00129 
00130    chdir("/");
00131 
00132    umask(0);
00133 
00134    for (i = 0; i < 64; i++)
00135       close(i);
00136 
00137    return 0;
00138 }
00139 
00148 static void xdasd_signal_handler(int signum)
00149 {
00150    switch(signum)
00151    {
00152       case SIGALRM: xdasd_set_signal(XDASD_SIGALRM); break;
00153       case SIGTERM: xdasd_set_signal(XDASD_SIGTERM); break;
00154       case SIGHUP:  xdasd_set_signal(XDASD_SIGHUP);  break;
00155    }
00156 }
00157 
00166 static int xdasd_setup_signal_handler(void)
00167 {
00168    int result;
00169    struct sigaction sa;
00170 
00171    sa.sa_handler = xdasd_signal_handler;
00172    sigemptyset(&sa.sa_mask);
00173    sa.sa_flags = 0;
00174 
00175 #ifdef HAVE_SA_RESTORER
00176    sa.sa_restorer = 0;
00177 #endif
00178 
00179    result =  sigaction(SIGALRM, &sa, 0);
00180    result |= sigaction(SIGTERM, &sa, 0);
00181    result |= sigaction(SIGPIPE, &sa, 0);
00182    result |= sigaction(SIGHUP,  &sa, 0);
00183 
00184    signal(SIGHUP, xdasd_signal_handler);
00185    return result;
00186 }
00187 
00197 int main(int argc, char ** argv) 
00198 {
00199    int err;
00200    XDASDCmdLine cmdline;
00201    char pidfile[FILENAME_MAX];
00202 
00203    if (xdasd_parse_cmdline(argc, argv, &cmdline) < 0)
00204       xdasd_fatal("Invalid command line.\n");
00205 
00206    
00207    mkdir(cmdline.runpath, 0777);
00208    snprintf(pidfile, sizeof(pidfile), "%s/" XDASD_PIDFNAME, cmdline.runpath);
00209 
00210    if (xdasd_check_pid(pidfile))
00211       xdasd_fatal("xdasd is already running. Check %s.\n", pidfile);
00212 
00213    if (cmdline.detach && xdasd_daemonize() < 0)
00214       xdasd_fatal("Could not daemonize (%d).\n", errno);
00215 
00216    if (xdasd_setup_signal_handler())
00217       xdasd_fatal("Error setting up signal handlers (%d).\n", errno);
00218 
00219    if ((err = xdasd_main_init(&cmdline)) == 0)
00220    {
00221       xdasd_write_pid(pidfile, getpid());
00222       xdasd_main_run();
00223    }
00224    return err;
00225 }
00226