ctdb-daemon: Fix CID 1364527/8/9: Null pointer dereferences (NULL_RETURNS)
[Samba.git] / ctdb / server / ctdb_event_helper.c
blob7b6e8434695f76921214268c360412cd26fbee69
1 /*
2 ctdb event script helper
4 Copyright (C) Amitay Isaacs 2013
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
25 #include <talloc.h>
27 #include "lib/util/blocking.h"
29 #include "ctdb_private.h"
31 #include "common/system.h"
33 static char *progname = NULL;
36 /* CTDB sends SIGTERM, when process must die */
37 static void sigterm(int sig)
39 pid_t pid;
41 /* all the child processes are running in the same process group */
42 pid = getpgrp();
43 if (pid == -1) {
44 kill(-getpid(), SIGKILL);
45 } else {
46 kill(-pid, SIGKILL);
48 _exit(0);
51 static int check_executable(const char *path)
53 struct stat st;
55 if (stat(path, &st) != 0) {
56 fprintf(stderr, "Failed to access '%s' - %s\n",
57 path, strerror(errno));
58 return errno;
61 if (!(st.st_mode & S_IXUSR)) {
62 return ENOEXEC;
65 return 0;
68 static void usage(void)
70 fprintf(stderr, "\n");
71 fprintf(stderr, "Usage: %s <log-fd> <output-fd> <script_path> <event> [<args>]\n",
72 progname);
75 int main(int argc, char *argv[])
77 int log_fd, write_fd;
78 pid_t pid;
79 int status, output, ret;
81 progname = argv[0];
83 if (argc < 5) {
84 usage();
85 exit(1);
88 reset_scheduler();
90 log_fd = atoi(argv[1]);
91 write_fd = atoi(argv[2]);
93 set_close_on_exec(write_fd);
95 close(STDOUT_FILENO);
96 close(STDERR_FILENO);
97 dup2(log_fd, STDOUT_FILENO);
98 dup2(log_fd, STDERR_FILENO);
99 close(log_fd);
101 if (setpgid(0, 0) != 0) {
102 fprintf(stderr, "Failed to create process group for event script - %s\n",
103 strerror(errno));
104 exit(1);
107 signal(SIGTERM, sigterm);
109 pid = fork();
110 if (pid < 0) {
111 int save_errno = errno;
112 fprintf(stderr, "Failed to fork - %s\n", strerror(errno));
113 sys_write(write_fd, &save_errno, sizeof(save_errno));
114 exit(1);
117 if (pid == 0) {
118 ret = check_executable(argv[3]);
119 if (ret != 0) {
120 _exit(ret);
122 ret = execv(argv[3], &argv[3]);
123 if (ret != 0) {
124 int save_errno = errno;
125 fprintf(stderr, "Error executing '%s' - %s\n",
126 argv[3], strerror(save_errno));
128 /* This should never happen */
129 _exit(ENOEXEC);
132 ret = waitpid(pid, &status, 0);
133 if (ret == -1) {
134 output = -errno;
135 fprintf(stderr, "waitpid() failed - %s\n", strerror(errno));
136 sys_write(write_fd, &output, sizeof(output));
137 exit(1);
139 if (WIFEXITED(status)) {
140 output = WEXITSTATUS(status);
141 /* Only errors should be returned as -ve values */
142 if (output == ENOENT || output == ENOEXEC) {
143 output = -output;
145 sys_write(write_fd, &output, sizeof(output));
146 exit(0);
148 if (WIFSIGNALED(status)) {
149 output = -EINTR;
150 fprintf(stderr, "Process terminated with signal - %d\n",
151 WTERMSIG(status));
152 sys_write(write_fd, &output, sizeof(output));
153 exit(0);
156 fprintf(stderr, "waitpid() status=%d\n", status);
157 exit(1);