00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <signal.h>
00024 #include <errno.h>
00025 #include <stdlib.h>
00026
00027 #ifdef HAVE_STRING_H
00028 #include <string.h>
00029 #endif
00030
00031 #ifdef HAVE_STRINGS_H
00032 #include <strings.h>
00033 #endif
00034
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038
00039 #ifdef HAVE_SYS_WAIT_H
00040 #include <sys/wait.h>
00041 #endif
00042
00043 #ifdef HAVE_SYS_TYPES_H
00044 #include <sys/types.h>
00045 #endif
00046
00047 #ifdef HAVE_SYS_STAT_H
00048 #include <sys/stat.h>
00049 #endif
00050
00051 #include "alert.h"
00052 #include "monitor.h"
00053 #include "engine.h"
00054
00055
00056 static void do_free();
00057 static Command_T copy_command(Command_T);
00058 static Mail_T create_exec_alert_list(Process_T, Command_T);
00059
00060
00074
00075
00076
00084 void spawn(Process_T P, Command_T C) {
00085
00086 pid_t pid;
00087 sigset_t mask, save;
00088
00089 ASSERT(P);
00090 ASSERT(C);
00091
00092
00093
00094
00095 sigemptyset(&mask);
00096 sigaddset(&mask, SIGCHLD);
00097 pthread_sigmask(SIG_BLOCK, &mask, &save);
00098
00099 if((pid= fork()) < 0) {
00100
00101 log("Cannot fork of a new process\n");
00102 exit(1);
00103
00104 } else if(pid == 0) {
00105
00106 if((pid= fork()) < 0) {
00107
00108 log("Cannot fork of a new process\n");
00109 exit(1);
00110
00111 }
00112
00113 else if(pid > 0) {
00114
00115 _exit(0);
00116
00117 } else {
00118
00119 Command_T c= copy_command(C);
00120 Mail_T alert_list= create_exec_alert_list(P, C);
00121
00122
00123
00124
00125
00126 sigemptyset(&mask);
00127 pthread_sigmask(SIG_SETMASK, &mask, NULL);
00128
00129
00130 signal(SIGTERM, SIG_DFL);
00131 signal(SIGUSR1, SIG_DFL);
00132 signal(SIGPIPE, SIG_DFL);
00133
00134
00135 do_free();
00136
00137
00138
00139
00140
00141 umask(Run.umask);
00142
00143
00144
00145
00146 redirect_stdfd();
00147
00148
00149
00150
00151 (void) execv(c->arg[0], c->arg);
00152 sendmail(alert_list);
00153 log("Could not execute %s\n", c->arg[0]);
00154 gc_mail_list(&alert_list);
00155 _exit(1);
00156
00157 }
00158 }
00159
00160
00161 if(waitpid(pid, NULL, 0) != pid) {
00162
00163 log("Waitpid error\n");
00164
00165 }
00166
00167
00168
00169
00170 pthread_sigmask(SIG_SETMASK, &save, NULL);
00171
00172
00173
00174
00175
00176 return ;
00177
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187 static void do_free() {
00188
00189 gc();
00190 destroy_hosts_allow();
00191 free(Run.controlfile);
00192 free(Run.pidfile);
00193 free(Run.logfile);
00194 free(Run.localhostname);
00195 free(Run.Env.user);
00196 free(Run.Env.home);
00197 free(Run.Env.cwd);
00198 free(Run.Auth.uname);
00199 free(Run.Auth.passwd);
00200 free(Run.MailFormat.from);
00201 free(Run.MailFormat.subject);
00202 free(Run.MailFormat.message);
00203 free(Run.bind_addr);
00204
00205
00206 }
00207
00208
00209
00210
00211
00212 static Command_T copy_command(Command_T C) {
00213
00214 int i;
00215 Command_T P= NEW(P);
00216
00217 for(i= 0; C->arg[i]; i++)
00218 P->arg[i]= xstrdup(C->arg[i]);
00219 P->arg[i]= NULL;
00220
00221 return P;
00222
00223 }
00224
00225
00226
00227
00228
00229
00230
00231 static Mail_T create_exec_alert_list(Process_T p, Command_T c) {
00232
00233 Mail_T l= NULL;
00234 Mail_T h= p->maillist;
00235
00236 for(; h; h= h->next)
00237 if(h->alert_on_restart) {
00238
00239 Mail_T n= NEW(n);
00240 char *message= xmalloc(STRLEN);
00241
00242 n->to= xstrdup(h->to);
00243 n->from= xstrdup("monit@localhost");
00244 n->subject= xstrdup("monit alert -- exec error");
00245 snprintf(message, STRLEN,
00246 "NOTE, THIS EMAIL TAKES PRECEDENCE OVER SUBSEQUENT RESTART ALERTS\n\n"
00247 "Could not execute program '%s' for process %s\n\n"
00248 "Your faithful employee,\nmonit",
00249 c->arg[0]?c->arg[0]:"null", p->name);
00250 n->message= message;
00251 n->next= l;
00252 l= n;
00253
00254 }
00255
00256 return l;
00257
00258 }