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