blob: 596801591b9e4b726d039e8a5571bfcea9f4e8d0 [file] [log] [blame]
Marc-Antoine Perennoued9803e2013-02-12 10:53:53 +01001/*
2 * Wrapper to make haproxy systemd-compliant.
3 *
4 * Copyright 2013 Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <errno.h>
14#include <signal.h>
15#include <stdbool.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <unistd.h>
20#include <sys/wait.h>
21
22static pid_t pid = 0;
23static char *pid_file = "/run/haproxy.pid";
24static int main_argc;
25static char **main_argv;
26
27static pid_t spawn_haproxy(char **pid_strv, int nb_pid)
28{
29 pid_t pid = fork();
30 if (!pid) {
31 /* 3 for "haproxy -Ds -sf" */
32 char **argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *));
33 int i;
34 int argno = 0;
35 argv[argno++] = SBINDIR"/haproxy";
36 for (i = 0; i < main_argc; ++i)
37 argv[argno++] = main_argv[i];
38 argv[argno++] = "-Ds";
39 if (nb_pid > 0) {
40 argv[argno++] = "-sf";
41 for (i = 0; i < nb_pid; ++i)
42 argv[argno++] = pid_strv[i];
43 }
44 argv[argno] = NULL;
45 execv(argv[0], argv);
46 exit(0);
47 }
48 return pid;
49}
50
51static int read_pids(char ***pid_strv)
52{
53 FILE *f = fopen(pid_file, "r");
54 int read = 0, allocated = 8;
55 char pid_str[10];
56
57 if (!f)
58 return 0;
59
60 *pid_strv = malloc(allocated * sizeof(char *));
61 while (1 == fscanf(f, "%s\n", pid_str)) {
62 if (read == allocated) {
63 allocated *= 2;
64 *pid_strv = realloc(*pid_strv, allocated * sizeof(char *));
65 }
66 (*pid_strv)[read++] = strdup(pid_str);
67 }
68
69 fclose(f);
70
71 return read;
72}
73
74static void signal_handler(int signum __attribute__((unused)))
75{
76 int i;
77 char **pid_strv = NULL;
78 int nb_pid = read_pids(&pid_strv);
79
80 pid = spawn_haproxy(pid_strv, nb_pid);
81
82 for (i = 0; i < nb_pid; ++i)
83 free(pid_strv[i]);
84 free(pid_strv);
85}
86
87static void init(int argc, char **argv)
88{
89 while (argc > 1) {
90 if (**argv == '-') {
91 char *flag = *argv + 1;
92 --argc; ++argv;
93 if (*flag == 'p')
94 pid_file = *argv;
95 }
96 --argc; ++argv;
97 }
98}
99
100int main(int argc, char **argv)
101{
102 --argc; ++argv;
103 main_argc = argc;
104 main_argv = argv;
105
106 init(argc, argv);
107
108 signal(SIGUSR2, &signal_handler);
109
110 pid = spawn_haproxy(NULL, 0);
111 while (-1 != waitpid(pid, NULL, 0) || errno == EINTR);
112
113 return EXIT_SUCCESS;
114}