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
00031
00032
00033
00034 #include <config.h>
00035
00036 #if defined __SUNPRO_C || defined __DECC || defined __HP_cc
00037 # pragma ident "@(#)$Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $"
00038 # pragma ident "$NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $"
00039 #endif
00040
00041 #include <fcntl.h>
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <sys/types.h>
00045 #include <sys/wait.h>
00046 #include <signal.h>
00047 #include <unistd.h>
00048 #include <errno.h>
00049 #include <sys/select.h>
00050
00051 #include <drizzled/daemon.h>
00052
00053 namespace drizzled
00054 {
00055
00056 int parent_pipe_fds[2];
00057
00058 extern "C"
00059 {
00060
00061 static void sigchld_handler(int sig)
00062 {
00063 int status= -1;
00064 if (sig == SIGCHLD)
00065 {
00066 (void)wait(&status);
00067 }
00068 _exit(status);
00069 }
00070
00071 }
00072
00073 void daemon_is_ready()
00074 {
00075 int fd;
00076 ssize_t wbytes;
00077 while ((wbytes= write(parent_pipe_fds[1], "\0", sizeof("\0"))) == 0);
00078 {
00079 if (wbytes < 0)
00080 {
00081 perror("write");
00082 _exit(errno);
00083 }
00084 }
00085 if (close(parent_pipe_fds[1]))
00086 {
00087 perror("close");
00088 _exit(errno);
00089 }
00090
00091 if ((fd = open("/dev/null", O_RDWR, 0)) != -1)
00092 {
00093 if(dup2(fd, STDIN_FILENO) < 0)
00094 {
00095 perror("dup2 stdin");
00096 return;
00097 }
00098
00099 if(dup2(fd, STDOUT_FILENO) < 0)
00100 {
00101 perror("dup2 stdout");
00102 return;
00103 }
00104
00105 if(dup2(fd, STDERR_FILENO) < 0)
00106 {
00107 perror("dup2 stderr");
00108 return;
00109 }
00110
00111 if (fd > STDERR_FILENO)
00112 {
00113 if (close(fd) < 0)
00114 {
00115 perror("close");
00116 return;
00117 }
00118 }
00119 }
00120 }
00121
00122 bool daemonize()
00123 {
00124 pid_t child= -1;
00125
00126 if (pipe(parent_pipe_fds))
00127 {
00128 perror("pipe");
00129 _exit(errno);
00130 }
00131
00132 child= fork();
00133
00134 switch (child)
00135 {
00136 case -1:
00137 return true;
00138
00139 case 0:
00140 break;
00141
00142 default:
00143 {
00144
00145 char ready_byte[1];
00146 size_t rbytes;
00147
00148
00149 signal(SIGCHLD, sigchld_handler);
00150
00151 if (close(parent_pipe_fds[1]))
00152 {
00153 perror("close");
00154 _exit(errno);
00155 }
00156
00157 if ((rbytes= read(parent_pipe_fds[0],ready_byte,sizeof(ready_byte))) < 1)
00158 {
00159 int estatus= -1;
00160 if (rbytes != 0)
00161 {
00162 estatus= errno;
00163 perror("read");
00164 }
00165 _exit(estatus);
00166 }
00167 if (close(parent_pipe_fds[0]))
00168 {
00169 perror("close");
00170 _exit(errno);
00171 }
00172
00173 _exit(EXIT_SUCCESS);
00174 }
00175 }
00176
00177
00178 if (close(parent_pipe_fds[0]))
00179 {
00180 perror("close");
00181 _exit(errno);
00182 }
00183 if (setsid() == -1)
00184 {
00185 return true;
00186 }
00187
00188 return false;
00189 }
00190
00191 }