swrap: We need to pass a pointer-pointer to not leak memory.
[Samba.git] / ctdb / server / ctdb_event_helper.c
blobab1eae44091b19f822cdbd5483dd6ae7903f3740
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 "includes.h"
21 #include "system/filesys.h"
23 static char *progname = NULL;
26 /* CTDB sends SIGTERM, when process must die */
27 static void sigterm(int sig)
29 pid_t pid;
31 /* all the child processes are running in the same process group */
32 pid = getpgrp();
33 if (pid == -1) {
34 kill(-getpid(), SIGKILL);
35 } else {
36 kill(-pid, SIGKILL);
38 _exit(0);
41 static void set_close_on_exec(int fd)
43 int v;
45 v = fcntl(fd, F_GETFD, 0);
46 if (v == -1) {
47 return;
49 fcntl(fd, F_SETFD, v | FD_CLOEXEC);
52 static int check_executable(const char *path)
54 struct stat st;
56 if (stat(path, &st) != 0) {
57 fprintf(stderr, "Failed to access '%s' - %s\n",
58 path, strerror(errno));
59 return errno;
62 if (!(st.st_mode & S_IXUSR)) {
63 return ENOEXEC;
66 return 0;
69 static void usage(void)
71 fprintf(stderr, "\n");
72 fprintf(stderr, "Usage: %s <log-fd> <output-fd> <script_path> <event> [<args>]\n",
73 progname);
76 int main(int argc, char *argv[])
78 int log_fd, write_fd;
79 pid_t pid;
80 int status, output;
82 progname = argv[0];
84 if (argc < 5) {
85 usage();
86 exit(1);
89 log_fd = atoi(argv[1]);
90 write_fd = atoi(argv[2]);
92 set_close_on_exec(write_fd);
94 close(STDOUT_FILENO);
95 close(STDERR_FILENO);
96 dup2(log_fd, STDOUT_FILENO);
97 dup2(log_fd, STDERR_FILENO);
98 close(log_fd);
100 if (setpgid(0, 0) != 0) {
101 fprintf(stderr, "Failed to create process group for event script - %s\n",
102 strerror(errno));
103 exit(1);
106 signal(SIGTERM, sigterm);
108 pid = fork();
109 if (pid < 0) {
110 fprintf(stderr, "Failed to fork - %s\n", strerror(errno));
111 exit(errno);
114 if (pid == 0) {
115 int save_errno;
117 execv(argv[3], &argv[3]);
118 if (errno == EACCES) {
119 save_errno = check_executable(argv[3]);
120 } else {
121 save_errno = errno;
122 fprintf(stderr, "Error executing '%s' - %s\n",
123 argv[3], strerror(errno));
125 _exit(save_errno);
128 waitpid(pid, &status, 0);
129 if (WIFEXITED(status)) {
130 output = WEXITSTATUS(status);
131 if (output == ENOENT || output == ENOEXEC) {
132 output = -output;
134 write(write_fd, &output, sizeof(output));
135 exit(output);
138 exit(1);